From 8d60bc0aaae2bc1dae3735fc1004150a446fd41f Mon Sep 17 00:00:00 2001 From: HinsonSIDAN Date: Thu, 12 Mar 2026 14:01:10 +0800 Subject: [PATCH 01/30] wip --- spec/8_hydra_account/w_migration.md | 30 ++++++++++++++++++++++++++++ spec/8_hydra_account/w_transferal.md | 3 +-- 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 spec/8_hydra_account/w_migration.md diff --git a/spec/8_hydra_account/w_migration.md b/spec/8_hydra_account/w_migration.md new file mode 100644 index 0000000..88bd4dd --- /dev/null +++ b/spec/8_hydra_account/w_migration.md @@ -0,0 +1,30 @@ +# Specification - HydraAccount - Migration + +## Overview + +Periodic migration workflow for updating `hydra_account` and `hydra_order_book` scripts. + +## Migration Steps + +1. Cancel all existing orders +2. Update the `dex_order_book` oracle datum with new `hydra_signers` keys +3. Migrate all `hydra_account` UTxOs: + - Same `master_key` + `operation_key` preserved + - `trading_logic` updated to the latest `hydra_order_book_script_hash` from `dex_order_book` oracle + +## Open Questions + +### Oracle Update vs Migration Ordering + +If step 2 (oracle update) happens before step 3 (migration), the old `hydra_account` validator can no longer look up its own script hash from the oracle — the oracle now points to the new script hash. This means `withdrawal_script_validated(withdrawals, hydra_account_script_hash)` in the old validator would check against the **new** hash, not the old one, and the old script's withdrawal cannot be triggered. + +Options: +- **Option A**: Perform step 3 before step 2 — migrate accounts while the oracle still references the old scripts +- **Option B**: Have the migration redeemer use `operation_key` signature directly (like `HydraAccountSpamPreventionWithdraw`) rather than the withdrawal-based pattern + +### Output Validation + +The migration validator must ensure: +- New UTxOs are sent to the **new** `hydra_account_script_hash` +- `trading_logic` in the datum is correctly updated to the new `hydra_order_book_script_hash` +- The source of truth for the new script hash must be authoritative (the updated oracle, or a validator parameter) diff --git a/spec/8_hydra_account/w_transferal.md b/spec/8_hydra_account/w_transferal.md index 7660f24..aff941c 100644 --- a/spec/8_hydra_account/w_transferal.md +++ b/spec/8_hydra_account/w_transferal.md @@ -13,8 +13,7 @@ - `AO_from` - Account Outputs with `from` account at intent - `AO_to` - Account Outputs with `to` account at intent - Other outputs -- Other inputs length == 1 (the intent input) -- No other outputs +- No other inputs/outputs at `hydra_account_script_hash` (only `from` and `to` account UTxOs allowed) - The 3 value are equal: 1. Deduct in value for `from` (`AI_from` - `AO_from`) 2. Increase in value for `to` (`AO_to` - `AI_to`) From e8e9d43cfae225f28429b0bfbac5e8626a697940 Mon Sep 17 00:00:00 2001 From: HinsonSIDAN Date: Thu, 12 Mar 2026 18:41:40 +0800 Subject: [PATCH 02/30] feat: update transferal logic --- lib/hydra_dex/types.ak | 2 + spec/8_hydra_account/core.md | 6 + spec/8_hydra_account/w_migration.md | 52 +++--- validators/hydra_account/core.ak | 25 ++- validators/hydra_account/migration.ak | 108 +++++++++++ validators/hydra_account/transferal.ak | 19 +- validators/tests/hydra_account/migration.ak | 181 +++++++++++++++++++ validators/tests/hydra_account/spend.ak | 66 ++++++- validators/tests/hydra_account/transferal.ak | 86 ++++++++- validators/tests/utils.ak | 17 ++ 10 files changed, 512 insertions(+), 50 deletions(-) create mode 100644 validators/hydra_account/migration.ak create mode 100644 validators/tests/hydra_account/migration.ak diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index 8718160..84ae778 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -235,6 +235,7 @@ pub type HydraAccountRedeemer { HydraAccountTrade { trade_redeemer: Data } HydraAccountOperate HydraAccountSpamPreventionWithdraw + HydraAccountMigrate } pub type HydraAccountOperation { @@ -248,6 +249,7 @@ pub type HydraAccountOperation { ProcessSplitUtxosAtOpen { tree_or_proofs_with_token_map: TreeOrProofsWithTokenMap, } + ProcessMigration { account: UserAccount } } // 9 - HydraOrderBook diff --git a/spec/8_hydra_account/core.md b/spec/8_hydra_account/core.md index a293ec4..08f4398 100644 --- a/spec/8_hydra_account/core.md +++ b/spec/8_hydra_account/core.md @@ -25,3 +25,9 @@ - Either one of below - Empty balance - Check balance against value by removing lovelace - is empty - There is no datum + +4. Migration - `HydraAccountMigrate` + + - Find own input via `OutputReference` + - Derive own script hash from input address payment credential + - Validate own withdrawal script: `withdrawal_script_validated(withdrawals, own_script_hash)` diff --git a/spec/8_hydra_account/w_migration.md b/spec/8_hydra_account/w_migration.md index 88bd4dd..82bc7e9 100644 --- a/spec/8_hydra_account/w_migration.md +++ b/spec/8_hydra_account/w_migration.md @@ -1,30 +1,32 @@ # Specification - HydraAccount - Migration -## Overview - -Periodic migration workflow for updating `hydra_account` and `hydra_order_book` scripts. - -## Migration Steps +## User Action + +- Ref input with `oracle_nft` +- Get `account` from redeemer +- Old script hash from own `credential` (this withdrawal script's hash) +- New script hash from oracle's `hydra_account_script_hash` +- Categorize inputs into + - `AI` - Account Inputs at old script hash with matching `account` datum + - Other inputs +- Categorize outputs into + - `AO` - Account Outputs at new `hydra_account_script_hash` (from oracle) + - Other outputs +- No other inputs at old script hash (single account per tx) +- No inputs at new `hydra_account_script_hash` (prevent mixing with normal operations) +- All `AO` have datum with: + - Same `account_id` + - Same `master_key` + - Same `operation_key` + - `trading_logic` updated to new `hydra_order_book_script_hash` from oracle +- Total value preserved: `inputs_value(AI) == outputs_value(AO)` +- Signed by `operation_key` + +## Note - Migration Workflow 1. Cancel all existing orders -2. Update the `dex_order_book` oracle datum with new `hydra_signers` keys -3. Migrate all `hydra_account` UTxOs: - - Same `master_key` + `operation_key` preserved - - `trading_logic` updated to the latest `hydra_order_book_script_hash` from `dex_order_book` oracle - -## Open Questions - -### Oracle Update vs Migration Ordering - -If step 2 (oracle update) happens before step 3 (migration), the old `hydra_account` validator can no longer look up its own script hash from the oracle — the oracle now points to the new script hash. This means `withdrawal_script_validated(withdrawals, hydra_account_script_hash)` in the old validator would check against the **new** hash, not the old one, and the old script's withdrawal cannot be triggered. - -Options: -- **Option A**: Perform step 3 before step 2 — migrate accounts while the oracle still references the old scripts -- **Option B**: Have the migration redeemer use `operation_key` signature directly (like `HydraAccountSpamPreventionWithdraw`) rather than the withdrawal-based pattern - -### Output Validation +2. Combine `hydra_account` utxos into 1 utxo per user +3. Update the `dex_order_book` oracle datum with new script hashes (`hydra_account` and `hydra_order_book` mainly) and `hydra_signers` keys +4. Migrate all `hydra_account` UTxOs using `ProcessMigration` withdrawal on the **new** script -The migration validator must ensure: -- New UTxOs are sent to the **new** `hydra_account_script_hash` -- `trading_logic` in the datum is correctly updated to the new `hydra_order_book_script_hash` -- The source of truth for the new script hash must be authoritative (the updated oracle, or a validator parameter) +Old account UTxOs are spent with `HydraAccountMigrate` redeemer. This derives the script's own hash from the input address and validates its own withdrawal script. The old script's `ProcessMigration` withdrawal then reads the new `hydra_account_script_hash` from the updated oracle to validate outputs are sent to the new script with correct migrated datums. diff --git a/validators/hydra_account/core.ak b/validators/hydra_account/core.ak index 06ca045..bb14891 100644 --- a/validators/hydra_account/core.ak +++ b/validators/hydra_account/core.ak @@ -1,20 +1,22 @@ use aiken/option.{is_none} -use cardano/address.{Credential} +use cardano/address.{Credential, Script} use cardano/assets.{PolicyId, without_lovelace, zero} use cardano/transaction.{OutputReference, Transaction, find_input} use cocktail.{key_signed, withdrawal_script_validated} use hydra_account/cancel_withdrawal.{cancel_withdrawal} use hydra_account/combine_utxos_at_close.{combine_utxos_at_close} +use hydra_account/migration.{migration} use hydra_account/same_account_transferal.{same_account_transferal} use hydra_account/split_utxos_at_open.{split_utxos_at_open} use hydra_account/transferal.{transferal} use hydra_account/withdrawal.{withdrawal} use hydra_dex/types.{ - DexOrderBookDatum, HydraAccountOperate, HydraAccountOperation, - HydraAccountRedeemer, HydraAccountSpamPreventionWithdraw, HydraAccountTrade, - ProcessCancelWithdrawal, ProcessCombineUtxosAtClose, - ProcessSameAccountTransferal, ProcessSplitUtxosAtOpen, ProcessTransferal, - ProcessWithdrawal, TreeOrProofsWithTokenMap, UserAccount, + DexOrderBookDatum, HydraAccountMigrate, HydraAccountOperate, + HydraAccountOperation, HydraAccountRedeemer, + HydraAccountSpamPreventionWithdraw, HydraAccountTrade, ProcessCancelWithdrawal, + ProcessCombineUtxosAtClose, ProcessMigration, ProcessSameAccountTransferal, + ProcessSplitUtxosAtOpen, ProcessTransferal, ProcessWithdrawal, + TreeOrProofsWithTokenMap, UserAccount, } use hydra_dex/utils.{get_dex_order_book_datum} @@ -47,6 +49,13 @@ validator hydra_account(dex_oracle_nft: PolicyId) { HydraAccountOperate -> withdrawal_script_validated(withdrawals, hydra_account_script_hash)? + HydraAccountMigrate -> { + expect Some(own_input) = inputs |> find_input(input) + expect Script(own_script_hash) = + own_input.output.address.payment_credential + withdrawal_script_validated(withdrawals, own_script_hash)? + } + HydraAccountSpamPreventionWithdraw -> { // TODO: review expect Some(own_input) = inputs |> find_input(input) @@ -73,7 +82,7 @@ validator hydra_account(dex_oracle_nft: PolicyId) { withdraw( redeemer: HydraAccountOperation, - _credential: Credential, + credential: Credential, tx: Transaction, ) { when redeemer is { @@ -94,6 +103,8 @@ validator hydra_account(dex_oracle_nft: PolicyId) { tree_or_proofs_with_token_map combine_utxos_at_close(dex_oracle_nft, proof, token_map, tx) } + ProcessMigration { account } -> + migration(dex_oracle_nft, account, credential, tx) } } diff --git a/validators/hydra_account/migration.ak b/validators/hydra_account/migration.ak new file mode 100644 index 0000000..d73642b --- /dev/null +++ b/validators/hydra_account/migration.ak @@ -0,0 +1,108 @@ +use aiken/collection/list +use cardano/address.{Credential, Script, from_script} +use cardano/assets.{PolicyId, without_lovelace} +use cardano/transaction.{Input, Output, Transaction} +use cocktail.{ + group_inputs, group_outputs, input_inline_datum, key_signed, + output_inline_datum, +} +use cocktail/vodka_value.{inputs_value, outputs_value} +use hydra_dex/types.{ + DexOrderBookDatum, UserAccount, UserFundingAccount, UserMobileAccount, + UserTradeAccount, +} +use hydra_dex/utils.{get_dex_order_book_datum} + +pub fn migration( + oracle_nft: PolicyId, + account: UserAccount, + credential: Credential, + tx: Transaction, +) -> Bool { + let Transaction { inputs, outputs, reference_inputs, extra_signatories, .. } = + tx + + // - Ref input with `oracle_nft` + let DexOrderBookDatum { + operation_key, + hydra_account_script_hash, + hydra_order_book_script_hash, + .. + }: DexOrderBookDatum = + reference_inputs |> get_dex_order_book_datum(oracle_nft) + + // - Old script hash from own credential (this withdrawal script) + expect Script(old_script_hash) = credential + let old_account_address = from_script(old_script_hash) + + // - New script hash from oracle + let new_account_address = from_script(hydra_account_script_hash) + + // - Categorize inputs into + // - `AI` - Account Inputs at old script hash with matching `account` datum + // - Other inputs + let ai_filter = + fn(input: Input) { + if input.output.address == old_account_address { + expect input_datum: UserAccount = input_inline_datum(input) + input_datum == account + } else { + False + } + } + let (account_inputs, other_inputs) = inputs |> group_inputs(ai_filter) + + // - Categorize outputs into + // - `AO` - Account Outputs at new `hydra_account_script_hash` + // - Other outputs + let migrated_account = migrate_account(account, hydra_order_book_script_hash) + let ao_filter = + fn(output: Output) { + if output.address == new_account_address { + expect output_datum: UserAccount = output_inline_datum(output) + output_datum == migrated_account + } else { + False + } + } + let (account_outputs, _other_outputs) = outputs |> group_outputs(ao_filter) + + // - No other inputs at old script hash (single account per tx) + let no_other_old_script_inputs = + other_inputs + |> list.all(fn(input) { input.output.address != old_account_address }) + + // - No inputs at new `hydra_account_script_hash` (prevent mixing with normal operations) + let no_new_script_inputs = + inputs + |> list.all(fn(input) { input.output.address != new_account_address }) + + // - Total value preserved + let ai_value = inputs_value(account_inputs) |> without_lovelace() + let ao_value = outputs_value(account_outputs) |> without_lovelace() + let is_value_preserved = ai_value == ao_value + + // - Signed by `operation_key` + let is_authorized = key_signed(extra_signatories, operation_key) + + and { + no_other_old_script_inputs?, + no_new_script_inputs?, + is_value_preserved?, + is_authorized?, + } +} + +fn migrate_account( + account: UserAccount, + new_trading_logic: ByteArray, +) -> UserAccount { + when account is { + UserTradeAccount { account, .. } -> + UserTradeAccount { account, trading_logic: new_trading_logic } + UserFundingAccount { account, .. } -> + UserFundingAccount { account, trading_logic: new_trading_logic } + UserMobileAccount { account, .. } -> + UserMobileAccount { account, trading_logic: new_trading_logic } + } +} diff --git a/validators/hydra_account/transferal.ak b/validators/hydra_account/transferal.ak index 55c1310..bc01880 100644 --- a/validators/hydra_account/transferal.ak +++ b/validators/hydra_account/transferal.ak @@ -1,10 +1,9 @@ -use aiken/collection/list use cardano/address.{from_script} use cardano/assets.{PolicyId, from_asset_list, merge, negate, without_lovelace} use cardano/transaction.{Transaction} use cocktail.{ - group_inputs_2, group_outputs_2, input_inline_datum, inputs_at_with_policy, - key_signed, + group_inputs_2, group_outputs_2, input_inline_datum, inputs_at, + inputs_at_with_policy, key_signed, outputs_at, } use cocktail/vodka_value.{inputs_value, outputs_value} use hydra_dex/account_utils.{ @@ -70,10 +69,12 @@ pub fn transferal(oracle_nft: PolicyId, tx: Transaction) -> Bool { let (account_outputs_from, account_outputs_to, other_outputs) = group_outputs_2(outputs, ao_from_filter, ao_to_filter) - // - Other inputs length == 1 (the intent input) - // - No other outputs - let no_other_inputs = list.length(other_inputs) == 1 - let no_other_outputs = other_outputs == [] + // - No other inputs/outputs at `hydra_account_script_hash` + let hydra_account_address = from_script(hydra_account_script_hash) + let no_other_account_inputs = + inputs_at(other_inputs, hydra_account_address) == [] + let no_other_account_outputs = + outputs_at(other_outputs, hydra_account_address) == [] // - The 3 value are equal: // 1. Deduct in value for `from` (`AI_from` - `AO_from`) @@ -100,8 +101,8 @@ pub fn transferal(oracle_nft: PolicyId, tx: Transaction) -> Bool { key_signed(extra_signatories, operation_key) and { - no_other_inputs?, - no_other_outputs?, + no_other_account_inputs?, + no_other_account_outputs?, is_values_matching?, is_hydra_internal_transfer_authorized?, is_intent_token_burnt?, diff --git a/validators/tests/hydra_account/migration.ak b/validators/tests/hydra_account/migration.ak new file mode 100644 index 0000000..e873fc9 --- /dev/null +++ b/validators/tests/hydra_account/migration.ak @@ -0,0 +1,181 @@ +use cardano/address.{Script, from_script} +use cardano/assets.{from_asset} +use cardano/transaction.{Transaction} +use hydra_account/core as ha +use hydra_dex/types.{ProcessMigration} +use mocktail.{ + complete, mock_tx_hash, mocktail_tx, ref_tx_in, ref_tx_in_inline_datum, + required_signer_hash, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use tests/utils.{ + mock_account, mock_account_2, mock_dex_order_book_address, + mock_dex_order_book_token, mock_hydra_account, mock_hydra_account_address, + mock_hydra_lovelace, mock_migrated_user_account, + mock_migration_dex_order_book_datum, mock_new_hydra_account_address, + mock_operation_key, mock_user_account, +} + +type MigrationTestCase { + is_operation_key_signed: Bool, + is_datum_migrated: Bool, + is_value_preserved: Bool, + is_no_other_old_script_inputs: Bool, + is_no_new_script_inputs: Bool, +} + +fn mock_migration_tx(test_case: MigrationTestCase) -> Transaction { + let MigrationTestCase { + is_operation_key_signed, + is_datum_migrated, + is_value_preserved, + is_no_other_old_script_inputs, + is_no_new_script_inputs, + } = test_case + + let input_value = mock_hydra_lovelace(1_000_000_000) + let output_value = + if is_value_preserved { + mock_hydra_lovelace(1_000_000_000) + } else { + mock_hydra_lovelace(500_000_000) + } + + let output_datum = + if is_datum_migrated { + mock_migrated_user_account(mock_account) + } else { + mock_user_account(mock_account) + } + + mocktail_tx() + |> ref_tx_in( + True, + mock_tx_hash(1), + 0, + from_asset(mock_dex_order_book_token, "", 1), + mock_dex_order_book_address, + ) + |> ref_tx_in_inline_datum(True, mock_migration_dex_order_book_datum) + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_hydra_account_address) + |> tx_in_inline_datum(True, mock_user_account(mock_account)) + |> tx_in( + !is_no_other_old_script_inputs, + mock_tx_hash(0), + 1, + mock_hydra_lovelace(500_000_000), + mock_hydra_account_address, + ) + |> tx_in_inline_datum( + !is_no_other_old_script_inputs, + mock_user_account(mock_account_2), + ) + |> tx_in( + !is_no_new_script_inputs, + mock_tx_hash(0), + 2, + mock_hydra_lovelace(500_000_000), + mock_new_hydra_account_address, + ) + |> tx_in_inline_datum( + !is_no_new_script_inputs, + mock_migrated_user_account(mock_account_2), + ) + |> tx_out(True, mock_new_hydra_account_address, output_value) + |> tx_out_inline_datum(True, output_datum) + |> required_signer_hash(is_operation_key_signed, mock_operation_key) + |> complete() +} + +fn default_test_case() -> MigrationTestCase { + MigrationTestCase { + is_operation_key_signed: True, + is_datum_migrated: True, + is_value_preserved: True, + is_no_other_old_script_inputs: True, + is_no_new_script_inputs: True, + } +} + +test s8_wm_success() { + let tx = mock_migration_tx(default_test_case()) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_without_operation_key_signed() { + let tx = + mock_migration_tx( + MigrationTestCase { ..default_test_case(), is_operation_key_signed: False }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_without_datum_migrated() { + let tx = + mock_migration_tx( + MigrationTestCase { ..default_test_case(), is_datum_migrated: False }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_without_value_preserved() { + let tx = + mock_migration_tx( + MigrationTestCase { ..default_test_case(), is_value_preserved: False }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_with_other_old_script_inputs() { + let tx = + mock_migration_tx( + MigrationTestCase { + ..default_test_case(), + is_no_other_old_script_inputs: False, + }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_with_new_script_inputs() { + let tx = + mock_migration_tx( + MigrationTestCase { ..default_test_case(), is_no_new_script_inputs: False }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} diff --git a/validators/tests/hydra_account/spend.ak b/validators/tests/hydra_account/spend.ak index dc7fea7..3c9e0f3 100644 --- a/validators/tests/hydra_account/spend.ak +++ b/validators/tests/hydra_account/spend.ak @@ -1,15 +1,18 @@ use cardano/assets.{from_asset, zero} use cardano/transaction.{Transaction} use hydra_account/core as ha -use hydra_dex/types.{HydraAccountSpamPreventionWithdraw} +use hydra_dex/types.{ + HydraAccountMigrate, HydraAccountSpamPreventionWithdraw, ProcessMigration, +} use mocktail.{ complete, mock_tx_hash, mock_utxo_ref, mocktail_tx, ref_tx_in, - ref_tx_in_inline_datum, required_signer_hash, tx_in, + ref_tx_in_inline_datum, required_signer_hash, script_withdrawal, tx_in, + tx_in_inline_datum, withdrawal_redeemer_value, } use tests/utils.{ mock_account, mock_dex_order_book_address, mock_dex_order_book_datum, - mock_dex_order_book_token, mock_hydra_account_address, mock_hydra_lovelace, - mock_operation_key, mock_user_account, + mock_dex_order_book_token, mock_hydra_account, mock_hydra_account_address, + mock_hydra_lovelace, mock_operation_key, mock_user_account, } type RemoveEmptyBalanceTestCase { @@ -117,6 +120,61 @@ test s8_spend_fail_spam_prevention_with_non_empty_balance_and_with_datum() { ) } +test s8_spend_success_migrate() { + let account = mock_user_account(mock_account) + let tx = + mocktail_tx() + |> ref_tx_in( + True, + mock_tx_hash(0), + 1, + from_asset(mock_dex_order_book_token, "", 1), + mock_dex_order_book_address, + ) + |> ref_tx_in_inline_datum(True, mock_dex_order_book_datum) + |> tx_in(True, mock_tx_hash(0), 0, zero, mock_hydra_account_address) + |> tx_in_inline_datum(True, account) + |> script_withdrawal(True, mock_hydra_account, 0) + |> withdrawal_redeemer_value( + True, + ProcessMigration { account }, + ) + |> complete() + + ha.hydra_account.spend( + mock_dex_order_book_token, + Some(account), + HydraAccountMigrate, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s8_spend_fail_migrate_without_withdrawal_script() { + let account = mock_user_account(mock_account) + let tx = + mocktail_tx() + |> ref_tx_in( + True, + mock_tx_hash(0), + 1, + from_asset(mock_dex_order_book_token, "", 1), + mock_dex_order_book_address, + ) + |> ref_tx_in_inline_datum(True, mock_dex_order_book_datum) + |> tx_in(True, mock_tx_hash(0), 0, zero, mock_hydra_account_address) + |> tx_in_inline_datum(True, account) + |> complete() + + !ha.hydra_account.spend( + mock_dex_order_book_token, + Some(account), + HydraAccountMigrate, + mock_utxo_ref(0, 0), + tx, + ) +} + test s8_spend_fail_spam_prevention_without_operation_key_signed() { let tx = mock_spam_prevention_tx( diff --git a/validators/tests/hydra_account/transferal.ak b/validators/tests/hydra_account/transferal.ak index 9cdc32f..6a40517 100644 --- a/validators/tests/hydra_account/transferal.ak +++ b/validators/tests/hydra_account/transferal.ak @@ -9,11 +9,11 @@ use mocktail.{ required_signer_hash, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, } use tests/utils.{ - mock_account, mock_account_2, mock_dex_order_book_address, - mock_dex_order_book_datum, mock_dex_order_book_token, - mock_hydra_account_address, mock_hydra_lovelace, - mock_hydra_user_intent_address, mock_hydra_user_intent_token, - mock_operation_key, mock_user_account, + mock_account, mock_account_2, mock_account_3, + mock_dex_order_book_address, mock_dex_order_book_datum, + mock_dex_order_book_token, mock_hydra_account_address, + mock_hydra_lovelace, mock_hydra_user_intent_address, + mock_hydra_user_intent_token, mock_operation_key, mock_user_account, } as test_utils type HydraInternalTransferTestCase { @@ -21,6 +21,8 @@ type HydraInternalTransferTestCase { is_from_account_balance_deducted: Bool, is_to_account_balance_added: Bool, is_intent_token_burnt: Bool, + has_other_account_input: Bool, + has_other_account_output: Bool, } fn mock_hydra_internal_transfer_tx( @@ -31,6 +33,8 @@ fn mock_hydra_internal_transfer_tx( is_from_account_balance_deducted, is_to_account_balance_added, is_intent_token_burnt, + has_other_account_input, + has_other_account_output, } = test_case let transferal_amount = mock_hydra_lovelace(100_000_000) @@ -95,6 +99,26 @@ fn mock_hydra_internal_transfer_tx( |> tx_in_inline_datum(True, mock_user_account(mock_account_2)) |> tx_out(True, mock_hydra_account_address, to_balance_end) |> tx_out_inline_datum(True, mock_user_account(mock_account_2)) + |> tx_in( + has_other_account_input, + mock_tx_hash(0), + 3, + mock_hydra_lovelace(500_000_000), + mock_hydra_account_address, + ) + |> tx_in_inline_datum( + has_other_account_input, + mock_user_account(mock_account_3), + ) + |> tx_out( + has_other_account_output, + mock_hydra_account_address, + mock_hydra_lovelace(500_000_000), + ) + |> tx_out_inline_datum( + has_other_account_output, + mock_user_account(mock_account_3), + ) |> mint(is_intent_token_burnt, -1, mock_hydra_user_intent_token, "") |> required_signer_hash(is_operation_key_signed, mock_operation_key) |> complete() @@ -107,6 +131,8 @@ test s8_wt_success() { is_from_account_balance_deducted: True, is_to_account_balance_added: True, is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, } let tx = mock_hydra_internal_transfer_tx(test_case) @@ -126,6 +152,8 @@ test s8_wt_failed_without_operation_key_signed() { is_from_account_balance_deducted: True, is_to_account_balance_added: True, is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, } let tx = mock_hydra_internal_transfer_tx(test_case) @@ -145,6 +173,8 @@ test s8_wt_failed_without_from_account_balance_deducted() { is_from_account_balance_deducted: False, is_to_account_balance_added: True, is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, } let tx = mock_hydra_internal_transfer_tx(test_case) @@ -164,6 +194,8 @@ test s8_wt_failed_without_to_account_balance_added() { is_from_account_balance_deducted: True, is_to_account_balance_added: False, is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, } let tx = mock_hydra_internal_transfer_tx(test_case) @@ -183,6 +215,50 @@ test s8_wt_failed_without_intent_token_burnt() { is_from_account_balance_deducted: True, is_to_account_balance_added: True, is_intent_token_burnt: False, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_hydra_internal_transfer_tx(test_case) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessTransferal, + Script(""), + tx, + ) +} + +test s8_wt_failed_with_other_account_input() { + let test_case = + HydraInternalTransferTestCase { + is_operation_key_signed: True, + is_from_account_balance_deducted: True, + is_to_account_balance_added: True, + is_intent_token_burnt: True, + has_other_account_input: True, + has_other_account_output: False, + } + + let tx = mock_hydra_internal_transfer_tx(test_case) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessTransferal, + Script(""), + tx, + ) +} + +test s8_wt_failed_with_other_account_output() { + let test_case = + HydraInternalTransferTestCase { + is_operation_key_signed: True, + is_from_account_balance_deducted: True, + is_to_account_balance_added: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: True, } let tx = mock_hydra_internal_transfer_tx(test_case) diff --git a/validators/tests/utils.ak b/validators/tests/utils.ak index 6bce422..995533e 100644 --- a/validators/tests/utils.ak +++ b/validators/tests/utils.ak @@ -394,6 +394,23 @@ pub fn mock_mobile_account(account: Account) -> UserAccount { UserMobileAccount { account, trading_logic: mock_hydra_order_book } } +pub const mock_new_hydra_account = mock_script_hash(801) + +pub const mock_new_hydra_account_address = from_script(mock_new_hydra_account) + +pub const mock_new_hydra_order_book = mock_script_hash(901) + +pub const mock_migration_dex_order_book_datum: DexOrderBookDatum = + DexOrderBookDatum { + ..mock_dex_order_book_datum, + hydra_account_script_hash: mock_new_hydra_account, + hydra_order_book_script_hash: mock_new_hydra_order_book, + } + +pub fn mock_migrated_user_account(account: Account) -> UserAccount { + UserTradeAccount { account, trading_logic: mock_new_hydra_order_book } +} + pub const mock_token_map: TokenMap = [ Pair("", ("", "")), From 453dcccb51bce9669dbcb1652211284118ab9d3e Mon Sep 17 00:00:00 2001 From: HinsonSIDAN Date: Thu, 12 Mar 2026 18:48:16 +0800 Subject: [PATCH 03/30] chore: update scripts --- validators/tests/hydra_account/migration.ak | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/validators/tests/hydra_account/migration.ak b/validators/tests/hydra_account/migration.ak index e873fc9..454c6e4 100644 --- a/validators/tests/hydra_account/migration.ak +++ b/validators/tests/hydra_account/migration.ak @@ -1,4 +1,4 @@ -use cardano/address.{Script, from_script} +use cardano/address.{Script} use cardano/assets.{from_asset} use cardano/transaction.{Transaction} use hydra_account/core as ha @@ -110,7 +110,10 @@ test s8_wm_success() { test s8_wm_failed_without_operation_key_signed() { let tx = mock_migration_tx( - MigrationTestCase { ..default_test_case(), is_operation_key_signed: False }, + MigrationTestCase { + ..default_test_case(), + is_operation_key_signed: False, + }, ) !ha.hydra_account.withdraw( @@ -169,7 +172,10 @@ test s8_wm_failed_with_other_old_script_inputs() { test s8_wm_failed_with_new_script_inputs() { let tx = mock_migration_tx( - MigrationTestCase { ..default_test_case(), is_no_new_script_inputs: False }, + MigrationTestCase { + ..default_test_case(), + is_no_new_script_inputs: False, + }, ) !ha.hydra_account.withdraw( From a5c34b7cc2c89999d8db7c004e6912c0c481e7d6 Mon Sep 17 00:00:00 2001 From: HinsonSIDAN Date: Thu, 12 Mar 2026 22:14:06 +0800 Subject: [PATCH 04/30] chore: update scripts --- lib/hydra_dex/types.ak | 3 ++ validators/hydra_account/core.ak | 53 ++++++++++++------------- validators/tests/hydra_account/spend.ak | 5 +-- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index 84ae778..40170ba 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -249,6 +249,9 @@ pub type HydraAccountOperation { ProcessSplitUtxosAtOpen { tree_or_proofs_with_token_map: TreeOrProofsWithTokenMap, } +} + +pub type ProcessMigrationRedeemer { ProcessMigration { account: UserAccount } } diff --git a/validators/hydra_account/core.ak b/validators/hydra_account/core.ak index bb14891..71d975a 100644 --- a/validators/hydra_account/core.ak +++ b/validators/hydra_account/core.ak @@ -14,9 +14,9 @@ use hydra_dex/types.{ DexOrderBookDatum, HydraAccountMigrate, HydraAccountOperate, HydraAccountOperation, HydraAccountRedeemer, HydraAccountSpamPreventionWithdraw, HydraAccountTrade, ProcessCancelWithdrawal, - ProcessCombineUtxosAtClose, ProcessMigration, ProcessSameAccountTransferal, - ProcessSplitUtxosAtOpen, ProcessTransferal, ProcessWithdrawal, - TreeOrProofsWithTokenMap, UserAccount, + ProcessCombineUtxosAtClose, ProcessMigration, ProcessMigrationRedeemer, + ProcessSameAccountTransferal, ProcessSplitUtxosAtOpen, ProcessTransferal, + ProcessWithdrawal, TreeOrProofsWithTokenMap, UserAccount, } use hydra_dex/utils.{get_dex_order_book_datum} @@ -80,31 +80,30 @@ validator hydra_account(dex_oracle_nft: PolicyId) { } } - withdraw( - redeemer: HydraAccountOperation, - credential: Credential, - tx: Transaction, - ) { - when redeemer is { - ProcessWithdrawal { mpf_action } -> - withdrawal(dex_oracle_nft, mpf_action, tx) - ProcessCancelWithdrawal { mpf_action } -> - cancel_withdrawal(dex_oracle_nft, mpf_action, tx) - ProcessSameAccountTransferal { account } -> - same_account_transferal(dex_oracle_nft, account, tx) - ProcessTransferal -> transferal(dex_oracle_nft, tx) - ProcessSplitUtxosAtOpen { tree_or_proofs_with_token_map } -> { - let TreeOrProofsWithTokenMap { proof, token_map } = - tree_or_proofs_with_token_map - split_utxos_at_open(dex_oracle_nft, proof, token_map, tx) - } - ProcessCombineUtxosAtClose { tree_or_proofs_with_token_map } -> { - let TreeOrProofsWithTokenMap { proof, token_map } = - tree_or_proofs_with_token_map - combine_utxos_at_close(dex_oracle_nft, proof, token_map, tx) + withdraw(redeemer: Data, credential: Credential, tx: Transaction) { + if redeemer is operation: HydraAccountOperation { + when operation is { + ProcessWithdrawal { mpf_action } -> + withdrawal(dex_oracle_nft, mpf_action, tx) + ProcessCancelWithdrawal { mpf_action } -> + cancel_withdrawal(dex_oracle_nft, mpf_action, tx) + ProcessSameAccountTransferal { account } -> + same_account_transferal(dex_oracle_nft, account, tx) + ProcessTransferal -> transferal(dex_oracle_nft, tx) + ProcessSplitUtxosAtOpen { tree_or_proofs_with_token_map } -> { + let TreeOrProofsWithTokenMap { proof, token_map } = + tree_or_proofs_with_token_map + split_utxos_at_open(dex_oracle_nft, proof, token_map, tx) + } + ProcessCombineUtxosAtClose { tree_or_proofs_with_token_map } -> { + let TreeOrProofsWithTokenMap { proof, token_map } = + tree_or_proofs_with_token_map + combine_utxos_at_close(dex_oracle_nft, proof, token_map, tx) + } } - ProcessMigration { account } -> - migration(dex_oracle_nft, account, credential, tx) + } else { + expect ProcessMigration { account }: ProcessMigrationRedeemer = redeemer + migration(dex_oracle_nft, account, credential, tx) } } diff --git a/validators/tests/hydra_account/spend.ak b/validators/tests/hydra_account/spend.ak index 3c9e0f3..6108d25 100644 --- a/validators/tests/hydra_account/spend.ak +++ b/validators/tests/hydra_account/spend.ak @@ -135,10 +135,7 @@ test s8_spend_success_migrate() { |> tx_in(True, mock_tx_hash(0), 0, zero, mock_hydra_account_address) |> tx_in_inline_datum(True, account) |> script_withdrawal(True, mock_hydra_account, 0) - |> withdrawal_redeemer_value( - True, - ProcessMigration { account }, - ) + |> withdrawal_redeemer_value(True, ProcessMigration { account }) |> complete() ha.hydra_account.spend( From ff5d7e2512806a0c6c6d333f9c7f3942bc9b26c5 Mon Sep 17 00:00:00 2001 From: twwu123 Date: Mon, 16 Mar 2026 16:09:55 +0800 Subject: [PATCH 05/30] change only minted check to policy mint check --- validators/hydra_user_intent.ak | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/validators/hydra_user_intent.ak b/validators/hydra_user_intent.ak index d3679d4..aa19c23 100644 --- a/validators/hydra_user_intent.ak +++ b/validators/hydra_user_intent.ak @@ -3,8 +3,8 @@ use cardano/address.{from_script} use cardano/assets.{PolicyId, flatten} use cardano/transaction.{OutputReference, Transaction} use cocktail.{ - key_signed, only_minted_token, output_inline_datum, outputs_at_with_policy, - outputs_with_policy, + key_signed, output_inline_datum, outputs_at_with_policy, outputs_with_policy, + policy_only_minted_token, } use hydra_dex/account_utils.{master_auth_by_account, trade_auth_by_account} use hydra_dex/types.{ @@ -61,7 +61,7 @@ validator hydra_user_intent(dex_oracle_nft: PolicyId) { from_script(oracle.hydra_user_intent_script_hash) when redeemer is { MintTradeIntent { account, intent } -> { - let token_check = only_minted_token(mint, policy_id, "", 1) + let token_check = policy_only_minted_token(mint, policy_id, "", 1) let only_output_check = when outputs_at_with_policy( @@ -85,7 +85,7 @@ validator hydra_user_intent(dex_oracle_nft: PolicyId) { token_check? && only_output_check? && is_account_auth? } MintMasterIntent { account, intent } -> { - let token_check = only_minted_token(mint, policy_id, "", 1) + let token_check = policy_only_minted_token(mint, policy_id, "", 1) let only_output_check = when outputs_at_with_policy( From a38f10d9ab73874ed20d3340d7efac875a3ddc63 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Tue, 17 Mar 2026 17:30:13 +0800 Subject: [PATCH 06/30] feat: vault deposit and withdrawal --- lib/hydra_dex/account_utils.ak | 28 ++ lib/hydra_dex/deposit_utils.ak | 45 ++ lib/hydra_dex/price_oracle_utils.ak | 66 +++ lib/hydra_dex/types.ak | 65 +++ lib/hydra_dex/utils.ak | 16 + lib/hydra_dex/withdraw_utils.ak | 96 ++++ spec/8_hydra_account/w_vault_deposit.md | 34 ++ spec/8_hydra_account/w_vault_withdrawal.md | 44 ++ validators/hydra_account/core.ak | 27 +- validators/hydra_account/vault_deposit.ak | 192 ++++++++ validators/hydra_account/vault_withdrawal.ak | 236 +++++++++ .../tests/deposit_utils/cal_shares_amount.ak | 48 ++ .../tests/deposit_utils/combine_m_value.ak | 82 ++++ .../deposit_utils/convert_m_value_to_usd.ak | 68 +++ .../tests/hydra_account/vault_deposit.ak | 375 ++++++++++++++ .../tests/hydra_account/vault_withdrawal.ak | 457 ++++++++++++++++++ .../cal_per_user_operator_fee.ak | 61 +++ .../withdraw_utils/check_output_value.ak | 87 ++++ .../withdraw_utils/compute_fee_shares.ak | 50 ++ .../withdraw_utils/convert_shares_to_usd.ak | 48 ++ 20 files changed, 2124 insertions(+), 1 deletion(-) create mode 100644 lib/hydra_dex/deposit_utils.ak create mode 100644 lib/hydra_dex/price_oracle_utils.ak create mode 100644 lib/hydra_dex/withdraw_utils.ak create mode 100644 spec/8_hydra_account/w_vault_deposit.md create mode 100644 spec/8_hydra_account/w_vault_withdrawal.md create mode 100644 validators/hydra_account/vault_deposit.ak create mode 100644 validators/hydra_account/vault_withdrawal.ak create mode 100644 validators/tests/deposit_utils/cal_shares_amount.ak create mode 100644 validators/tests/deposit_utils/combine_m_value.ak create mode 100644 validators/tests/deposit_utils/convert_m_value_to_usd.ak create mode 100644 validators/tests/hydra_account/vault_deposit.ak create mode 100644 validators/tests/hydra_account/vault_withdrawal.ak create mode 100644 validators/tests/withdraw_utils/cal_per_user_operator_fee.ak create mode 100644 validators/tests/withdraw_utils/check_output_value.ak create mode 100644 validators/tests/withdraw_utils/compute_fee_shares.ak create mode 100644 validators/tests/withdraw_utils/convert_shares_to_usd.ak diff --git a/lib/hydra_dex/account_utils.ak b/lib/hydra_dex/account_utils.ak index a59dee8..2a55efa 100644 --- a/lib/hydra_dex/account_utils.ak +++ b/lib/hydra_dex/account_utils.ak @@ -49,6 +49,34 @@ pub fn create_account_outputs_filter( } } +pub fn create_master_key_inputs_filter( + master_key: Credential, + hydra_account_script_hash: ByteArray, +) { + fn(input: Input) { + if input.output.address == from_script(hydra_account_script_hash) { + expect input_datum: UserAccount = input_inline_datum(input) + get_master_key(input_datum) == master_key + } else { + False + } + } +} + +pub fn create_master_key_outputs_filter( + master_key: Credential, + hydra_account_script_hash: ByteArray, +) { + fn(output: Output) { + if output.address == from_script(hydra_account_script_hash) { + expect output_datum: UserAccount = output_inline_datum(output) + get_master_key(output_datum) == master_key + } else { + False + } + } +} + // Account Value related pub fn hash_token(policy_id: PolicyId, asset_name: AssetName) -> AssetName { diff --git a/lib/hydra_dex/deposit_utils.ak b/lib/hydra_dex/deposit_utils.ak new file mode 100644 index 0000000..2bd5e1f --- /dev/null +++ b/lib/hydra_dex/deposit_utils.ak @@ -0,0 +1,45 @@ +use aiken/cbor +use aiken/collection/dict +use cardano/assets.{Value} +use hydra_dex/types.{MValue} + +pub fn to_mvalue(value: Value) -> MValue { + let data = cbor.serialise(value) + expect Some(mvalue_raw): Option = cbor.deserialise(data) + expect mvalue: MValue = mvalue_raw + mvalue +} + +pub fn combine_m_value(left_m_value: MValue, right_m_value: MValue) -> MValue { + let left_dict = dict.from_pairs(left_m_value) + let right_dict = dict.from_pairs(right_m_value) + + dict.union_with( + left_dict, + right_dict, + fn(_k, v1, v2) { + let v1_dict = dict.from_pairs(v1) + let v2_dict = dict.from_pairs(v2) + let all = + dict.union_with( + v1_dict, + v2_dict, + fn(_k, v_v_1, v_v_2) { Some(v_v_1 + v_v_2) }, + ) + |> dict.to_pairs() + Some(all) + }, + ) + |> dict.to_pairs() +} + +pub fn cal_shares_amount( + usd_value: Int, + vault_equity: Int, + total_shares: Int, +) -> Int { + when total_shares is { + 0 -> fail @"Total shares cannot be zero" + _ -> usd_value * total_shares / vault_equity + } +} diff --git a/lib/hydra_dex/price_oracle_utils.ak b/lib/hydra_dex/price_oracle_utils.ak new file mode 100644 index 0000000..2a1903e --- /dev/null +++ b/lib/hydra_dex/price_oracle_utils.ak @@ -0,0 +1,66 @@ +use aiken/cbor +use aiken/collection/list +use aiken/collection/pairs +use cardano/assets.{AssetName, PolicyId, Value} +use cardano/transaction.{Input} +use cocktail.{verify_pub_keys, verify_signatures} +use hydra_dex/types.{MValue, Message} + +pub fn verify_prices_oracle_messages( + prices_message: ByteArray, + inputs: List, + hydra_signers: List, + hydra_node_pub_keys: List, + signatures: List, +) -> (Int, Pairs<(PolicyId, AssetName), Int>, Bool) { + expect Some(signed_data) = cbor.deserialise(prices_message) + expect Message { vault_equity, prices, utxo_ref }: Message = signed_data + + let is_utxo_consumed = + list.any(inputs, fn(input) { input.output_reference == utxo_ref }) + + let keys_check = verify_pub_keys(hydra_node_pub_keys, hydra_signers) + let signatures_check = + verify_signatures(hydra_node_pub_keys, prices_message, signatures) + + let message_verified = is_utxo_consumed? && keys_check? && signatures_check? + + (vault_equity, prices, message_verified) +} + +pub fn convert_value_to_usd( + value: Value, + prices: Pairs<(PolicyId, AssetName), Int>, +) -> Int { + assets.reduce( + value, + 0, + fn(policy_id, asset_name, amount, acc) { + expect Some(price) = prices |> pairs.get_first((policy_id, asset_name)) + + acc + amount * price + }, + ) +} + +pub fn convert_m_value_to_usd( + m_value: MValue, + prices: Pairs<(PolicyId, AssetName), Int>, +) -> Int { + list.foldl( + m_value, + 0, + fn(policy_pair: Pair>, acc: Int) { + list.foldl( + policy_pair.2nd, + acc, + fn(asset_pair: Pair, nested_acc: Int) { + expect Some(price) = + prices + |> pairs.get_first((policy_pair.1st, asset_pair.1st)) + nested_acc + price * asset_pair.2nd + }, + ) + }, + ) +} diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index 40170ba..7b72736 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -249,6 +249,13 @@ pub type HydraAccountOperation { ProcessSplitUtxosAtOpen { tree_or_proofs_with_token_map: TreeOrProofsWithTokenMap, } + ProcessVaultDeposit(ByteArray, List, SharesMPFAction) + ProcessVaultWithdrawal( + ByteArray, + List, + SharesMPFAction, + SharesMPFAction, + ) } pub type ProcessMigrationRedeemer { @@ -307,3 +314,61 @@ pub type HydraInitialRedeemer { ViaAbort ViaCommit { committed_refs: List } } + +// Shares Merkle Patricia Forestry action type +// Note: new_value/to are computed from shares + total_deposited, not passed in redeemer +pub type SharesMPFAction { + SharesInsert { proof: Proof } + SharesUpdate { from: ByteArray, to_proof: Proof } + SharesDelete { proof: Proof, old_value: ByteArray } +} + +// Shares Record entry (serialized into MPF values) +pub type SharesRecordEntry { + shares: Int, + total_deposited: Int, +} + +// Price oracle message +pub type Message { + vault_equity: Int, + prices: Pairs<(PolicyId, AssetName), Int>, + utxo_ref: OutputReference, +} + +pub type VaultDepositIntentDatumL2 { + vault_oracle_nft: PolicyId, + depositor: UserAccount, + deposit_amount: MValue, +} + +pub type VaultWithdrawalIntentDatumL2 { + vault_oracle_nft: PolicyId, + withdrawer: UserAccount, + shares_to_redeem: Int, +} + +// Vault Oracle Datum — holds config + state, commits to Hydra +pub type VaultOracleDatum { + // Config (all updatable via UpdateConfig) + app_oracle: PolicyId, + vault_script_hash: ByteArray, + l1_deposit_intent_script_hash: ByteArray, + l1_withdrawal_intent_script_hash: ByteArray, + l2_deposit_intent_script_hash: ByteArray, + l2_withdrawal_intent_script_hash: ByteArray, + pluggable_logic: ByteArray, + vault_stake_rotation_script_hash: ByteArray, + operator_key: VerificationKeyHash, + operator_account: UserAccount, + operator_charge_percentage: Int, + operator_min_deposit_percentage: Int, + hydra_node_pub_keys: List, + is_active: Bool, + // State (mutable) + total_shares: Int, + operator_shares: Int, + total_deposited: Int, + shares_merkle_root: ByteArray, + total_fee_collected: Int, +} diff --git a/lib/hydra_dex/utils.ak b/lib/hydra_dex/utils.ak index 50204d7..5ed711b 100644 --- a/lib/hydra_dex/utils.ak +++ b/lib/hydra_dex/utils.ak @@ -126,3 +126,19 @@ pub fn to_mvalue(value: Value) -> MValue { expect mvalue: MValue = mvalue_raw mvalue } + +/// Find the policy being burnt (negative quantity) from mint field +pub fn get_burning_intent_policy( + mint: List<(PolicyId, AssetName, Int)>, +) -> PolicyId { + expect Some((policy_id, _asset_name, quantity)) = + list.find( + mint, + fn(entry) { + let (_, _, qty) = entry + qty < 0 + }, + ) + expect quantity == -1 + policy_id +} diff --git a/lib/hydra_dex/withdraw_utils.ak b/lib/hydra_dex/withdraw_utils.ak new file mode 100644 index 0000000..71d5d37 --- /dev/null +++ b/lib/hydra_dex/withdraw_utils.ak @@ -0,0 +1,96 @@ +use aiken/cbor +use aiken/collection/pairs +use aiken/merkle_patricia_forestry as mpf +use cardano/assets.{AssetName, PolicyId, Value} +use hydra_dex/types.{ + SharesInsert, SharesMPFAction, SharesRecordEntry, SharesUpdate, UserAccount, +} + +pub fn convert_shares_to_usd( + shares_amount: Int, + total_shares: Int, + vault_equity: Int, +) -> Int { + shares_amount * vault_equity / total_shares +} + +// Round UP: ceil(a * b / c) = (a * b + c - 1) / c +fn ceil_div(numerator: Int, denominator: Int) -> Int { + ( numerator + denominator - 1 ) / denominator +} + +pub fn cal_per_user_operator_fee( + withdrawal_value: Int, + cost_basis: Int, + operator_charge_percentage: Int, +) -> Int { + let profit = withdrawal_value - cost_basis + if profit <= 0 { + 0 + } else { + // Round UP — fee never underpaid + ceil_div(profit * operator_charge_percentage, 100) + } +} + +pub fn compute_fee_shares(fee: Int, total_shares: Int, vault_equity: Int) -> Int { + // Round UP — protects operator + ceil_div(fee * total_shares, vault_equity) +} + +pub fn check_output_value_equal_to_shares_usd_value( + output_value: Value, + shares_usd_value: Int, + prices: Pairs<(PolicyId, AssetName), Int>, +) -> Bool { + assets.reduce( + output_value, + 0, + fn(policy_id, asset_name, amount, acc) { + expect Some(price) = prices |> pairs.get_first((policy_id, asset_name)) + + acc + amount * price + }, + ) == shares_usd_value +} + +// Apply operator fee share MPF action after all user withdrawals +pub fn apply_operator_fee_share( + current_root: ByteArray, + total_fee_shares: Int, + operator_account: UserAccount, + operator_action: SharesMPFAction, +) -> ByteArray { + if total_fee_shares <= 0 { + current_root + } else { + // Use Account directly as MPF key + let mpf_key = cbor.serialise(operator_account) + when operator_action is { + SharesInsert { proof } -> { + // Operator has no existing entry - compute new_value + let new_entry = + SharesRecordEntry { shares: total_fee_shares, total_deposited: 0 } + let new_value = cbor.serialise(new_entry) + let trie = mpf.from_root(current_root) + let new_trie = mpf.insert(trie, mpf_key, new_value, proof) + mpf.root(new_trie) + } + SharesUpdate { from, to_proof } -> { + // Operator has existing entry — add fee shares, total_deposited unchanged + expect Some(from_data) = cbor.deserialise(from) + expect old_entry: SharesRecordEntry = from_data + let new_entry = + SharesRecordEntry { + shares: old_entry.shares + total_fee_shares, + total_deposited: old_entry.total_deposited, + } + let to = cbor.serialise(new_entry) + let trie = mpf.from_root(current_root) + let new_trie = mpf.update(trie, mpf_key, to_proof, from, to) + mpf.root(new_trie) + } + _ -> fail @"Invalid MPF action for operator fee share" + } + } +} diff --git a/spec/8_hydra_account/w_vault_deposit.md b/spec/8_hydra_account/w_vault_deposit.md new file mode 100644 index 0000000..52b0dfb --- /dev/null +++ b/spec/8_hydra_account/w_vault_deposit.md @@ -0,0 +1,34 @@ +# Specification - HydraAccount - Vault Deposit + +## User Action + +- Ref input with `dex_oracle_nft` +- Get `II` - Intent Input from burn event (negative mint quantity) +- `II` with `VaultDepositIntentDatumL2` datum + - `vault_oracle_nft`, `depositor: UserAccount`, `deposit_amount: MValue` +- Get Vault Oracle input/output (UTxO with `vault_oracle_nft`) +- Validate intent script matches vault config (`intent_policy_id == l2_deposit_intent_script_hash`) +- Verify prices message with hydra node signatures +- Calculate shares: `shares_minted = (deposit_usd_value * total_shares) / vault_equity` (round DOWN) +- Categorize inputs into + - `DI` - Depositor Inputs (by full `UserAccount`) + - `VI` - Vault Inputs (by `master_key == Script(l2_deposit_intent_script_hash)`) + - Other inputs +- Categorize outputs into + - `DO` - Depositor Outputs (by full `UserAccount`) + - `VO` - Vault Outputs (by `master_key == Script(l2_deposit_intent_script_hash)`) + - Other outputs +- No other inputs/outputs at `hydra_account_script_hash` +- The 3 values are equal: + 1. Deduct in value for depositor (`DI` - `DO`) without lovelace + 2. Increase in value for vault (`VO` - `VI`) without lovelace + 3. Value in deposit intent (`deposit_amount`) +- Verify Merkle transition (SharesInsert or SharesUpdate) + - Key: `cbor.serialise(depositor)` (UserAccount) + - Value: `SharesRecordEntry { shares, total_deposited }` +- Vault Oracle output datum updated: + - `total_shares += shares_minted` + - `total_deposited += deposit_usd_value` + - `shares_merkle_root = computed_new_root` +- The intent token is burnt +- Signed by `operation_key` diff --git a/spec/8_hydra_account/w_vault_withdrawal.md b/spec/8_hydra_account/w_vault_withdrawal.md new file mode 100644 index 0000000..00f6291 --- /dev/null +++ b/spec/8_hydra_account/w_vault_withdrawal.md @@ -0,0 +1,44 @@ +# Specification - HydraAccount - Vault Withdrawal + +## User Action + +- Ref input with `dex_oracle_nft` +- Get `II` - Intent Input from burn event (negative mint quantity) +- `II` with `VaultWithdrawalIntentDatumL2` datum + - `vault_oracle_nft`, `withdrawer: UserAccount`, `shares_to_redeem: Int` +- Get Vault Oracle input/output (UTxO with `vault_oracle_nft`) +- Validate intent script matches vault config (`intent_policy_id == l2_withdrawal_intent_script_hash`) +- Verify prices message with hydra node signatures +- Calculate withdrawal values: + - `gross_value = (shares_to_redeem * vault_equity) / total_shares` (round DOWN) + - `cost_basis` from merkle proof (proportional for partial withdrawal) + - `fee = ceil((profit * operator_charge_percentage) / 100)` if profit > 0 + - `fee_shares = ceil((fee * total_shares) / vault_equity)` + - `user_receives = gross_value - fee` +- Categorize inputs into + - `WI` - Withdrawer Inputs (by full `UserAccount`) + - `VI` - Vault Inputs (by `master_key == Script(l2_withdrawal_intent_script_hash)`) + - Other inputs +- Categorize outputs into + - `WO` - Withdrawer Outputs (by full `UserAccount`) + - `VO` - Vault Outputs (by `master_key == Script(l2_withdrawal_intent_script_hash)`) + - Other outputs +- No other inputs/outputs at `hydra_account_script_hash` +- Value transfer validated (in USD): + - Vault deducted == `user_receives` + - Withdrawer added == `user_receives` +- Verify User Merkle transition (SharesUpdate or SharesDelete) + - Key: `cbor.serialise(withdrawer)` (UserAccount) + - SharesDelete: full withdrawal, `shares_to_redeem == old_entry.shares` + - SharesUpdate: partial withdrawal, deduct shares and proportional cost_basis +- Apply Operator Fee Shares (if `fee_shares > 0`) + - Key: `cbor.serialise(operator_account)` (UserAccount) + - SharesInsert or SharesUpdate for operator +- Vault Oracle output datum updated: + - `total_shares = input_total_shares - shares_to_redeem + fee_shares` + - `operator_shares += fee_shares` + - `total_deposited -= cost_basis` + - `total_fee_collected += fee` + - `shares_merkle_root = final_root` +- The intent token is burnt +- Signed by `operation_key` OR `operator_key` diff --git a/validators/hydra_account/core.ak b/validators/hydra_account/core.ak index 71d975a..ba279fd 100644 --- a/validators/hydra_account/core.ak +++ b/validators/hydra_account/core.ak @@ -9,6 +9,8 @@ use hydra_account/migration.{migration} use hydra_account/same_account_transferal.{same_account_transferal} use hydra_account/split_utxos_at_open.{split_utxos_at_open} use hydra_account/transferal.{transferal} +use hydra_account/vault_deposit.{vault_deposit} +use hydra_account/vault_withdrawal.{vault_withdrawal} use hydra_account/withdrawal.{withdrawal} use hydra_dex/types.{ DexOrderBookDatum, HydraAccountMigrate, HydraAccountOperate, @@ -16,7 +18,8 @@ use hydra_dex/types.{ HydraAccountSpamPreventionWithdraw, HydraAccountTrade, ProcessCancelWithdrawal, ProcessCombineUtxosAtClose, ProcessMigration, ProcessMigrationRedeemer, ProcessSameAccountTransferal, ProcessSplitUtxosAtOpen, ProcessTransferal, - ProcessWithdrawal, TreeOrProofsWithTokenMap, UserAccount, + ProcessVaultDeposit, ProcessVaultWithdrawal, ProcessWithdrawal, + TreeOrProofsWithTokenMap, UserAccount, } use hydra_dex/utils.{get_dex_order_book_datum} @@ -100,6 +103,28 @@ validator hydra_account(dex_oracle_nft: PolicyId) { tree_or_proofs_with_token_map combine_utxos_at_close(dex_oracle_nft, proof, token_map, tx) } + ProcessVaultDeposit(prices_message, signatures, mpf_action) -> + vault_deposit( + dex_oracle_nft, + prices_message, + signatures, + mpf_action, + tx, + ) + ProcessVaultWithdrawal( + prices_message, + signatures, + mpf_action, + operator_mpf_action, + ) -> + vault_withdrawal( + dex_oracle_nft, + prices_message, + signatures, + mpf_action, + operator_mpf_action, + tx, + ) } } else { expect ProcessMigration { account }: ProcessMigrationRedeemer = redeemer diff --git a/validators/hydra_account/vault_deposit.ak b/validators/hydra_account/vault_deposit.ak new file mode 100644 index 0000000..9fe8b4c --- /dev/null +++ b/validators/hydra_account/vault_deposit.ak @@ -0,0 +1,192 @@ +use aiken/cbor +use aiken/merkle_patricia_forestry as mpf +use cardano/address.{Script, from_script} +use cardano/assets.{ + PolicyId, flatten, from_asset_list, merge, negate, without_lovelace, +} +use cardano/transaction.{Transaction} +use cocktail.{ + group_inputs_2, group_outputs_2, input_inline_datum, inputs_at, + inputs_at_with_policy, inputs_value, inputs_with_policy, key_signed, + output_inline_datum, outputs_at, outputs_value, outputs_with_policy, +} +use hydra_dex/account_utils.{ + create_account_inputs_filter, create_account_outputs_filter, + create_master_key_inputs_filter, create_master_key_outputs_filter, +} +use hydra_dex/deposit_utils.{cal_shares_amount} +use hydra_dex/price_oracle_utils.{ + convert_m_value_to_usd, verify_prices_oracle_messages, +} +use hydra_dex/types.{ + DexOrderBookDatum, SharesInsert, SharesMPFAction, SharesRecordEntry, + SharesUpdate, VaultDepositIntentDatumL2, VaultOracleDatum, +} +use hydra_dex/utils.{get_burning_intent_policy, get_dex_order_book_datum} + +pub fn vault_deposit( + dex_oracle_nft: PolicyId, + prices_message: ByteArray, + signatures: List, + mpf_action: SharesMPFAction, + tx: Transaction, +) -> Bool { + let Transaction { + inputs, + outputs, + reference_inputs, + extra_signatories, + mint, + .. + } = tx + + // 1. Get DexOrderBook datum (reference input with `dex_oracle_nft`) + let DexOrderBookDatum { operation_key, hydra_account_script_hash, .. }: DexOrderBookDatum = + reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) + + // 2. Get L2 Deposit Intent from burn event (implicitly verifies burn) + let mint_list = mint |> flatten() + let intent_policy_id = get_burning_intent_policy(mint_list) + let intent_address = from_script(intent_policy_id) + + expect [intent_input] = + inputs_at_with_policy(inputs, intent_address, intent_policy_id) + expect VaultDepositIntentDatumL2 { + vault_oracle_nft, + depositor, + deposit_amount, + }: VaultDepositIntentDatumL2 = input_inline_datum(intent_input) + + // 3. Get Vault Oracle input/output (derived from intent datum) + expect [vault_oracle_input] = inputs_with_policy(inputs, vault_oracle_nft) + expect [vault_oracle_output] = outputs_with_policy(outputs, vault_oracle_nft) + + expect input_oracle_datum: VaultOracleDatum = + input_inline_datum(vault_oracle_input) + expect output_oracle_datum: VaultOracleDatum = + output_inline_datum(vault_oracle_output) + + let VaultOracleDatum { + l2_deposit_intent_script_hash, + hydra_node_pub_keys, + total_shares: input_total_shares, + total_deposited: input_total_deposited, + shares_merkle_root: input_merkle_root, + .. + } = input_oracle_datum + + // 4. Validate intent script matches vault config + let is_intent_valid = intent_policy_id == l2_deposit_intent_script_hash + + // 5. Verify prices message + let (vault_equity, prices, is_prices_verified) = + verify_prices_oracle_messages( + prices_message, + inputs, + hydra_node_pub_keys, + hydra_node_pub_keys, + signatures, + ) + + // 6. Calculate shares and USD value (Division Order: multiply first!) + let deposit_usd_value = convert_m_value_to_usd(deposit_amount, prices) + // Round DOWN (integer division) - protects vault + let shares_minted = + cal_shares_amount(deposit_usd_value, vault_equity, input_total_shares) + + // 7. Group Account UTxOs (following transferal.ak pattern) + // Vault UTxOs are filtered by master_key == intent script hash + let vault_master_key = Script(l2_deposit_intent_script_hash) + let depositor_input_filter = + create_account_inputs_filter(depositor, hydra_account_script_hash) + let vault_input_filter = + create_master_key_inputs_filter(vault_master_key, hydra_account_script_hash) + let depositor_output_filter = + create_account_outputs_filter(depositor, hydra_account_script_hash) + let vault_output_filter = + create_master_key_outputs_filter( + vault_master_key, + hydra_account_script_hash, + ) + + let (depositor_inputs, vault_inputs, other_inputs) = + group_inputs_2(inputs, depositor_input_filter, vault_input_filter) + let (depositor_outputs, vault_outputs, other_outputs) = + group_outputs_2(outputs, depositor_output_filter, vault_output_filter) + + // No other inputs/outputs at hydra_account_script_hash + let hydra_account_address = from_script(hydra_account_script_hash) + let no_other_account_inputs = + inputs_at(other_inputs, hydra_account_address) == [] + let no_other_account_outputs = + outputs_at(other_outputs, hydra_account_address) == [] + + // 8. Validate value transfer + let deducted_amount = + inputs_value(depositor_inputs) + |> merge(negate(outputs_value(depositor_outputs))) + |> without_lovelace() + let added_amount = + outputs_value(vault_outputs) + |> merge(negate(inputs_value(vault_inputs))) + |> without_lovelace() + let intent_amount = from_asset_list(deposit_amount) + + let is_value_transfer_correct = + deducted_amount == added_amount && added_amount == intent_amount + + // 9. Verify Merkle root transition + let mpf_key = cbor.serialise(depositor) + let computed_new_root = + when mpf_action is { + SharesInsert { proof } -> { + // New depositor + let new_entry = + SharesRecordEntry { + shares: shares_minted, + total_deposited: deposit_usd_value, + } + let new_value = cbor.serialise(new_entry) + let trie = mpf.from_root(input_merkle_root) + let new_trie = mpf.insert(trie, mpf_key, new_value, proof) + mpf.root(new_trie) + } + SharesUpdate { from, to_proof } -> { + // Existing depositor + expect Some(from_data) = cbor.deserialise(from) + expect old_entry: SharesRecordEntry = from_data + let new_entry = + SharesRecordEntry { + shares: old_entry.shares + shares_minted, + total_deposited: old_entry.total_deposited + deposit_usd_value, + } + let to = cbor.serialise(new_entry) + let trie = mpf.from_root(input_merkle_root) + let new_trie = mpf.update(trie, mpf_key, to_proof, from, to) + mpf.root(new_trie) + } + _ -> fail @"Invalid MPF action for deposit" + } + + // 10. Verify Vault Oracle output datum + let is_oracle_datum_updated = + output_oracle_datum == VaultOracleDatum { + ..input_oracle_datum, + total_shares: input_total_shares + shares_minted, + total_deposited: input_total_deposited + deposit_usd_value, + shares_merkle_root: computed_new_root, + } + + // 11. Verify signature (operation_key) + let is_signed = key_signed(extra_signatories, operation_key) + + and { + is_intent_valid?, + is_prices_verified?, + no_other_account_inputs?, + no_other_account_outputs?, + is_value_transfer_correct?, + is_oracle_datum_updated?, + is_signed?, + } +} diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak new file mode 100644 index 0000000..2e69a91 --- /dev/null +++ b/validators/hydra_account/vault_withdrawal.ak @@ -0,0 +1,236 @@ +use aiken/cbor +use aiken/merkle_patricia_forestry as mpf +use cardano/address.{Script, from_script} +use cardano/assets.{PolicyId, flatten, merge, negate} +use cardano/transaction.{Transaction} +use cocktail.{ + group_inputs_2, group_outputs_2, input_inline_datum, inputs_at, + inputs_at_with_policy, inputs_value, inputs_with_policy, key_signed, + output_inline_datum, outputs_at, outputs_value, outputs_with_policy, +} +use hydra_dex/account_utils.{ + create_account_inputs_filter, create_account_outputs_filter, + create_master_key_inputs_filter, create_master_key_outputs_filter, +} +use hydra_dex/price_oracle_utils.{ + convert_value_to_usd, verify_prices_oracle_messages, +} +use hydra_dex/types.{ + DexOrderBookDatum, SharesDelete, SharesMPFAction, SharesRecordEntry, + SharesUpdate, VaultOracleDatum, VaultWithdrawalIntentDatumL2, +} +use hydra_dex/utils.{get_burning_intent_policy, get_dex_order_book_datum} +use hydra_dex/withdraw_utils.{ + apply_operator_fee_share, cal_per_user_operator_fee, compute_fee_shares, + convert_shares_to_usd, +} + +pub fn vault_withdrawal( + dex_oracle_nft: PolicyId, + prices_message: ByteArray, + signatures: List, + mpf_action: SharesMPFAction, + operator_mpf_action: SharesMPFAction, + tx: Transaction, +) -> Bool { + let Transaction { + inputs, + outputs, + reference_inputs, + extra_signatories, + mint, + .. + } = tx + + // 1. Get DexOrderBook datum (reference input with `dex_oracle_nft`) + let DexOrderBookDatum { operation_key, hydra_account_script_hash, .. }: DexOrderBookDatum = + reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) + + // 2. Get L2 Withdrawal Intent from burn event (implicitly verifies burn) + let mint_list = mint |> flatten() + let intent_policy_id = get_burning_intent_policy(mint_list) + let intent_address = from_script(intent_policy_id) + + expect [intent_input] = + inputs_at_with_policy(inputs, intent_address, intent_policy_id) + expect VaultWithdrawalIntentDatumL2 { + vault_oracle_nft, + withdrawer, + shares_to_redeem, + }: VaultWithdrawalIntentDatumL2 = input_inline_datum(intent_input) + + // 3. Get Vault Oracle input/output (derived from intent datum) + expect [vault_oracle_input] = inputs_with_policy(inputs, vault_oracle_nft) + expect [vault_oracle_output] = outputs_with_policy(outputs, vault_oracle_nft) + + expect input_oracle_datum: VaultOracleDatum = + input_inline_datum(vault_oracle_input) + expect output_oracle_datum: VaultOracleDatum = + output_inline_datum(vault_oracle_output) + + let VaultOracleDatum { + l2_withdrawal_intent_script_hash, + hydra_node_pub_keys, + operator_account, + operator_key, + operator_charge_percentage, + total_shares: input_total_shares, + operator_shares: input_operator_shares, + total_deposited: input_total_deposited, + shares_merkle_root: input_merkle_root, + total_fee_collected: input_total_fee_collected, + .. + } = input_oracle_datum + + // 4. Validate intent script matches vault config + let is_intent_valid = intent_policy_id == l2_withdrawal_intent_script_hash + + // 5. Verify prices message + let (vault_equity, prices, is_prices_verified) = + verify_prices_oracle_messages( + prices_message, + inputs, + hydra_node_pub_keys, + hydra_node_pub_keys, + signatures, + ) + + // 6. Calculate withdrawal values (Division Order: multiply first!) + // Gross value: Round DOWN (integer division) - protects vault + let gross_value = + convert_shares_to_usd(shares_to_redeem, input_total_shares, vault_equity) + + // Process User Merkle transition and calculate cost_basis + let mpf_key = cbor.serialise(withdrawer) + let (cost_basis, new_user_root) = + when mpf_action is { + SharesDelete { proof, old_value } -> { + // Total withdrawal + expect Some(old_data) = cbor.deserialise(old_value) + expect old_entry: SharesRecordEntry = old_data + expect shares_to_redeem == old_entry.shares + let cost = old_entry.total_deposited + let trie = mpf.from_root(input_merkle_root) + let new_trie = mpf.delete(trie, mpf_key, old_value, proof) + (cost, mpf.root(new_trie)) + } + SharesUpdate { from, to_proof } -> { + // Partial withdrawal + expect Some(from_data) = cbor.deserialise(from) + expect old_entry: SharesRecordEntry = from_data + expect old_entry.shares >= shares_to_redeem + // Proportional cost basis + let cost = + old_entry.total_deposited * shares_to_redeem / old_entry.shares + let new_entry = + SharesRecordEntry { + shares: old_entry.shares - shares_to_redeem, + total_deposited: old_entry.total_deposited - cost, + } + let to = cbor.serialise(new_entry) + let trie = mpf.from_root(input_merkle_root) + let new_trie = mpf.update(trie, mpf_key, to_proof, from, to) + (cost, mpf.root(new_trie)) + } + _ -> fail @"Invalid MPF action for withdrawal" + } + + // Calculate fee based on profit - Round UP to protect operator + let fee = + cal_per_user_operator_fee( + gross_value, + cost_basis, + operator_charge_percentage, + ) + + // Fee shares - Round UP to protect operator + let fee_shares = compute_fee_shares(fee, input_total_shares, vault_equity) + + // User receives (naturally rounds DOWN) + let user_receives = gross_value - fee + + // 7. Group Account UTxOs + // Vault UTxOs are filtered by master_key == intent script hash + let vault_master_key = Script(l2_withdrawal_intent_script_hash) + let withdrawer_input_filter = + create_account_inputs_filter(withdrawer, hydra_account_script_hash) + let vault_input_filter = + create_master_key_inputs_filter(vault_master_key, hydra_account_script_hash) + let withdrawer_output_filter = + create_account_outputs_filter(withdrawer, hydra_account_script_hash) + let vault_output_filter = + create_master_key_outputs_filter( + vault_master_key, + hydra_account_script_hash, + ) + + let (vault_inputs, withdrawer_inputs, other_inputs) = + group_inputs_2(inputs, vault_input_filter, withdrawer_input_filter) + let (vault_outputs, withdrawer_outputs, other_outputs) = + group_outputs_2(outputs, vault_output_filter, withdrawer_output_filter) + + // No other inputs/outputs at hydra_account_script_hash + let hydra_account_address = from_script(hydra_account_script_hash) + let no_other_account_inputs = + inputs_at(other_inputs, hydra_account_address) == [] + let no_other_account_outputs = + outputs_at(other_outputs, hydra_account_address) == [] + + // 8. Validate value transfer + // Vault loses user_receives (in USD value) + let vault_deducted = + merge(inputs_value(vault_inputs), negate(outputs_value(vault_outputs))) + let vault_deducted_usd = convert_value_to_usd(vault_deducted, prices) + + // Withdrawer gains user_receives (in USD value) + let withdrawer_added = + merge( + outputs_value(withdrawer_outputs), + negate(inputs_value(withdrawer_inputs)), + ) + let withdrawer_added_usd = convert_value_to_usd(withdrawer_added, prices) + + let is_value_transfer_correct = + vault_deducted_usd == user_receives && withdrawer_added_usd == user_receives + + // 10. Apply Operator Fee Shares (if fee > 0) + let final_root = + if fee_shares > 0 { + apply_operator_fee_share( + new_user_root, + fee_shares, + operator_account, + operator_mpf_action, + ) + } else { + new_user_root + } + + // 11. Verify Vault Oracle output datum + let is_oracle_datum_updated = + output_oracle_datum == VaultOracleDatum { + ..input_oracle_datum, + total_shares: input_total_shares - shares_to_redeem + fee_shares, + operator_shares: input_operator_shares + fee_shares, + total_deposited: input_total_deposited - cost_basis, + total_fee_collected: input_total_fee_collected + fee, + shares_merkle_root: final_root, + } + + // 12. Verify signature (operation_key OR operator_key) + let is_signed = + key_signed(extra_signatories, operation_key) || key_signed( + extra_signatories, + operator_key, + ) + + and { + is_intent_valid?, + is_prices_verified?, + no_other_account_inputs?, + no_other_account_outputs?, + is_value_transfer_correct?, + is_oracle_datum_updated?, + is_signed?, + } +} diff --git a/validators/tests/deposit_utils/cal_shares_amount.ak b/validators/tests/deposit_utils/cal_shares_amount.ak new file mode 100644 index 0000000..6715860 --- /dev/null +++ b/validators/tests/deposit_utils/cal_shares_amount.ak @@ -0,0 +1,48 @@ +use hydra_dex/deposit_utils.{cal_shares_amount} + +// ========== cal_shares_amount tests ========== +// Formula: shares = usd_value * total_shares / vault_equity + +// Basic calculation: 1000 USD with vault_equity=2000, total_shares=1000 → 500 shares +test du_cal_shares_amount_basic() { + cal_shares_amount(1000, 2000, 1000) == 500 +} + +// Equal values: 1000 USD with vault_equity=1000, total_shares=1000 → 1000 shares +test du_cal_shares_amount_equal() { + cal_shares_amount(1000, 1000, 1000) == 1000 +} + +// Larger vault: 1000 USD with vault_equity=10000, total_shares=1000 → 100 shares +test du_cal_shares_amount_larger_vault() { + cal_shares_amount(1000, 10000, 1000) == 100 +} + +// Larger total_shares: 1000 USD with vault_equity=1000, total_shares=10000 → 10000 shares +test du_cal_shares_amount_more_shares() { + cal_shares_amount(1000, 1000, 10000) == 10000 +} + +// Round down: 100 USD with vault_equity=300, total_shares=100 → 33 shares (100*100/300 = 33.33...) +test du_cal_shares_amount_round_down() { + cal_shares_amount(100, 300, 100) == 33 +} + +// Zero USD value: 0 USD → 0 shares +test du_cal_shares_amount_zero_usd() { + cal_shares_amount(0, 1000, 1000) == 0 +} + +// Fail when total_shares is zero +test du_cal_shares_amount_fail_zero_total_shares() fail { + cal_shares_amount(1000, 1000, 0) == 0 +} + +// Real-world example using mock values: +// vault_equity = 2400000000 (2400 USD with 6 decimals) +// total_shares = 3000000000000000 +// deposit_usd = 3000000 (3 USD with 6 decimals) +// expected = 3000000 * 3000000000000000 / 2400000000 = 3750000000000 +test du_cal_shares_amount_real_world() { + cal_shares_amount(3000000, 2400000000, 3000000000000000) == 3750000000000 +} diff --git a/validators/tests/deposit_utils/combine_m_value.ak b/validators/tests/deposit_utils/combine_m_value.ak new file mode 100644 index 0000000..92e5a8a --- /dev/null +++ b/validators/tests/deposit_utils/combine_m_value.ak @@ -0,0 +1,82 @@ +use hydra_dex/deposit_utils.{combine_m_value} +use hydra_dex/types.{MValue} + +const m_value_a = + [ + Pair("", [Pair("", 100)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair(#"5553444d", 100)], + ), + ] + +const m_value_b = + [ + Pair("", [Pair("", 200)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair(#"5553444d", 200)], + ), + ] + +const m_value_a_and_b = + [ + Pair("", [Pair("", 300)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair(#"5553444d", 300)], + ), + ] + +const m_value_a_and_b_wrong = + [ + Pair("", [Pair("", 300)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair(#"5553444d", 301)], + ), + ] + +const m_value_c = + [ + Pair("", [Pair("", 300)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair("", 300), Pair(#"5553444d", 300)], + ), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c999", + [Pair(#"5553444d", 300)], + ), + ] + +const m_value_a_and_b_and_c = + [ + Pair("", [Pair("", 600)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair("", 300), Pair(#"5553444d", 600)], + ), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c999", + [Pair(#"5553444d", 300)], + ), + ] + +const empty_m_value: MValue = [] + +test du_combine_m_value_a_and_b() { + combine_m_value(m_value_a, m_value_b) == m_value_a_and_b +} + +test du_combine_m_value_a_and_b_wrong() { + combine_m_value(m_value_a, m_value_b) != m_value_a_and_b_wrong +} + +test du_combine_m_value_a_and_b_and_c() { + (combine_m_value(m_value_a_and_b, m_value_c) == m_value_a_and_b_and_c)? +} + +test du_combine_m_value_empty_and_a() { + combine_m_value(empty_m_value, m_value_a) == m_value_a +} diff --git a/validators/tests/deposit_utils/convert_m_value_to_usd.ak b/validators/tests/deposit_utils/convert_m_value_to_usd.ak new file mode 100644 index 0000000..999754c --- /dev/null +++ b/validators/tests/deposit_utils/convert_m_value_to_usd.ak @@ -0,0 +1,68 @@ +use cardano/assets.{AssetName, PolicyId} +use hydra_dex/price_oracle_utils.{convert_m_value_to_usd} +use hydra_dex/types.{MValue} + +const prices: Pairs<(PolicyId, AssetName), Int> = + [ + Pair((#"", #""), 2), + Pair( + (#"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", #"5553444d"), + 1, + ), + ] + +const empty_m_value: MValue = [] + +const m_value_a = + [ + Pair("", [Pair("", 100)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair(#"5553444d", 100)], + ), + ] + +const m_value_b = + [ + Pair("", [Pair("", 200)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair(#"5553444d", 200)], + ), + ] + +const m_value_c = + [ + Pair("", [Pair("", 300)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair("", 300), Pair(#"5553444d", 300)], + ), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c999", + [Pair(#"5553444d", 300)], + ), + ] + +// m_value_a: 100 * 2 (ADA) + 100 * 1 (USDM) = 300 +const m_value_a_in_usd = 300 + +// m_value_b: 200 * 2 (ADA) + 200 * 1 (USDM) = 600 +const m_value_b_in_usd = 600 + +test du_convert_m_value_to_usd_a() { + convert_m_value_to_usd(m_value_a, prices) == m_value_a_in_usd +} + +test du_convert_m_value_to_usd_b() { + convert_m_value_to_usd(m_value_b, prices) == m_value_b_in_usd +} + +test du_convert_m_value_to_usd_empty() { + convert_m_value_to_usd(empty_m_value, prices) == 0 +} + +// m_value_c has an asset with no price - should fail +test du_convert_m_value_to_usd_fail_no_price() fail { + convert_m_value_to_usd(m_value_c, prices) == 0 +} diff --git a/validators/tests/hydra_account/vault_deposit.ak b/validators/tests/hydra_account/vault_deposit.ak new file mode 100644 index 0000000..595598e --- /dev/null +++ b/validators/tests/hydra_account/vault_deposit.ak @@ -0,0 +1,375 @@ +use cardano/address.{Script, from_script} +use cardano/assets.{from_asset, merge, negate} +use cardano/transaction.{Transaction} +use hydra_account/core as ha +use hydra_dex/types.{ + Account, ProcessVaultDeposit, SharesInsert, UserTradeAccount, + VaultDepositIntentDatumL2, VaultOracleDatum, +} +use hydra_dex/utils.{to_mvalue} +use mocktail.{ + complete, mint, mock_policy_id, mock_tx_hash, mocktail_tx, ref_tx_in, + ref_tx_in_inline_datum, required_signer_hash, tx_in, tx_in_inline_datum, + tx_out, tx_out_inline_datum, +} +use tests/utils.{ + mock_account, mock_account_3, mock_dex_order_book_address, + mock_dex_order_book_datum, mock_dex_order_book_token, + mock_hydra_account_address, mock_hydra_lovelace, mock_operation_key, + mock_user_account, +} as test_utils + +// ========== Test Constants ========== + +const mock_vault_oracle_nft = mock_policy_id(500) + +const mock_l2_deposit_intent_script_hash = + #"1234567890abcdef1234567890abcdef1234567890abcdef12345678" + +// Mock vault account - uses intent script hash as master key +fn mock_vault_account() { + Account { + account_id: #"aabbccdd", + master_key: Script(mock_l2_deposit_intent_script_hash), + operation_key: Script(mock_l2_deposit_intent_script_hash), + } +} + +fn mock_vault_user_account() { + UserTradeAccount { + account: mock_vault_account(), + trading_logic: test_utils.mock_hydra_order_book, + } +} + +fn mock_vault_oracle_datum_input() -> VaultOracleDatum { + VaultOracleDatum { + app_oracle: mock_policy_id(0), + vault_script_hash: #"", + l1_deposit_intent_script_hash: #"", + l1_withdrawal_intent_script_hash: #"", + l2_deposit_intent_script_hash: mock_l2_deposit_intent_script_hash, + l2_withdrawal_intent_script_hash: #"", + pluggable_logic: #"", + vault_stake_rotation_script_hash: #"", + operator_key: mock_operation_key, + operator_account: mock_user_account(mock_account), + operator_charge_percentage: 10, + operator_min_deposit_percentage: 0, + hydra_node_pub_keys: [], + is_active: True, + total_shares: 1_000_000_000_000, + operator_shares: 0, + total_deposited: 1_000_000_000, + shares_merkle_root: #"", + total_fee_collected: 0, + } +} + +// ========== Test Case Type ========== + +type VaultDepositTestCase { + is_operation_key_signed: Bool, + is_depositor_balance_deducted: Bool, + is_vault_balance_increased: Bool, + is_intent_token_burnt: Bool, + has_other_account_input: Bool, + has_other_account_output: Bool, +} + +// ========== Mock Transaction Builder ========== + +fn mock_vault_deposit_tx(test_case: VaultDepositTestCase) -> Transaction { + let VaultDepositTestCase { + is_operation_key_signed, + is_depositor_balance_deducted, + is_vault_balance_increased, + is_intent_token_burnt, + has_other_account_input, + has_other_account_output, + } = test_case + + let deposit_amount = mock_hydra_lovelace(100_000_000) + let depositor_balance_start = mock_hydra_lovelace(1_000_000_000) + let vault_balance_start = mock_hydra_lovelace(5_000_000_000) + + let depositor_balance_end = + if is_depositor_balance_deducted { + deposit_amount |> negate() |> merge(depositor_balance_start) + } else { + depositor_balance_start + } + + let vault_balance_end = + if is_vault_balance_increased { + deposit_amount |> merge(vault_balance_start) + } else { + vault_balance_start + } + + let vault_oracle_address = from_script("vault_oracle") + + // Input oracle datum + let input_oracle_datum = mock_vault_oracle_datum_input() + + // Output oracle datum - updated with new shares + // TODO: Update shares calculation when price tests are added + let output_oracle_datum = + VaultOracleDatum { + ..input_oracle_datum, + total_shares: input_oracle_datum.total_shares + 100_000_000_000, + total_deposited: input_oracle_datum.total_deposited + 100_000_000, + shares_merkle_root: #"0000000000000000000000000000000000000000", + } + + let intent_address = from_script(mock_l2_deposit_intent_script_hash) + + mocktail_tx() + // Reference input: DexOrderBook + |> ref_tx_in( + True, + mock_tx_hash(1), + 0, + from_asset(mock_dex_order_book_token, "", 1), + mock_dex_order_book_address, + ) + |> ref_tx_in_inline_datum(True, mock_dex_order_book_datum) + // Intent input (to be burnt) + |> tx_in( + True, + mock_tx_hash(0), + 0, + from_asset(mock_l2_deposit_intent_script_hash, "", 1), + intent_address, + ) + |> tx_in_inline_datum( + True, + VaultDepositIntentDatumL2 { + vault_oracle_nft: mock_vault_oracle_nft, + depositor: mock_user_account(mock_account), + deposit_amount: deposit_amount |> to_mvalue(), + }, + ) + // Vault Oracle input + |> tx_in( + True, + mock_tx_hash(0), + 1, + from_asset(mock_vault_oracle_nft, "", 1), + vault_oracle_address, + ) + |> tx_in_inline_datum(True, input_oracle_datum) + // Vault Oracle output + |> tx_out( + True, + vault_oracle_address, + from_asset(mock_vault_oracle_nft, "", 1), + ) + |> tx_out_inline_datum(True, output_oracle_datum) + // Depositor input + |> tx_in( + True, + mock_tx_hash(0), + 2, + depositor_balance_start, + mock_hydra_account_address, + ) + |> tx_in_inline_datum(True, mock_user_account(mock_account)) + // Depositor output + |> tx_out(True, mock_hydra_account_address, depositor_balance_end) + |> tx_out_inline_datum(True, mock_user_account(mock_account)) + // Vault account input + |> tx_in( + True, + mock_tx_hash(0), + 3, + vault_balance_start, + mock_hydra_account_address, + ) + |> tx_in_inline_datum(True, mock_vault_user_account()) + // Vault account output + |> tx_out(True, mock_hydra_account_address, vault_balance_end) + |> tx_out_inline_datum(True, mock_vault_user_account()) + // Other account (for testing isolation) + |> tx_in( + has_other_account_input, + mock_tx_hash(0), + 4, + mock_hydra_lovelace(500_000_000), + mock_hydra_account_address, + ) + |> tx_in_inline_datum( + has_other_account_input, + mock_user_account(mock_account_3), + ) + |> tx_out( + has_other_account_output, + mock_hydra_account_address, + mock_hydra_lovelace(500_000_000), + ) + |> tx_out_inline_datum( + has_other_account_output, + mock_user_account(mock_account_3), + ) + // Mint (burn intent token) + |> mint(is_intent_token_burnt, -1, mock_l2_deposit_intent_script_hash, "") + // Required signer + |> required_signer_hash(is_operation_key_signed, mock_operation_key) + |> complete() +} + +// ========== Success Tests ========== + +// TODO: Add success test with proper merkle proof and price verification +// test s8_vd_success() { +// ... +// } + +// ========== Failure Tests ========== + +test s8_vd_failed_without_operation_key_signed() fail { + let test_case = + VaultDepositTestCase { + is_operation_key_signed: False, + is_depositor_balance_deducted: True, + is_vault_balance_increased: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + // TODO: Replace with actual function call when merkle/price tests added + // Currently tests validator structure only + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_failed_without_depositor_balance_deducted() fail { + let test_case = + VaultDepositTestCase { + is_operation_key_signed: True, + is_depositor_balance_deducted: False, + is_vault_balance_increased: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_failed_without_vault_balance_increased() fail { + let test_case = + VaultDepositTestCase { + is_operation_key_signed: True, + is_depositor_balance_deducted: True, + is_vault_balance_increased: False, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_failed_without_intent_token_burnt() fail { + let test_case = + VaultDepositTestCase { + is_operation_key_signed: True, + is_depositor_balance_deducted: True, + is_vault_balance_increased: True, + is_intent_token_burnt: False, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_failed_with_other_account_input() fail { + let test_case = + VaultDepositTestCase { + is_operation_key_signed: True, + is_depositor_balance_deducted: True, + is_vault_balance_increased: True, + is_intent_token_burnt: True, + has_other_account_input: True, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_failed_with_other_account_output() fail { + let test_case = + VaultDepositTestCase { + is_operation_key_signed: True, + is_depositor_balance_deducted: True, + is_vault_balance_increased: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: True, + } + + let tx = mock_vault_deposit_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + Script(""), + tx, + ) +} +// ========== TODO: Merkle Tests ========== +// test s8_vd_success_new_depositor_merkle_insert() { ... } +// test s8_vd_success_existing_depositor_merkle_update() { ... } +// test s8_vd_failed_invalid_merkle_root_transition() fail { ... } +// test s8_vd_failed_shares_mismatch_in_merkle() fail { ... } + +// ========== TODO: Price Verification Tests ========== +// test s8_vd_success_with_valid_price_signatures() { ... } +// test s8_vd_failed_invalid_price_signatures() fail { ... } +// test s8_vd_failed_mismatched_vault_equity() fail { ... } + +// ========== TODO: Shares Calculation Tests ========== +// test s8_vd_shares_calculation_correct() { ... } +// test s8_vd_shares_round_down() { ... } + +// ========== TODO: Oracle Datum Update Tests ========== +// test s8_vd_failed_total_shares_not_updated() fail { ... } +// test s8_vd_failed_total_deposited_not_updated() fail { ... } +// test s8_vd_failed_other_fields_changed() fail { ... } diff --git a/validators/tests/hydra_account/vault_withdrawal.ak b/validators/tests/hydra_account/vault_withdrawal.ak new file mode 100644 index 0000000..88ebbb8 --- /dev/null +++ b/validators/tests/hydra_account/vault_withdrawal.ak @@ -0,0 +1,457 @@ +use cardano/address.{Script, VerificationKey, from_script} +use cardano/assets.{from_asset, merge, negate} +use cardano/transaction.{Transaction} +use hydra_account/core as ha +use hydra_dex/types.{ + Account, ProcessVaultWithdrawal, SharesDelete, SharesInsert, UserTradeAccount, + VaultOracleDatum, VaultWithdrawalIntentDatumL2, +} +use mocktail.{ + complete, mint, mock_policy_id, mock_pub_key_hash, mock_tx_hash, mocktail_tx, + ref_tx_in, ref_tx_in_inline_datum, required_signer_hash, tx_in, + tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use tests/utils.{ + mock_account, mock_account_3, mock_dex_order_book_address, + mock_dex_order_book_datum, mock_dex_order_book_token, + mock_hydra_account_address, mock_hydra_lovelace, mock_operation_key, + mock_user_account, +} as test_utils + +// ========== Test Constants ========== + +const mock_vault_oracle_nft = mock_policy_id(500) + +const mock_l2_withdrawal_intent_script_hash = + #"abcdef1234567890abcdef1234567890abcdef1234567890abcdef12" + +const mock_operator_key = mock_pub_key_hash(999) + +// Mock vault account - uses intent script hash as master key +fn mock_vault_account() { + Account { + account_id: #"aabbccdd", + master_key: Script(mock_l2_withdrawal_intent_script_hash), + operation_key: Script(mock_l2_withdrawal_intent_script_hash), + } +} + +fn mock_vault_user_account() { + UserTradeAccount { + account: mock_vault_account(), + trading_logic: test_utils.mock_hydra_order_book, + } +} + +fn mock_operator_account() { + Account { + account_id: #"eeeeeeee", + master_key: VerificationKey(mock_operator_key), + operation_key: VerificationKey(mock_operator_key), + } +} + +fn mock_operator_user_account() { + UserTradeAccount { + account: mock_operator_account(), + trading_logic: test_utils.mock_hydra_order_book, + } +} + +fn mock_vault_oracle_datum_input() -> VaultOracleDatum { + VaultOracleDatum { + app_oracle: mock_policy_id(0), + vault_script_hash: #"", + l1_deposit_intent_script_hash: #"", + l1_withdrawal_intent_script_hash: #"", + l2_deposit_intent_script_hash: #"", + l2_withdrawal_intent_script_hash: mock_l2_withdrawal_intent_script_hash, + pluggable_logic: #"", + vault_stake_rotation_script_hash: #"", + operator_key: mock_operator_key, + operator_account: mock_operator_user_account(), + operator_charge_percentage: 10, + operator_min_deposit_percentage: 0, + hydra_node_pub_keys: [], + is_active: True, + total_shares: 1_000_000_000_000, + operator_shares: 0, + total_deposited: 1_000_000_000, + shares_merkle_root: #"", + total_fee_collected: 0, + } +} + +// ========== Test Case Type ========== + +type VaultWithdrawalTestCase { + is_operation_key_signed: Bool, + is_operator_key_signed: Bool, + is_withdrawer_balance_increased: Bool, + is_vault_balance_deducted: Bool, + is_intent_token_burnt: Bool, + has_other_account_input: Bool, + has_other_account_output: Bool, +} + +// ========== Mock Transaction Builder ========== + +fn mock_vault_withdrawal_tx(test_case: VaultWithdrawalTestCase) -> Transaction { + let VaultWithdrawalTestCase { + is_operation_key_signed, + is_operator_key_signed, + is_withdrawer_balance_increased, + is_vault_balance_deducted, + is_intent_token_burnt, + has_other_account_input, + has_other_account_output, + } = test_case + + // Withdrawal: user receives value from vault + let withdrawal_value = mock_hydra_lovelace(100_000_000) + let withdrawer_balance_start = mock_hydra_lovelace(500_000_000) + let vault_balance_start = mock_hydra_lovelace(5_000_000_000) + + let withdrawer_balance_end = + if is_withdrawer_balance_increased { + withdrawal_value |> merge(withdrawer_balance_start) + } else { + withdrawer_balance_start + } + + let vault_balance_end = + if is_vault_balance_deducted { + withdrawal_value |> negate() |> merge(vault_balance_start) + } else { + vault_balance_start + } + + let vault_oracle_address = from_script("vault_oracle") + + // Input oracle datum + let input_oracle_datum = mock_vault_oracle_datum_input() + + // Output oracle datum - updated after withdrawal + // TODO: Update shares calculation when price/fee tests are added + let shares_to_redeem = 100_000_000_000 + let output_oracle_datum = + VaultOracleDatum { + ..input_oracle_datum, + total_shares: input_oracle_datum.total_shares - shares_to_redeem, + total_deposited: input_oracle_datum.total_deposited - 100_000_000, + shares_merkle_root: #"0000000000000000000000000000000000000000", + } + + let intent_address = from_script(mock_l2_withdrawal_intent_script_hash) + + mocktail_tx() + // Reference input: DexOrderBook + |> ref_tx_in( + True, + mock_tx_hash(1), + 0, + from_asset(mock_dex_order_book_token, "", 1), + mock_dex_order_book_address, + ) + |> ref_tx_in_inline_datum(True, mock_dex_order_book_datum) + // Intent input (to be burnt) + |> tx_in( + True, + mock_tx_hash(0), + 0, + from_asset(mock_l2_withdrawal_intent_script_hash, "", 1), + intent_address, + ) + |> tx_in_inline_datum( + True, + VaultWithdrawalIntentDatumL2 { + vault_oracle_nft: mock_vault_oracle_nft, + withdrawer: mock_user_account(mock_account), + shares_to_redeem, + }, + ) + // Vault Oracle input + |> tx_in( + True, + mock_tx_hash(0), + 1, + from_asset(mock_vault_oracle_nft, "", 1), + vault_oracle_address, + ) + |> tx_in_inline_datum(True, input_oracle_datum) + // Vault Oracle output + |> tx_out( + True, + vault_oracle_address, + from_asset(mock_vault_oracle_nft, "", 1), + ) + |> tx_out_inline_datum(True, output_oracle_datum) + // Withdrawer input + |> tx_in( + True, + mock_tx_hash(0), + 2, + withdrawer_balance_start, + mock_hydra_account_address, + ) + |> tx_in_inline_datum(True, mock_user_account(mock_account)) + // Withdrawer output + |> tx_out(True, mock_hydra_account_address, withdrawer_balance_end) + |> tx_out_inline_datum(True, mock_user_account(mock_account)) + // Vault account input + |> tx_in( + True, + mock_tx_hash(0), + 3, + vault_balance_start, + mock_hydra_account_address, + ) + |> tx_in_inline_datum(True, mock_vault_user_account()) + // Vault account output + |> tx_out(True, mock_hydra_account_address, vault_balance_end) + |> tx_out_inline_datum(True, mock_vault_user_account()) + // Other account (for testing isolation) + |> tx_in( + has_other_account_input, + mock_tx_hash(0), + 4, + mock_hydra_lovelace(500_000_000), + mock_hydra_account_address, + ) + |> tx_in_inline_datum( + has_other_account_input, + mock_user_account(mock_account_3), + ) + |> tx_out( + has_other_account_output, + mock_hydra_account_address, + mock_hydra_lovelace(500_000_000), + ) + |> tx_out_inline_datum( + has_other_account_output, + mock_user_account(mock_account_3), + ) + // Mint (burn intent token) + |> mint( + is_intent_token_burnt, + -1, + mock_l2_withdrawal_intent_script_hash, + "", + ) + // Required signers (operation_key OR operator_key) + |> required_signer_hash(is_operation_key_signed, mock_operation_key) + |> required_signer_hash(is_operator_key_signed, mock_operator_key) + |> complete() +} + +// ========== Success Tests ========== + +// TODO: Add success test with proper merkle proof and price verification +// test s8_vw_success_operation_key() { +// ... +// } + +// TODO: Test operator_key as alternative signer +// test s8_vw_success_operator_key() { +// ... +// } + +// ========== Failure Tests ========== + +test s8_vw_failed_without_any_signature() fail { + let test_case = + VaultWithdrawalTestCase { + is_operation_key_signed: False, + is_operator_key_signed: False, + is_withdrawer_balance_increased: True, + is_vault_balance_deducted: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_withdrawal_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} + +test s8_vw_failed_without_withdrawer_balance_increased() fail { + let test_case = + VaultWithdrawalTestCase { + is_operation_key_signed: True, + is_operator_key_signed: False, + is_withdrawer_balance_increased: False, + is_vault_balance_deducted: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_withdrawal_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} + +test s8_vw_failed_without_vault_balance_deducted() fail { + let test_case = + VaultWithdrawalTestCase { + is_operation_key_signed: True, + is_operator_key_signed: False, + is_withdrawer_balance_increased: True, + is_vault_balance_deducted: False, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_withdrawal_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} + +test s8_vw_failed_without_intent_token_burnt() fail { + let test_case = + VaultWithdrawalTestCase { + is_operation_key_signed: True, + is_operator_key_signed: False, + is_withdrawer_balance_increased: True, + is_vault_balance_deducted: True, + is_intent_token_burnt: False, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_withdrawal_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} + +test s8_vw_failed_with_other_account_input() fail { + let test_case = + VaultWithdrawalTestCase { + is_operation_key_signed: True, + is_operator_key_signed: False, + is_withdrawer_balance_increased: True, + is_vault_balance_deducted: True, + is_intent_token_burnt: True, + has_other_account_input: True, + has_other_account_output: False, + } + + let tx = mock_vault_withdrawal_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} + +test s8_vw_failed_with_other_account_output() fail { + let test_case = + VaultWithdrawalTestCase { + is_operation_key_signed: True, + is_operator_key_signed: False, + is_withdrawer_balance_increased: True, + is_vault_balance_deducted: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: True, + } + + let tx = mock_vault_withdrawal_tx(test_case) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} +// ========== TODO: Signature Tests ========== +// test s8_vw_success_with_operation_key_only() { ... } +// test s8_vw_success_with_operator_key_only() { ... } + +// ========== TODO: Merkle Tests ========== +// test s8_vw_success_full_withdrawal_merkle_delete() { ... } +// test s8_vw_success_partial_withdrawal_merkle_update() { ... } +// test s8_vw_failed_invalid_merkle_root_transition() fail { ... } +// test s8_vw_failed_shares_mismatch_in_merkle() fail { ... } +// test s8_vw_failed_partial_withdrawal_exceeds_shares() fail { ... } + +// ========== TODO: Price Verification Tests ========== +// test s8_vw_success_with_valid_price_signatures() { ... } +// test s8_vw_failed_invalid_price_signatures() fail { ... } + +// ========== TODO: Fee Calculation Tests ========== +// test s8_vw_fee_calculated_when_profit() { ... } +// test s8_vw_no_fee_when_no_profit() { ... } +// test s8_vw_fee_rounds_up() { ... } +// test s8_vw_fee_shares_rounds_up() { ... } + +// ========== TODO: Operator Fee Share Tests ========== +// test s8_vw_operator_fee_share_insert() { ... } +// test s8_vw_operator_fee_share_update() { ... } +// test s8_vw_no_operator_fee_when_no_profit() { ... } + +// ========== TODO: Oracle Datum Update Tests ========== +// test s8_vw_failed_total_shares_not_updated() fail { ... } +// test s8_vw_failed_operator_shares_not_updated() fail { ... } +// test s8_vw_failed_total_deposited_not_updated() fail { ... } +// test s8_vw_failed_total_fee_collected_not_updated() fail { ... } +// test s8_vw_failed_other_fields_changed() fail { ... } + +// ========== TODO: Value Transfer Tests ========== +// test s8_vw_value_transfer_matches_gross_minus_fee() { ... } +// test s8_vw_failed_value_mismatch() fail { ... } diff --git a/validators/tests/withdraw_utils/cal_per_user_operator_fee.ak b/validators/tests/withdraw_utils/cal_per_user_operator_fee.ak new file mode 100644 index 0000000..0e5445d --- /dev/null +++ b/validators/tests/withdraw_utils/cal_per_user_operator_fee.ak @@ -0,0 +1,61 @@ +use hydra_dex/withdraw_utils.{cal_per_user_operator_fee} + +// ========== cal_per_user_operator_fee tests ========== +// Formula: if profit > 0, fee = ceil(profit * operator_charge_percentage / 100) +// profit = withdrawal_value - cost_basis + +// Basic profit case: withdrawal=1000, cost=800, charge=10% → profit=200, fee=20 +test wu_cal_per_user_operator_fee_basic_profit() { + cal_per_user_operator_fee(1000, 800, 10) == 20 +} + +// No profit (break even): withdrawal=1000, cost=1000 → profit=0, fee=0 +test wu_cal_per_user_operator_fee_no_profit() { + cal_per_user_operator_fee(1000, 1000, 10) == 0 +} + +// Loss case: withdrawal=800, cost=1000 → profit=-200, fee=0 +test wu_cal_per_user_operator_fee_loss() { + cal_per_user_operator_fee(800, 1000, 10) == 0 +} + +// Round up: withdrawal=1003, cost=1000, charge=10% → profit=3, fee=ceil(0.3)=1 +test wu_cal_per_user_operator_fee_round_up() { + cal_per_user_operator_fee(1003, 1000, 10) == 1 +} + +// Exact division: withdrawal=1100, cost=1000, charge=10% → profit=100, fee=10 +test wu_cal_per_user_operator_fee_exact() { + cal_per_user_operator_fee(1100, 1000, 10) == 10 +} + +// Higher charge percentage: 20% +test wu_cal_per_user_operator_fee_higher_percentage() { + cal_per_user_operator_fee(1000, 800, 20) == 40 +} + +// Zero charge percentage: fee always 0 +test wu_cal_per_user_operator_fee_zero_percentage() { + cal_per_user_operator_fee(1000, 500, 0) == 0 +} + +// 100% charge: all profit goes to operator +test wu_cal_per_user_operator_fee_full_charge() { + cal_per_user_operator_fee(1000, 800, 100) == 200 +} + +// Real-world example: +// withdrawal_value = 1000000 (1 USD with 6 decimals) +// cost_basis = 800000 (0.8 USD) +// charge = 10% +// profit = 200000, fee = ceil(200000 * 10 / 100) = 20000 +test wu_cal_per_user_operator_fee_real_world() { + cal_per_user_operator_fee(1000000, 800000, 10) == 20000 +} + +// Large profit with rounding: +// withdrawal = 1234567, cost = 1000000, charge = 15% +// profit = 234567, fee = ceil(234567 * 15 / 100) = ceil(35185.05) = 35186 +test wu_cal_per_user_operator_fee_large_profit_round_up() { + cal_per_user_operator_fee(1234567, 1000000, 15) == 35186 +} diff --git a/validators/tests/withdraw_utils/check_output_value.ak b/validators/tests/withdraw_utils/check_output_value.ak new file mode 100644 index 0000000..a56ed8c --- /dev/null +++ b/validators/tests/withdraw_utils/check_output_value.ak @@ -0,0 +1,87 @@ +use cardano/assets.{AssetName, PolicyId, add, from_asset} +use hydra_dex/withdraw_utils.{check_output_value_equal_to_shares_usd_value} + +const usdm_policy = #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913" + +const usdm_name = #"5553444d" + +const prices: Pairs<(PolicyId, AssetName), Int> = + [Pair((#"", #""), 2), Pair((usdm_policy, usdm_name), 1)] + +// ========== check_output_value_equal_to_shares_usd_value tests ========== + +// Output value: 1000000 USDM (price=1) + 2000000 ADA (price=2) +// USD value = 1000000 * 1 + 2000000 * 2 = 5000000 +const output_value_a = + from_asset(usdm_policy, usdm_name, 1000000) + |> add(#"", #"", 2000000) + +const shares_usd_value_a = 5000000 + +test wu_check_output_value_mixed_a() { + check_output_value_equal_to_shares_usd_value( + output_value_a, + shares_usd_value_a, + prices, + ) +} + +// Output value: 2000000 USDM (price=1) + 1000000 ADA (price=2) +// USD value = 2000000 * 1 + 1000000 * 2 = 4000000 +const output_value_b = + from_asset(usdm_policy, usdm_name, 2000000) + |> add(#"", #"", 1000000) + +const shares_usd_value_b = 4000000 + +test wu_check_output_value_mixed_b() { + check_output_value_equal_to_shares_usd_value( + output_value_b, + shares_usd_value_b, + prices, + ) +} + +// Wrong USD value should return false +test wu_check_output_value_wrong() { + !check_output_value_equal_to_shares_usd_value(output_value_a, 4000000, prices) +} + +// Output with asset that has no price should fail +const output_value_no_price = + from_asset( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c999", + #"", + 1000000, + ) + |> add(usdm_policy, usdm_name, 2000000) + +test wu_check_output_value_fail_no_price() fail { + check_output_value_equal_to_shares_usd_value( + output_value_no_price, + 4000000, + prices, + ) +} + +// Pure USDM output +const output_value_usdm_only = from_asset(usdm_policy, usdm_name, 3000000) + +test wu_check_output_value_usdm_only() { + check_output_value_equal_to_shares_usd_value( + output_value_usdm_only, + 3000000, + prices, + ) +} + +// Pure ADA output +const output_value_ada_only = from_asset(#"", #"", 1500000) + +test wu_check_output_value_ada_only() { + check_output_value_equal_to_shares_usd_value( + output_value_ada_only, + 3000000, + prices, + ) +} diff --git a/validators/tests/withdraw_utils/compute_fee_shares.ak b/validators/tests/withdraw_utils/compute_fee_shares.ak new file mode 100644 index 0000000..27063d0 --- /dev/null +++ b/validators/tests/withdraw_utils/compute_fee_shares.ak @@ -0,0 +1,50 @@ +use hydra_dex/withdraw_utils.{compute_fee_shares} + +// ========== compute_fee_shares tests ========== +// Formula: fee_shares = ceil(fee * total_shares / vault_equity) + +// Basic case: fee=100, total_shares=1000, vault_equity=1000 → 100 shares +test wu_compute_fee_shares_basic() { + compute_fee_shares(100, 1000, 1000) == 100 +} + +// Round up: fee=100, total_shares=1000, vault_equity=300 → ceil(333.33) = 334 +test wu_compute_fee_shares_round_up() { + compute_fee_shares(100, 1000, 300) == 334 +} + +// Exact division: fee=300, total_shares=1000, vault_equity=1000 → 300 +test wu_compute_fee_shares_exact() { + compute_fee_shares(300, 1000, 1000) == 300 +} + +// Zero fee: fee=0 → 0 shares +test wu_compute_fee_shares_zero_fee() { + compute_fee_shares(0, 1000, 1000) == 0 +} + +// Large total_shares: fee=100, total_shares=1000000, vault_equity=1000 → 100000 +test wu_compute_fee_shares_large_total() { + compute_fee_shares(100, 1000000, 1000) == 100000 +} + +// Small vault equity: fee=10, total_shares=1000, vault_equity=100 → 100 +test wu_compute_fee_shares_small_equity() { + compute_fee_shares(10, 1000, 100) == 100 +} + +// Real-world example: +// fee = 20000 (0.02 USD with 6 decimals) +// total_shares = 3000000000000000 +// vault_equity = 2400000000 +// fee_shares = ceil(20000 * 3000000000000000 / 2400000000) = ceil(25000000000) = 25000000000 +test wu_compute_fee_shares_real_world() { + compute_fee_shares(20000, 3000000000000000, 2400000000) == 25000000000 +} + +// Small fee with rounding: +// fee = 1, total_shares = 1000, vault_equity = 3 +// fee_shares = ceil(1 * 1000 / 3) = ceil(333.33) = 334 +test wu_compute_fee_shares_small_round_up() { + compute_fee_shares(1, 1000, 3) == 334 +} diff --git a/validators/tests/withdraw_utils/convert_shares_to_usd.ak b/validators/tests/withdraw_utils/convert_shares_to_usd.ak new file mode 100644 index 0000000..ae1725a --- /dev/null +++ b/validators/tests/withdraw_utils/convert_shares_to_usd.ak @@ -0,0 +1,48 @@ +use hydra_dex/withdraw_utils.{convert_shares_to_usd} + +// ========== convert_shares_to_usd tests ========== +// Formula: usd_value = shares_amount * vault_equity / total_shares + +// Basic calculation: 1000 shares with vault_equity=2000, total_shares=1000 → 2000 USD +test wu_convert_shares_to_usd_basic() { + convert_shares_to_usd(1000, 1000, 2000) == 2000 +} + +// Equal values: 1000 shares with vault_equity=1000, total_shares=1000 → 1000 USD +test wu_convert_shares_to_usd_equal() { + convert_shares_to_usd(1000, 1000, 1000) == 1000 +} + +// Larger vault: 1000 shares with vault_equity=10000, total_shares=1000 → 10000 USD +test wu_convert_shares_to_usd_larger_vault() { + convert_shares_to_usd(1000, 1000, 10000) == 10000 +} + +// More total shares: 1000 shares with vault_equity=1000, total_shares=10000 → 100 USD +test wu_convert_shares_to_usd_more_total_shares() { + convert_shares_to_usd(1000, 10000, 1000) == 100 +} + +// Round down: 100 shares with total_shares=300, vault_equity=100 → 33 USD (100*100/300) +test wu_convert_shares_to_usd_round_down() { + convert_shares_to_usd(100, 300, 100) == 33 +} + +// Zero shares: 0 shares → 0 USD +test wu_convert_shares_to_usd_zero() { + convert_shares_to_usd(0, 1000, 1000) == 0 +} + +// Real-world example using mock values: +// vault_equity = 2400000000 (2400 USD with 6 decimals) +// total_shares = 3000000000000000 +// shares_amount = 1250000000000000 (half of total) +// expected = 1250000000000000 * 2400000000 / 3000000000000000 = 1000000000 +test wu_convert_shares_to_usd_real_world() { + convert_shares_to_usd(1250000000000000, 3000000000000000, 2400000000) == 1000000000 +} + +// Partial withdrawal: 25% of shares +test wu_convert_shares_to_usd_partial() { + convert_shares_to_usd(750000000000000, 3000000000000000, 2400000000) == 600000000 +} From 93b3a56cc06d2193add14592bfe3bf234544904e Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 18 Mar 2026 14:30:44 +0800 Subject: [PATCH 07/30] fix: handle l2 unit --- lib/hydra_dex/types.ak | 3 ++- spec/8_hydra_account/w_transferal.md | 8 +++++- spec/8_hydra_account/w_vault_deposit.md | 21 +++++++++++++++- spec/8_hydra_account/w_vault_withdrawal.md | 24 ++++++++++++++++-- validators/hydra_account/core.ak | 5 +++- validators/hydra_account/vault_deposit.ak | 25 ++++++++++++++----- validators/hydra_account/vault_withdrawal.ak | 25 +++++++++++++++---- .../tests/hydra_account/vault_deposit.ak | 20 +++++++++------ .../tests/hydra_account/vault_withdrawal.ak | 16 ++++++++++-- 9 files changed, 121 insertions(+), 26 deletions(-) diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index 7b72736..3e81864 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -249,10 +249,11 @@ pub type HydraAccountOperation { ProcessSplitUtxosAtOpen { tree_or_proofs_with_token_map: TreeOrProofsWithTokenMap, } - ProcessVaultDeposit(ByteArray, List, SharesMPFAction) + ProcessVaultDeposit(ByteArray, List, TokenMap, SharesMPFAction) ProcessVaultWithdrawal( ByteArray, List, + TokenMap, SharesMPFAction, SharesMPFAction, ) diff --git a/spec/8_hydra_account/w_transferal.md b/spec/8_hydra_account/w_transferal.md index aff941c..8e3f5d8 100644 --- a/spec/8_hydra_account/w_transferal.md +++ b/spec/8_hydra_account/w_transferal.md @@ -14,9 +14,15 @@ - `AO_to` - Account Outputs with `to` account at intent - Other outputs - No other inputs/outputs at `hydra_account_script_hash` (only `from` and `to` account UTxOs allowed) -- The 3 value are equal: +- The 3 value are equal (all in L2 format): 1. Deduct in value for `from` (`AI_from` - `AO_from`) 2. Increase in value for `to` (`AO_to` - `AI_to`) 3. Value in transferal intent - The intent token is burnt - Signed by `operating_key` + +## L2 Asset Units + +- **Intent datum** contains `transfer_amount` in **L2 format**: `(hydra_token_policy_id, hashed_asset_name, qty)` +- **Account UTxOs** contain values in **L2 format**: `(hydra_token_policy_id, hash_token(policy_id, asset_name), qty)` +- All comparisons are done directly in L2 format (no conversion needed) diff --git a/spec/8_hydra_account/w_vault_deposit.md b/spec/8_hydra_account/w_vault_deposit.md index 52b0dfb..b38f300 100644 --- a/spec/8_hydra_account/w_vault_deposit.md +++ b/spec/8_hydra_account/w_vault_deposit.md @@ -19,7 +19,7 @@ - `VO` - Vault Outputs (by `master_key == Script(l2_deposit_intent_script_hash)`) - Other outputs - No other inputs/outputs at `hydra_account_script_hash` -- The 3 values are equal: +- The 3 values are equal (all in L2 format): 1. Deduct in value for depositor (`DI` - `DO`) without lovelace 2. Increase in value for vault (`VO` - `VI`) without lovelace 3. Value in deposit intent (`deposit_amount`) @@ -32,3 +32,22 @@ - `shares_merkle_root = computed_new_root` - The intent token is burnt - Signed by `operation_key` + +## L2 Asset Units + +- **Intent datum** contains `deposit_amount` in **L2 format**: `MValue = Pairs>` +- **Account UTxOs** contain values in **L2 format**: `(hydra_token_policy_id, hash_token(policy_id, asset_name), qty)` +- **Price message** contains prices in **L1 format**: `Pairs<(PolicyId, AssetName), Int>` +- **Token map** (`TokenMap`) maps L2 asset hash → L1 asset identity for price lookup +- Validator converts L2 deposit amount to L1 using `from_hydra_balance_to_value(l2_value, hydra_token_policy_id, token_map)` for USD calculation + +## Redeemer + +``` +ProcessVaultDeposit( + prices_message: ByteArray, + signatures: List, + token_map: TokenMap, + mpf_action: SharesMPFAction, +) +``` diff --git a/spec/8_hydra_account/w_vault_withdrawal.md b/spec/8_hydra_account/w_vault_withdrawal.md index 00f6291..636af46 100644 --- a/spec/8_hydra_account/w_vault_withdrawal.md +++ b/spec/8_hydra_account/w_vault_withdrawal.md @@ -25,8 +25,9 @@ - Other outputs - No other inputs/outputs at `hydra_account_script_hash` - Value transfer validated (in USD): - - Vault deducted == `user_receives` - - Withdrawer added == `user_receives` + - Convert L2 UTxO values to L1 using `token_map` for price lookup + - Vault deducted (L2 → L1 → USD) == `user_receives` + - Withdrawer added (L2 → L1 → USD) == `user_receives` - Verify User Merkle transition (SharesUpdate or SharesDelete) - Key: `cbor.serialise(withdrawer)` (UserAccount) - SharesDelete: full withdrawal, `shares_to_redeem == old_entry.shares` @@ -42,3 +43,22 @@ - `shares_merkle_root = final_root` - The intent token is burnt - Signed by `operation_key` OR `operator_key` + +## L1 vs L2 Asset Units + +- **Price message** contains prices in **L1 format**: `Pairs<(PolicyId, AssetName), Int>` +- **Account UTxOs** contain values in **L2 format**: `(hydra_token_policy_id, hash_token(policy_id, asset_name), qty)` +- **Token map** (`TokenMap = Pairs`) maps L2 asset hash → L1 asset identity +- Validator converts L2 UTxO values to L1 using `from_hydra_balance_to_value(l2_value, hydra_token_policy_id, token_map)` before price lookup + +## Redeemer + +``` +ProcessVaultWithdrawal( + prices_message: ByteArray, + signatures: List, + token_map: TokenMap, + mpf_action: SharesMPFAction, + operator_mpf_action: SharesMPFAction, +) +``` diff --git a/validators/hydra_account/core.ak b/validators/hydra_account/core.ak index ba279fd..f408c4d 100644 --- a/validators/hydra_account/core.ak +++ b/validators/hydra_account/core.ak @@ -103,17 +103,19 @@ validator hydra_account(dex_oracle_nft: PolicyId) { tree_or_proofs_with_token_map combine_utxos_at_close(dex_oracle_nft, proof, token_map, tx) } - ProcessVaultDeposit(prices_message, signatures, mpf_action) -> + ProcessVaultDeposit(prices_message, signatures, token_map, mpf_action) -> vault_deposit( dex_oracle_nft, prices_message, signatures, + token_map, mpf_action, tx, ) ProcessVaultWithdrawal( prices_message, signatures, + token_map, mpf_action, operator_mpf_action, ) -> @@ -121,6 +123,7 @@ validator hydra_account(dex_oracle_nft: PolicyId) { dex_oracle_nft, prices_message, signatures, + token_map, mpf_action, operator_mpf_action, tx, diff --git a/validators/hydra_account/vault_deposit.ak b/validators/hydra_account/vault_deposit.ak index 9fe8b4c..4a15916 100644 --- a/validators/hydra_account/vault_deposit.ak +++ b/validators/hydra_account/vault_deposit.ak @@ -13,14 +13,15 @@ use cocktail.{ use hydra_dex/account_utils.{ create_account_inputs_filter, create_account_outputs_filter, create_master_key_inputs_filter, create_master_key_outputs_filter, + from_hydra_balance_to_value, } use hydra_dex/deposit_utils.{cal_shares_amount} use hydra_dex/price_oracle_utils.{ - convert_m_value_to_usd, verify_prices_oracle_messages, + convert_value_to_usd, verify_prices_oracle_messages, } use hydra_dex/types.{ DexOrderBookDatum, SharesInsert, SharesMPFAction, SharesRecordEntry, - SharesUpdate, VaultDepositIntentDatumL2, VaultOracleDatum, + SharesUpdate, TokenMap, VaultDepositIntentDatumL2, VaultOracleDatum, } use hydra_dex/utils.{get_burning_intent_policy, get_dex_order_book_datum} @@ -28,6 +29,7 @@ pub fn vault_deposit( dex_oracle_nft: PolicyId, prices_message: ByteArray, signatures: List, + token_map: TokenMap, mpf_action: SharesMPFAction, tx: Transaction, ) -> Bool { @@ -41,8 +43,12 @@ pub fn vault_deposit( } = tx // 1. Get DexOrderBook datum (reference input with `dex_oracle_nft`) - let DexOrderBookDatum { operation_key, hydra_account_script_hash, .. }: DexOrderBookDatum = - reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) + let DexOrderBookDatum { + operation_key, + hydra_account_script_hash, + hydra_token_policy_id, + .. + }: DexOrderBookDatum = reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) // 2. Get L2 Deposit Intent from burn event (implicitly verifies burn) let mint_list = mint |> flatten() @@ -89,7 +95,11 @@ pub fn vault_deposit( ) // 6. Calculate shares and USD value (Division Order: multiply first!) - let deposit_usd_value = convert_m_value_to_usd(deposit_amount, prices) + // Convert L2 deposit amount to L1 for price lookup (prices are L1-keyed) + let deposit_amount_l1 = + from_asset_list(deposit_amount) + |> from_hydra_balance_to_value(hydra_token_policy_id, token_map) + let deposit_usd_value = convert_value_to_usd(deposit_amount_l1, prices) // Round DOWN (integer division) - protects vault let shares_minted = cal_shares_amount(deposit_usd_value, vault_equity, input_total_shares) @@ -130,7 +140,10 @@ pub fn vault_deposit( outputs_value(vault_outputs) |> merge(negate(inputs_value(vault_inputs))) |> without_lovelace() - let intent_amount = from_asset_list(deposit_amount) + // deposit_amount is already in L2 format (consistent with UTxO values) + let intent_amount = + from_asset_list(deposit_amount) + |> without_lovelace() let is_value_transfer_correct = deducted_amount == added_amount && added_amount == intent_amount diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak index 2e69a91..5b7b27c 100644 --- a/validators/hydra_account/vault_withdrawal.ak +++ b/validators/hydra_account/vault_withdrawal.ak @@ -11,13 +11,14 @@ use cocktail.{ use hydra_dex/account_utils.{ create_account_inputs_filter, create_account_outputs_filter, create_master_key_inputs_filter, create_master_key_outputs_filter, + from_hydra_balance_to_value, } use hydra_dex/price_oracle_utils.{ convert_value_to_usd, verify_prices_oracle_messages, } use hydra_dex/types.{ DexOrderBookDatum, SharesDelete, SharesMPFAction, SharesRecordEntry, - SharesUpdate, VaultOracleDatum, VaultWithdrawalIntentDatumL2, + SharesUpdate, TokenMap, VaultOracleDatum, VaultWithdrawalIntentDatumL2, } use hydra_dex/utils.{get_burning_intent_policy, get_dex_order_book_datum} use hydra_dex/withdraw_utils.{ @@ -29,6 +30,7 @@ pub fn vault_withdrawal( dex_oracle_nft: PolicyId, prices_message: ByteArray, signatures: List, + token_map: TokenMap, mpf_action: SharesMPFAction, operator_mpf_action: SharesMPFAction, tx: Transaction, @@ -43,8 +45,12 @@ pub fn vault_withdrawal( } = tx // 1. Get DexOrderBook datum (reference input with `dex_oracle_nft`) - let DexOrderBookDatum { operation_key, hydra_account_script_hash, .. }: DexOrderBookDatum = - reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) + let DexOrderBookDatum { + operation_key, + hydra_account_script_hash, + hydra_token_policy_id, + .. + }: DexOrderBookDatum = reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) // 2. Get L2 Withdrawal Intent from burn event (implicitly verifies burn) let mint_list = mint |> flatten() @@ -178,9 +184,12 @@ pub fn vault_withdrawal( // 8. Validate value transfer // Vault loses user_receives (in USD value) + // Convert L2 values to L1 for price lookup (prices are L1-keyed) let vault_deducted = merge(inputs_value(vault_inputs), negate(outputs_value(vault_outputs))) - let vault_deducted_usd = convert_value_to_usd(vault_deducted, prices) + let vault_deducted_l1 = + from_hydra_balance_to_value(vault_deducted, hydra_token_policy_id, token_map) + let vault_deducted_usd = convert_value_to_usd(vault_deducted_l1, prices) // Withdrawer gains user_receives (in USD value) let withdrawer_added = @@ -188,7 +197,13 @@ pub fn vault_withdrawal( outputs_value(withdrawer_outputs), negate(inputs_value(withdrawer_inputs)), ) - let withdrawer_added_usd = convert_value_to_usd(withdrawer_added, prices) + let withdrawer_added_l1 = + from_hydra_balance_to_value( + withdrawer_added, + hydra_token_policy_id, + token_map, + ) + let withdrawer_added_usd = convert_value_to_usd(withdrawer_added_l1, prices) let is_value_transfer_correct = vault_deducted_usd == user_receives && withdrawer_added_usd == user_receives diff --git a/validators/tests/hydra_account/vault_deposit.ak b/validators/tests/hydra_account/vault_deposit.ak index 595598e..ca101a0 100644 --- a/validators/tests/hydra_account/vault_deposit.ak +++ b/validators/tests/hydra_account/vault_deposit.ak @@ -3,7 +3,7 @@ use cardano/assets.{from_asset, merge, negate} use cardano/transaction.{Transaction} use hydra_account/core as ha use hydra_dex/types.{ - Account, ProcessVaultDeposit, SharesInsert, UserTradeAccount, + Account, ProcessVaultDeposit, SharesInsert, TokenMap, UserTradeAccount, VaultDepositIntentDatumL2, VaultOracleDatum, } use hydra_dex/utils.{to_mvalue} @@ -242,9 +242,10 @@ test s8_vd_failed_without_operation_key_signed() fail { // TODO: Replace with actual function call when merkle/price tests added // Currently tests validator structure only + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, - ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), Script(""), tx, ) @@ -263,9 +264,10 @@ test s8_vd_failed_without_depositor_balance_deducted() fail { let tx = mock_vault_deposit_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, - ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), Script(""), tx, ) @@ -284,9 +286,10 @@ test s8_vd_failed_without_vault_balance_increased() fail { let tx = mock_vault_deposit_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, - ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), Script(""), tx, ) @@ -305,9 +308,10 @@ test s8_vd_failed_without_intent_token_burnt() fail { let tx = mock_vault_deposit_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, - ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), Script(""), tx, ) @@ -326,9 +330,10 @@ test s8_vd_failed_with_other_account_input() fail { let tx = mock_vault_deposit_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, - ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), Script(""), tx, ) @@ -347,9 +352,10 @@ test s8_vd_failed_with_other_account_output() fail { let tx = mock_vault_deposit_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, - ProcessVaultDeposit(#"", [], SharesInsert { proof: [] }), + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), Script(""), tx, ) diff --git a/validators/tests/hydra_account/vault_withdrawal.ak b/validators/tests/hydra_account/vault_withdrawal.ak index 88ebbb8..0d0668e 100644 --- a/validators/tests/hydra_account/vault_withdrawal.ak +++ b/validators/tests/hydra_account/vault_withdrawal.ak @@ -3,8 +3,8 @@ use cardano/assets.{from_asset, merge, negate} use cardano/transaction.{Transaction} use hydra_account/core as ha use hydra_dex/types.{ - Account, ProcessVaultWithdrawal, SharesDelete, SharesInsert, UserTradeAccount, - VaultOracleDatum, VaultWithdrawalIntentDatumL2, + Account, ProcessVaultWithdrawal, SharesDelete, SharesInsert, TokenMap, + UserTradeAccount, VaultOracleDatum, VaultWithdrawalIntentDatumL2, } use mocktail.{ complete, mint, mock_policy_id, mock_pub_key_hash, mock_tx_hash, mocktail_tx, @@ -272,11 +272,13 @@ test s8_vw_failed_without_any_signature() fail { let tx = mock_vault_withdrawal_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, ProcessVaultWithdrawal( #"", [], + mock_token_map, SharesDelete { proof: [], old_value: #"" }, SharesInsert { proof: [] }, ), @@ -299,11 +301,13 @@ test s8_vw_failed_without_withdrawer_balance_increased() fail { let tx = mock_vault_withdrawal_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, ProcessVaultWithdrawal( #"", [], + mock_token_map, SharesDelete { proof: [], old_value: #"" }, SharesInsert { proof: [] }, ), @@ -326,11 +330,13 @@ test s8_vw_failed_without_vault_balance_deducted() fail { let tx = mock_vault_withdrawal_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, ProcessVaultWithdrawal( #"", [], + mock_token_map, SharesDelete { proof: [], old_value: #"" }, SharesInsert { proof: [] }, ), @@ -353,11 +359,13 @@ test s8_vw_failed_without_intent_token_burnt() fail { let tx = mock_vault_withdrawal_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, ProcessVaultWithdrawal( #"", [], + mock_token_map, SharesDelete { proof: [], old_value: #"" }, SharesInsert { proof: [] }, ), @@ -380,11 +388,13 @@ test s8_vw_failed_with_other_account_input() fail { let tx = mock_vault_withdrawal_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, ProcessVaultWithdrawal( #"", [], + mock_token_map, SharesDelete { proof: [], old_value: #"" }, SharesInsert { proof: [] }, ), @@ -407,11 +417,13 @@ test s8_vw_failed_with_other_account_output() fail { let tx = mock_vault_withdrawal_tx(test_case) + let mock_token_map: TokenMap = [] ha.hydra_account.withdraw( mock_dex_order_book_token, ProcessVaultWithdrawal( #"", [], + mock_token_map, SharesDelete { proof: [], old_value: #"" }, SharesInsert { proof: [] }, ), From 4f2aaf6aba98eea4b0be23cfac5f8aad58e04fec Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 18 Mar 2026 17:47:31 +0800 Subject: [PATCH 08/30] fix: l2 initial deposit --- spec/8_hydra_account/w_vault_deposit.md | 15 +- validators/hydra_account/vault_deposit.ak | 14 +- .../tests/hydra_account/vault_deposit.ak | 178 +++++++++++++++++- 3 files changed, 197 insertions(+), 10 deletions(-) diff --git a/spec/8_hydra_account/w_vault_deposit.md b/spec/8_hydra_account/w_vault_deposit.md index b38f300..824fc14 100644 --- a/spec/8_hydra_account/w_vault_deposit.md +++ b/spec/8_hydra_account/w_vault_deposit.md @@ -1,5 +1,7 @@ # Specification - HydraAccount - Vault Deposit +Supports both initial deposit (when `total_shares == 0`) and regular deposits. + ## User Action - Ref input with `dex_oracle_nft` @@ -8,8 +10,11 @@ - `vault_oracle_nft`, `depositor: UserAccount`, `deposit_amount: MValue` - Get Vault Oracle input/output (UTxO with `vault_oracle_nft`) - Validate intent script matches vault config (`intent_policy_id == l2_deposit_intent_script_hash`) +- Check if initial deposit: `is_initial_deposit = input_total_shares == 0` - Verify prices message with hydra node signatures -- Calculate shares: `shares_minted = (deposit_usd_value * total_shares) / vault_equity` (round DOWN) +- Calculate shares: + - **Initial deposit**: `shares_minted = deposit_usd_value` (share price = 1.0) + - **Regular deposit**: `shares_minted = (deposit_usd_value * total_shares) / vault_equity` (round DOWN) - Categorize inputs into - `DI` - Depositor Inputs (by full `UserAccount`) - `VI` - Vault Inputs (by `master_key == Script(l2_deposit_intent_script_hash)`) @@ -24,7 +29,7 @@ 2. Increase in value for vault (`VO` - `VI`) without lovelace 3. Value in deposit intent (`deposit_amount`) - Verify Merkle transition (SharesInsert or SharesUpdate) - - Key: `cbor.serialise(depositor)` (UserAccount) + - Key: `cbor.serialise(depositor)` (shares always go to depositor) - Value: `SharesRecordEntry { shares, total_deposited }` - Vault Oracle output datum updated: - `total_shares += shares_minted` @@ -33,6 +38,12 @@ - The intent token is burnt - Signed by `operation_key` +## Initial Deposit Notes + +- Anyone can perform the initial deposit (no depositor restriction) +- Shares are minted for the depositor (same as regular deposit) +- Share price is 1.0 (shares = USD value deposited) + ## L2 Asset Units - **Intent datum** contains `deposit_amount` in **L2 format**: `MValue = Pairs>` diff --git a/validators/hydra_account/vault_deposit.ak b/validators/hydra_account/vault_deposit.ak index 4a15916..1cf6d9e 100644 --- a/validators/hydra_account/vault_deposit.ak +++ b/validators/hydra_account/vault_deposit.ak @@ -48,7 +48,8 @@ pub fn vault_deposit( hydra_account_script_hash, hydra_token_policy_id, .. - }: DexOrderBookDatum = reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) + }: DexOrderBookDatum = + reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) // 2. Get L2 Deposit Intent from burn event (implicitly verifies burn) let mint_list = mint |> flatten() @@ -81,6 +82,8 @@ pub fn vault_deposit( .. } = input_oracle_datum + let is_initial_deposit = input_total_shares == 0 + // 4. Validate intent script matches vault config let is_intent_valid = intent_policy_id == l2_deposit_intent_script_hash @@ -100,9 +103,14 @@ pub fn vault_deposit( from_asset_list(deposit_amount) |> from_hydra_balance_to_value(hydra_token_policy_id, token_map) let deposit_usd_value = convert_value_to_usd(deposit_amount_l1, prices) - // Round DOWN (integer division) - protects vault + // Initial deposit: share price = 1.0, so shares = deposit_usd_value + // Regular deposit: Round DOWN (integer division) - protects vault let shares_minted = - cal_shares_amount(deposit_usd_value, vault_equity, input_total_shares) + if is_initial_deposit { + deposit_usd_value + } else { + cal_shares_amount(deposit_usd_value, vault_equity, input_total_shares) + } // 7. Group Account UTxOs (following transferal.ak pattern) // Vault UTxOs are filtered by master_key == intent script hash diff --git a/validators/tests/hydra_account/vault_deposit.ak b/validators/tests/hydra_account/vault_deposit.ak index ca101a0..f8a0947 100644 --- a/validators/tests/hydra_account/vault_deposit.ak +++ b/validators/tests/hydra_account/vault_deposit.ak @@ -69,6 +69,7 @@ fn mock_vault_oracle_datum_input() -> VaultOracleDatum { // ========== Test Case Type ========== type VaultDepositTestCase { + is_initial_deposit: Bool, is_operation_key_signed: Bool, is_depositor_balance_deducted: Bool, is_vault_balance_increased: Bool, @@ -81,6 +82,7 @@ type VaultDepositTestCase { fn mock_vault_deposit_tx(test_case: VaultDepositTestCase) -> Transaction { let VaultDepositTestCase { + is_initial_deposit, is_operation_key_signed, is_depositor_balance_deducted, is_vault_balance_increased, @@ -109,15 +111,30 @@ fn mock_vault_deposit_tx(test_case: VaultDepositTestCase) -> Transaction { let vault_oracle_address = from_script("vault_oracle") - // Input oracle datum - let input_oracle_datum = mock_vault_oracle_datum_input() + // Input oracle datum - for initial deposit, total_shares = 0 + let input_oracle_datum = + if is_initial_deposit { + VaultOracleDatum { ..mock_vault_oracle_datum_input(), total_shares: 0 } + } else { + mock_vault_oracle_datum_input() + } // Output oracle datum - updated with new shares - // TODO: Update shares calculation when price tests are added + // Initial deposit: shares_minted = deposit_usd_value (share price = 1.0) + // Regular deposit: shares_minted = (deposit_usd_value * total_shares) / vault_equity + let shares_minted = + if is_initial_deposit { + // Initial: share price = 1.0, so shares = USD value + 100_000_000 + } else { + // Regular: proportional calculation (simplified for test) + 100_000_000_000 + } + let output_oracle_datum = VaultOracleDatum { ..input_oracle_datum, - total_shares: input_oracle_datum.total_shares + 100_000_000_000, + total_shares: input_oracle_datum.total_shares + shares_minted, total_deposited: input_oracle_datum.total_deposited + 100_000_000, shares_merkle_root: #"0000000000000000000000000000000000000000", } @@ -230,6 +247,7 @@ fn mock_vault_deposit_tx(test_case: VaultDepositTestCase) -> Transaction { test s8_vd_failed_without_operation_key_signed() fail { let test_case = VaultDepositTestCase { + is_initial_deposit: False, is_operation_key_signed: False, is_depositor_balance_deducted: True, is_vault_balance_increased: True, @@ -254,12 +272,13 @@ test s8_vd_failed_without_operation_key_signed() fail { test s8_vd_failed_without_depositor_balance_deducted() fail { let test_case = VaultDepositTestCase { + is_initial_deposit: False, is_operation_key_signed: True, is_depositor_balance_deducted: False, is_vault_balance_increased: True, is_intent_token_burnt: True, has_other_account_input: False, - has_other_account_output: False, + has_other_account_output: False, } let tx = mock_vault_deposit_tx(test_case) @@ -276,6 +295,7 @@ test s8_vd_failed_without_depositor_balance_deducted() fail { test s8_vd_failed_without_vault_balance_increased() fail { let test_case = VaultDepositTestCase { + is_initial_deposit: False, is_operation_key_signed: True, is_depositor_balance_deducted: True, is_vault_balance_increased: False, @@ -298,6 +318,7 @@ test s8_vd_failed_without_vault_balance_increased() fail { test s8_vd_failed_without_intent_token_burnt() fail { let test_case = VaultDepositTestCase { + is_initial_deposit: False, is_operation_key_signed: True, is_depositor_balance_deducted: True, is_vault_balance_increased: True, @@ -320,6 +341,7 @@ test s8_vd_failed_without_intent_token_burnt() fail { test s8_vd_failed_with_other_account_input() fail { let test_case = VaultDepositTestCase { + is_initial_deposit: False, is_operation_key_signed: True, is_depositor_balance_deducted: True, is_vault_balance_increased: True, @@ -342,6 +364,147 @@ test s8_vd_failed_with_other_account_input() fail { test s8_vd_failed_with_other_account_output() fail { let test_case = VaultDepositTestCase { + is_initial_deposit: False, + is_operation_key_signed: True, + is_depositor_balance_deducted: True, + is_vault_balance_increased: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: True, + } + + let tx = mock_vault_deposit_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +// ========== Initial Deposit Tests ========== + +test s8_vd_initial_failed_without_operation_key_signed() fail { + let test_case = + VaultDepositTestCase { + is_initial_deposit: True, + is_operation_key_signed: False, + is_depositor_balance_deducted: True, + is_vault_balance_increased: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_initial_failed_without_depositor_balance_deducted() fail { + let test_case = + VaultDepositTestCase { + is_initial_deposit: True, + is_operation_key_signed: True, + is_depositor_balance_deducted: False, + is_vault_balance_increased: True, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_initial_failed_without_vault_balance_increased() fail { + let test_case = + VaultDepositTestCase { + is_initial_deposit: True, + is_operation_key_signed: True, + is_depositor_balance_deducted: True, + is_vault_balance_increased: False, + is_intent_token_burnt: True, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_initial_failed_without_intent_token_burnt() fail { + let test_case = + VaultDepositTestCase { + is_initial_deposit: True, + is_operation_key_signed: True, + is_depositor_balance_deducted: True, + is_vault_balance_increased: True, + is_intent_token_burnt: False, + has_other_account_input: False, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_initial_failed_with_other_account_input() fail { + let test_case = + VaultDepositTestCase { + is_initial_deposit: True, + is_operation_key_signed: True, + is_depositor_balance_deducted: True, + is_vault_balance_increased: True, + is_intent_token_burnt: True, + has_other_account_input: True, + has_other_account_output: False, + } + + let tx = mock_vault_deposit_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultDeposit(#"", [], mock_token_map, SharesInsert { proof: [] }), + Script(""), + tx, + ) +} + +test s8_vd_initial_failed_with_other_account_output() fail { + let test_case = + VaultDepositTestCase { + is_initial_deposit: True, is_operation_key_signed: True, is_depositor_balance_deducted: True, is_vault_balance_increased: True, @@ -374,8 +537,13 @@ test s8_vd_failed_with_other_account_output() fail { // ========== TODO: Shares Calculation Tests ========== // test s8_vd_shares_calculation_correct() { ... } // test s8_vd_shares_round_down() { ... } +// test s8_vd_initial_shares_equals_usd_value() { ... } -- initial deposit share price = 1.0 // ========== TODO: Oracle Datum Update Tests ========== // test s8_vd_failed_total_shares_not_updated() fail { ... } // test s8_vd_failed_total_deposited_not_updated() fail { ... } // test s8_vd_failed_other_fields_changed() fail { ... } + +// ========== TODO: Initial Deposit Specific Tests ========== +// test s8_vd_initial_success_anyone_can_deposit() { ... } -- no depositor restriction +// test s8_vd_initial_shares_go_to_depositor() { ... } -- verify MPF key is depositor From 78cd62c4452fd5bed8fd8d18f5fbcbc2444bbeb2 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 19 Mar 2026 01:52:23 +0800 Subject: [PATCH 09/30] fix: vault accoutn master key wrong check --- spec/8_hydra_account/w_vault_deposit.md | 4 ++-- spec/8_hydra_account/w_vault_withdrawal.md | 4 ++-- validators/hydra_account/vault_deposit.ak | 3 ++- validators/hydra_account/vault_withdrawal.ak | 12 +++++++++--- validators/tests/hydra_account/vault_deposit.ak | 11 +++++++---- validators/tests/hydra_account/vault_withdrawal.ak | 11 +++++++---- 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/spec/8_hydra_account/w_vault_deposit.md b/spec/8_hydra_account/w_vault_deposit.md index 824fc14..351ee3d 100644 --- a/spec/8_hydra_account/w_vault_deposit.md +++ b/spec/8_hydra_account/w_vault_deposit.md @@ -17,11 +17,11 @@ Supports both initial deposit (when `total_shares == 0`) and regular deposits. - **Regular deposit**: `shares_minted = (deposit_usd_value * total_shares) / vault_equity` (round DOWN) - Categorize inputs into - `DI` - Depositor Inputs (by full `UserAccount`) - - `VI` - Vault Inputs (by `master_key == Script(l2_deposit_intent_script_hash)`) + - `VI` - Vault Inputs (by `master_key == Script(vault_script_hash)`) - Other inputs - Categorize outputs into - `DO` - Depositor Outputs (by full `UserAccount`) - - `VO` - Vault Outputs (by `master_key == Script(l2_deposit_intent_script_hash)`) + - `VO` - Vault Outputs (by `master_key == Script(vault_script_hash)`) - Other outputs - No other inputs/outputs at `hydra_account_script_hash` - The 3 values are equal (all in L2 format): diff --git a/spec/8_hydra_account/w_vault_withdrawal.md b/spec/8_hydra_account/w_vault_withdrawal.md index 636af46..272d829 100644 --- a/spec/8_hydra_account/w_vault_withdrawal.md +++ b/spec/8_hydra_account/w_vault_withdrawal.md @@ -17,11 +17,11 @@ - `user_receives = gross_value - fee` - Categorize inputs into - `WI` - Withdrawer Inputs (by full `UserAccount`) - - `VI` - Vault Inputs (by `master_key == Script(l2_withdrawal_intent_script_hash)`) + - `VI` - Vault Inputs (by `master_key == Script(vault_script_hash)`) - Other inputs - Categorize outputs into - `WO` - Withdrawer Outputs (by full `UserAccount`) - - `VO` - Vault Outputs (by `master_key == Script(l2_withdrawal_intent_script_hash)`) + - `VO` - Vault Outputs (by `master_key == Script(vault_script_hash)`) - Other outputs - No other inputs/outputs at `hydra_account_script_hash` - Value transfer validated (in USD): diff --git a/validators/hydra_account/vault_deposit.ak b/validators/hydra_account/vault_deposit.ak index 1cf6d9e..a9e13c1 100644 --- a/validators/hydra_account/vault_deposit.ak +++ b/validators/hydra_account/vault_deposit.ak @@ -76,6 +76,7 @@ pub fn vault_deposit( let VaultOracleDatum { l2_deposit_intent_script_hash, hydra_node_pub_keys, + vault_script_hash, total_shares: input_total_shares, total_deposited: input_total_deposited, shares_merkle_root: input_merkle_root, @@ -114,7 +115,7 @@ pub fn vault_deposit( // 7. Group Account UTxOs (following transferal.ak pattern) // Vault UTxOs are filtered by master_key == intent script hash - let vault_master_key = Script(l2_deposit_intent_script_hash) + let vault_master_key = Script(vault_script_hash) let depositor_input_filter = create_account_inputs_filter(depositor, hydra_account_script_hash) let vault_input_filter = diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak index 5b7b27c..64fc5e6 100644 --- a/validators/hydra_account/vault_withdrawal.ak +++ b/validators/hydra_account/vault_withdrawal.ak @@ -50,7 +50,8 @@ pub fn vault_withdrawal( hydra_account_script_hash, hydra_token_policy_id, .. - }: DexOrderBookDatum = reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) + }: DexOrderBookDatum = + reference_inputs |> get_dex_order_book_datum(dex_oracle_nft) // 2. Get L2 Withdrawal Intent from burn event (implicitly verifies burn) let mint_list = mint |> flatten() @@ -79,6 +80,7 @@ pub fn vault_withdrawal( hydra_node_pub_keys, operator_account, operator_key, + vault_script_hash, operator_charge_percentage, total_shares: input_total_shares, operator_shares: input_operator_shares, @@ -157,7 +159,7 @@ pub fn vault_withdrawal( // 7. Group Account UTxOs // Vault UTxOs are filtered by master_key == intent script hash - let vault_master_key = Script(l2_withdrawal_intent_script_hash) + let vault_master_key = Script(vault_script_hash) let withdrawer_input_filter = create_account_inputs_filter(withdrawer, hydra_account_script_hash) let vault_input_filter = @@ -188,7 +190,11 @@ pub fn vault_withdrawal( let vault_deducted = merge(inputs_value(vault_inputs), negate(outputs_value(vault_outputs))) let vault_deducted_l1 = - from_hydra_balance_to_value(vault_deducted, hydra_token_policy_id, token_map) + from_hydra_balance_to_value( + vault_deducted, + hydra_token_policy_id, + token_map, + ) let vault_deducted_usd = convert_value_to_usd(vault_deducted_l1, prices) // Withdrawer gains user_receives (in USD value) diff --git a/validators/tests/hydra_account/vault_deposit.ak b/validators/tests/hydra_account/vault_deposit.ak index f8a0947..cc749ef 100644 --- a/validators/tests/hydra_account/vault_deposit.ak +++ b/validators/tests/hydra_account/vault_deposit.ak @@ -26,12 +26,15 @@ const mock_vault_oracle_nft = mock_policy_id(500) const mock_l2_deposit_intent_script_hash = #"1234567890abcdef1234567890abcdef1234567890abcdef12345678" -// Mock vault account - uses intent script hash as master key +const mock_vault_script_hash = + #"fedcba0987654321fedcba0987654321fedcba0987654321fedcba09" + +// Mock vault account - uses vault_script_hash as master key fn mock_vault_account() { Account { account_id: #"aabbccdd", - master_key: Script(mock_l2_deposit_intent_script_hash), - operation_key: Script(mock_l2_deposit_intent_script_hash), + master_key: Script(mock_vault_script_hash), + operation_key: Script(mock_vault_script_hash), } } @@ -45,7 +48,7 @@ fn mock_vault_user_account() { fn mock_vault_oracle_datum_input() -> VaultOracleDatum { VaultOracleDatum { app_oracle: mock_policy_id(0), - vault_script_hash: #"", + vault_script_hash: mock_vault_script_hash, l1_deposit_intent_script_hash: #"", l1_withdrawal_intent_script_hash: #"", l2_deposit_intent_script_hash: mock_l2_deposit_intent_script_hash, diff --git a/validators/tests/hydra_account/vault_withdrawal.ak b/validators/tests/hydra_account/vault_withdrawal.ak index 0d0668e..1ec6cc1 100644 --- a/validators/tests/hydra_account/vault_withdrawal.ak +++ b/validators/tests/hydra_account/vault_withdrawal.ak @@ -25,14 +25,17 @@ const mock_vault_oracle_nft = mock_policy_id(500) const mock_l2_withdrawal_intent_script_hash = #"abcdef1234567890abcdef1234567890abcdef1234567890abcdef12" +const mock_vault_script_hash = + #"fedcba0987654321fedcba0987654321fedcba0987654321fedcba09" + const mock_operator_key = mock_pub_key_hash(999) -// Mock vault account - uses intent script hash as master key +// Mock vault account - uses vault_script_hash as master key fn mock_vault_account() { Account { account_id: #"aabbccdd", - master_key: Script(mock_l2_withdrawal_intent_script_hash), - operation_key: Script(mock_l2_withdrawal_intent_script_hash), + master_key: Script(mock_vault_script_hash), + operation_key: Script(mock_vault_script_hash), } } @@ -61,7 +64,7 @@ fn mock_operator_user_account() { fn mock_vault_oracle_datum_input() -> VaultOracleDatum { VaultOracleDatum { app_oracle: mock_policy_id(0), - vault_script_hash: #"", + vault_script_hash: mock_vault_script_hash, l1_deposit_intent_script_hash: #"", l1_withdrawal_intent_script_hash: #"", l2_deposit_intent_script_hash: #"", From f4e24f5c8a624291a5016ce418489b7e14fa9eef Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Fri, 20 Mar 2026 00:33:31 +0800 Subject: [PATCH 10/30] fix: operator min check --- spec/8_hydra_account/w_vault_deposit.md | 9 ++++ spec/8_hydra_account/w_vault_withdrawal.md | 25 ++++++++++- validators/hydra_account/vault_deposit.ak | 16 ++++++- validators/hydra_account/vault_withdrawal.ak | 32 +++++++++++-- .../tests/hydra_account/vault_deposit.ak | 16 +++++++ .../tests/hydra_account/vault_withdrawal.ak | 45 +++++++++++++++++++ 6 files changed, 137 insertions(+), 6 deletions(-) diff --git a/spec/8_hydra_account/w_vault_deposit.md b/spec/8_hydra_account/w_vault_deposit.md index 351ee3d..e7829d6 100644 --- a/spec/8_hydra_account/w_vault_deposit.md +++ b/spec/8_hydra_account/w_vault_deposit.md @@ -33,6 +33,7 @@ Supports both initial deposit (when `total_shares == 0`) and regular deposits. - Value: `SharesRecordEntry { shares, total_deposited }` - Vault Oracle output datum updated: - `total_shares += shares_minted` + - `operator_shares += shares_minted` (only if `depositor == operator_account`) - `total_deposited += deposit_usd_value` - `shares_merkle_root = computed_new_root` - The intent token is burnt @@ -44,6 +45,14 @@ Supports both initial deposit (when `total_shares == 0`) and regular deposits. - Shares are minted for the depositor (same as regular deposit) - Share price is 1.0 (shares = USD value deposited) +## Edge Case: Operator == Depositor + +If the operator deposits (after previously receiving fee shares from withdrawals): +- Existing entry might be: `{ shares: fee_shares, total_deposited: 0 }` (fees don't add to deposited) +- After deposit: `{ shares: fee_shares + new_shares, total_deposited: 0 + deposit_usd_value }` + +This is handled correctly by `SharesUpdate` which adds to both `shares` and `total_deposited`. + ## L2 Asset Units - **Intent datum** contains `deposit_amount` in **L2 format**: `MValue = Pairs>` diff --git a/spec/8_hydra_account/w_vault_withdrawal.md b/spec/8_hydra_account/w_vault_withdrawal.md index 272d829..f5372c8 100644 --- a/spec/8_hydra_account/w_vault_withdrawal.md +++ b/spec/8_hydra_account/w_vault_withdrawal.md @@ -34,16 +34,37 @@ - SharesUpdate: partial withdrawal, deduct shares and proportional cost_basis - Apply Operator Fee Shares (if `fee_shares > 0`) - Key: `cbor.serialise(operator_account)` (UserAccount) - - SharesInsert or SharesUpdate for operator + - SharesInsert: New entry with `{ shares: fee_shares, total_deposited: 0 }` + - SharesUpdate: Add fee_shares to existing entry, **`total_deposited` remains unchanged** + - Fee shares represent earned fees, not new capital deposits +- **Operator minimum share percentage check** (only when operator withdraws): + - `new_operator_shares * 100 >= operator_min_deposit_percentage * new_total_shares` + - Ensures operator maintains minimum stake in the vault - Vault Oracle output datum updated: - `total_shares = input_total_shares - shares_to_redeem + fee_shares` - - `operator_shares += fee_shares` + - `operator_shares`: + - If `withdrawer == operator_account`: `operator_shares - shares_to_redeem + fee_shares` + - If `withdrawer != operator_account`: `operator_shares + fee_shares` - `total_deposited -= cost_basis` - `total_fee_collected += fee` - `shares_merkle_root = final_root` - The intent token is burnt - Signed by `operation_key` OR `operator_key` +## Edge Case: Operator == Withdrawer + +When the operator is also the withdrawer, both MPF transitions operate on the **same entry**: + +1. **Step 1 (User MPF)**: Update/delete the withdrawer's entry → `new_user_root` +2. **Step 2 (Operator MPF)**: Insert/update the operator's entry using `new_user_root` → `final_root` + +| Scenario | Step 1 | Step 2 | Final Entry | +|----------|--------|--------|-------------| +| Full withdrawal | Delete entry | SharesInsert | `{ shares: fee_shares, total_deposited: 0 }` | +| Partial withdrawal | Update (reduce shares/deposited) | SharesUpdate | `{ shares: remaining + fee_shares, total_deposited: reduced }` | + +**Important**: The `operator_mpf_action.from` value must reflect the state **AFTER** step 1's transition. + ## L1 vs L2 Asset Units - **Price message** contains prices in **L1 format**: `Pairs<(PolicyId, AssetName), Int>` diff --git a/validators/hydra_account/vault_deposit.ak b/validators/hydra_account/vault_deposit.ak index a9e13c1..d2bd919 100644 --- a/validators/hydra_account/vault_deposit.ak +++ b/validators/hydra_account/vault_deposit.ak @@ -77,7 +77,9 @@ pub fn vault_deposit( l2_deposit_intent_script_hash, hydra_node_pub_keys, vault_script_hash, + operator_account, total_shares: input_total_shares, + operator_shares: input_operator_shares, total_deposited: input_total_deposited, shares_merkle_root: input_merkle_root, .. @@ -190,11 +192,23 @@ pub fn vault_deposit( _ -> fail @"Invalid MPF action for deposit" } - // 10. Verify Vault Oracle output datum + // 10. Calculate new operator_shares + // If depositor == operator: shares increase by shares_minted + // If depositor != operator: shares unchanged + let is_operator_depositing = depositor == operator_account + let new_operator_shares = + if is_operator_depositing { + input_operator_shares + shares_minted + } else { + input_operator_shares + } + + // Verify Vault Oracle output datum let is_oracle_datum_updated = output_oracle_datum == VaultOracleDatum { ..input_oracle_datum, total_shares: input_total_shares + shares_minted, + operator_shares: new_operator_shares, total_deposited: input_total_deposited + deposit_usd_value, shares_merkle_root: computed_new_root, } diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak index 64fc5e6..2c51357 100644 --- a/validators/hydra_account/vault_withdrawal.ak +++ b/validators/hydra_account/vault_withdrawal.ak @@ -82,6 +82,7 @@ pub fn vault_withdrawal( operator_key, vault_script_hash, operator_charge_percentage, + operator_min_deposit_percentage, total_shares: input_total_shares, operator_shares: input_operator_shares, total_deposited: input_total_deposited, @@ -227,12 +228,36 @@ pub fn vault_withdrawal( new_user_root } - // 11. Verify Vault Oracle output datum + // 11. Calculate new operator_shares + // If withdrawer == operator: shares decrease by shares_to_redeem, increase by fee_shares + // If withdrawer != operator: shares only increase by fee_shares + let is_operator_withdrawing = withdrawer == operator_account + let new_operator_shares = + if is_operator_withdrawing { + input_operator_shares - shares_to_redeem + fee_shares + } else { + input_operator_shares + fee_shares + } + + // Calculate new total_shares for min percentage check + let new_total_shares = input_total_shares - shares_to_redeem + fee_shares + + // Verify operator maintains minimum share percentage when withdrawing + // new_operator_shares / new_total_shares >= operator_min_deposit_percentage / 100 + // Rearranged to avoid division: new_operator_shares * 100 >= operator_min_deposit_percentage * new_total_shares + let is_operator_min_percentage_maintained = + if is_operator_withdrawing { + new_operator_shares * 100 >= operator_min_deposit_percentage * new_total_shares + } else { + True + } + + // Verify Vault Oracle output datum let is_oracle_datum_updated = output_oracle_datum == VaultOracleDatum { ..input_oracle_datum, - total_shares: input_total_shares - shares_to_redeem + fee_shares, - operator_shares: input_operator_shares + fee_shares, + total_shares: new_total_shares, + operator_shares: new_operator_shares, total_deposited: input_total_deposited - cost_basis, total_fee_collected: input_total_fee_collected + fee, shares_merkle_root: final_root, @@ -251,6 +276,7 @@ pub fn vault_withdrawal( no_other_account_inputs?, no_other_account_outputs?, is_value_transfer_correct?, + is_operator_min_percentage_maintained?, is_oracle_datum_updated?, is_signed?, } diff --git a/validators/tests/hydra_account/vault_deposit.ak b/validators/tests/hydra_account/vault_deposit.ak index cc749ef..4c911e2 100644 --- a/validators/tests/hydra_account/vault_deposit.ak +++ b/validators/tests/hydra_account/vault_deposit.ak @@ -550,3 +550,19 @@ test s8_vd_initial_failed_with_other_account_output() fail { // ========== TODO: Initial Deposit Specific Tests ========== // test s8_vd_initial_success_anyone_can_deposit() { ... } -- no depositor restriction // test s8_vd_initial_shares_go_to_depositor() { ... } -- verify MPF key is depositor + +// ========== TODO: Operator == Depositor Edge Case ========== +// When operator deposits (after receiving fee shares from withdrawals) +// Uses SharesUpdate since operator already has an MPF entry +// +// test s8_vd_operator_deposits_with_existing_fee_shares() { ... } +// - Existing entry: { shares: fee_shares, total_deposited: 0 } (from fees) +// - After deposit: { shares: fee_shares + new_shares, total_deposited: deposit_usd_value } +// - Both shares and total_deposited increase correctly +// - operator_shares in VaultOracleDatum increases by shares_minted +// +// test s8_vd_operator_shares_updated_when_operator_deposits() { ... } +// - Verify operator_shares = input_operator_shares + shares_minted +// +// test s8_vd_operator_shares_unchanged_when_non_operator_deposits() { ... } +// - Verify operator_shares remains unchanged when depositor != operator diff --git a/validators/tests/hydra_account/vault_withdrawal.ak b/validators/tests/hydra_account/vault_withdrawal.ak index 1ec6cc1..0f9a060 100644 --- a/validators/tests/hydra_account/vault_withdrawal.ak +++ b/validators/tests/hydra_account/vault_withdrawal.ak @@ -456,9 +456,54 @@ test s8_vw_failed_with_other_account_output() fail { // test s8_vw_fee_shares_rounds_up() { ... } // ========== TODO: Operator Fee Share Tests ========== +// Operator receives fee_shares when profit > 0 +// Key behavior: operator's total_deposited remains UNCHANGED (fee shares are earned, not deposited) +// // test s8_vw_operator_fee_share_insert() { ... } +// - Operator has no existing MPF entry +// - New entry created: { shares: fee_shares, total_deposited: 0 } +// // test s8_vw_operator_fee_share_update() { ... } +// - Operator has existing MPF entry +// - Entry updated: { shares: old_shares + fee_shares, total_deposited: old_deposited } (unchanged) +// // test s8_vw_no_operator_fee_when_no_profit() { ... } +// - No fee when withdrawal_value <= cost_basis + +// ========== TODO: Operator == Withdrawer Edge Case ========== +// When operator is also the withdrawer, both MPF transitions affect the same entry +// Step 1 (user MPF) runs first, Step 2 (operator MPF) uses the resulting root +// operator_shares = input_operator_shares - shares_to_redeem + fee_shares +// +// test s8_vw_operator_is_withdrawer_full_withdrawal() { ... } +// - Step 1: SharesDelete (remove operator's entry) +// - Step 2: SharesInsert (re-insert with fee_shares only) +// - Final entry: { shares: fee_shares, total_deposited: 0 } +// - operator_shares = input_operator_shares - shares_to_redeem + fee_shares +// +// test s8_vw_operator_is_withdrawer_partial_withdrawal() { ... } +// - Step 1: SharesUpdate (reduce shares and proportional cost_basis) +// - Step 2: SharesUpdate (add fee_shares, total_deposited unchanged from step 1) +// - Final entry: { shares: remaining + fee_shares, total_deposited: reduced } +// - operator_shares = input_operator_shares - shares_to_redeem + fee_shares +// +// test s8_vw_operator_shares_updated_when_operator_withdraws() { ... } +// - Verify operator_shares = input - shares_to_redeem + fee_shares +// +// test s8_vw_operator_shares_only_adds_fee_when_non_operator_withdraws() { ... } +// - Verify operator_shares = input + fee_shares when withdrawer != operator + +// ========== TODO: Operator Minimum Percentage Tests ========== +// When operator withdraws, must maintain: new_operator_shares / new_total_shares >= operator_min_deposit_percentage / 100 +// +// test s8_vw_operator_withdrawal_respects_min_percentage() { ... } +// - Operator can withdraw if they maintain minimum percentage +// +// test s8_vw_operator_withdrawal_fails_below_min_percentage() fail { ... } +// - Operator cannot withdraw if it would drop below minimum percentage +// +// test s8_vw_non_operator_withdrawal_ignores_min_percentage() { ... } +// - Non-operator withdrawals don't check minimum percentage // ========== TODO: Oracle Datum Update Tests ========== // test s8_vw_failed_total_shares_not_updated() fail { ... } From 54e87f4f259eada35ed97e7cdadeb5f5caf5b675 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Fri, 20 Mar 2026 00:42:05 +0800 Subject: [PATCH 11/30] feat: operator min check --- .../tests/hydra_account/vault_withdrawal.ak | 259 +++++++++++++++++- 1 file changed, 249 insertions(+), 10 deletions(-) diff --git a/validators/tests/hydra_account/vault_withdrawal.ak b/validators/tests/hydra_account/vault_withdrawal.ak index 0f9a060..beb1644 100644 --- a/validators/tests/hydra_account/vault_withdrawal.ak +++ b/validators/tests/hydra_account/vault_withdrawal.ak @@ -493,17 +493,256 @@ test s8_vw_failed_with_other_account_output() fail { // test s8_vw_operator_shares_only_adds_fee_when_non_operator_withdraws() { ... } // - Verify operator_shares = input + fee_shares when withdrawer != operator -// ========== TODO: Operator Minimum Percentage Tests ========== +// ========== Operator Minimum Percentage Tests ========== // When operator withdraws, must maintain: new_operator_shares / new_total_shares >= operator_min_deposit_percentage / 100 -// -// test s8_vw_operator_withdrawal_respects_min_percentage() { ... } -// - Operator can withdraw if they maintain minimum percentage -// -// test s8_vw_operator_withdrawal_fails_below_min_percentage() fail { ... } -// - Operator cannot withdraw if it would drop below minimum percentage -// -// test s8_vw_non_operator_withdrawal_ignores_min_percentage() { ... } -// - Non-operator withdrawals don't check minimum percentage + +type OperatorMinPercentageTestCase { + // Vault state + total_shares: Int, + operator_shares: Int, + operator_min_deposit_percentage: Int, + // Withdrawal params + shares_to_redeem: Int, + fee_shares: Int, +} + +fn mock_operator_min_percentage_tx(test_case: OperatorMinPercentageTestCase) -> Transaction { + let OperatorMinPercentageTestCase { + total_shares, + operator_shares, + operator_min_deposit_percentage, + shares_to_redeem, + fee_shares, + } = test_case + + let withdrawal_value = mock_hydra_lovelace(100_000_000) + let operator_balance_start = mock_hydra_lovelace(500_000_000) + let vault_balance_start = mock_hydra_lovelace(5_000_000_000) + + let operator_balance_end = withdrawal_value |> merge(operator_balance_start) + let vault_balance_end = + withdrawal_value |> negate() |> merge(vault_balance_start) + + let vault_oracle_address = from_script("vault_oracle") + + // Input oracle datum with operator shares and min percentage + let input_oracle_datum = + VaultOracleDatum { + ..mock_vault_oracle_datum_input(), + total_shares: total_shares, + operator_shares: operator_shares, + operator_min_deposit_percentage: operator_min_deposit_percentage, + } + + // Calculate new values after withdrawal + let new_total_shares = total_shares - shares_to_redeem + fee_shares + let new_operator_shares = operator_shares - shares_to_redeem + fee_shares + + let output_oracle_datum = + VaultOracleDatum { + ..input_oracle_datum, + total_shares: new_total_shares, + operator_shares: new_operator_shares, + total_deposited: input_oracle_datum.total_deposited - 100_000_000, + shares_merkle_root: #"0000000000000000000000000000000000000000", + } + + let intent_address = from_script(mock_l2_withdrawal_intent_script_hash) + + mocktail_tx() + // Reference input: DexOrderBook + |> ref_tx_in( + True, + mock_tx_hash(1), + 0, + from_asset(mock_dex_order_book_token, "", 1), + mock_dex_order_book_address, + ) + |> ref_tx_in_inline_datum(True, mock_dex_order_book_datum) + // Intent input - OPERATOR is the withdrawer + |> tx_in( + True, + mock_tx_hash(0), + 0, + from_asset(mock_l2_withdrawal_intent_script_hash, "", 1), + intent_address, + ) + |> tx_in_inline_datum( + True, + VaultWithdrawalIntentDatumL2 { + vault_oracle_nft: mock_vault_oracle_nft, + withdrawer: mock_operator_user_account(), + shares_to_redeem, + }, + ) + // Vault Oracle input + |> tx_in( + True, + mock_tx_hash(0), + 1, + from_asset(mock_vault_oracle_nft, "", 1), + vault_oracle_address, + ) + |> tx_in_inline_datum(True, input_oracle_datum) + // Vault Oracle output + |> tx_out( + True, + vault_oracle_address, + from_asset(mock_vault_oracle_nft, "", 1), + ) + |> tx_out_inline_datum(True, output_oracle_datum) + // Operator (withdrawer) input + |> tx_in( + True, + mock_tx_hash(0), + 2, + operator_balance_start, + mock_hydra_account_address, + ) + |> tx_in_inline_datum(True, mock_operator_user_account()) + // Operator (withdrawer) output + |> tx_out(True, mock_hydra_account_address, operator_balance_end) + |> tx_out_inline_datum(True, mock_operator_user_account()) + // Vault account input + |> tx_in( + True, + mock_tx_hash(0), + 3, + vault_balance_start, + mock_hydra_account_address, + ) + |> tx_in_inline_datum(True, mock_vault_user_account()) + // Vault account output + |> tx_out(True, mock_hydra_account_address, vault_balance_end) + |> tx_out_inline_datum(True, mock_vault_user_account()) + // Mint (burn intent token) + |> mint(True, -1, mock_l2_withdrawal_intent_script_hash, "") + // Operator signs + |> required_signer_hash(True, mock_operator_key) + |> complete() +} + +// Operator has 20% of shares (200 of 1000), min is 10% +// Withdraws 50 shares -> new: 150/950 = 15.7% >= 10% ✓ +// NOTE: Test marked `fail` because merkle/price verification not mocked. +// Min percentage check PASSES in this scenario (150*100 >= 10*950 -> 15000 >= 9500) +test s8_vw_operator_withdrawal_respects_min_percentage() fail { + let test_case = + OperatorMinPercentageTestCase { + total_shares: 1000, + operator_shares: 200, + operator_min_deposit_percentage: 10, + shares_to_redeem: 50, + fee_shares: 0, + } + + let tx = mock_operator_min_percentage_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + mock_token_map, + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} + +// Operator has 15% of shares (150 of 1000), min is 10% +// Withdraws 100 shares -> new: 50/900 = 5.5% < 10% ✗ +// Min percentage check FAILS (50*100 >= 10*900 -> 5000 >= 9000 is FALSE) +test s8_vw_operator_withdrawal_fails_below_min_percentage() fail { + let test_case = + OperatorMinPercentageTestCase { + total_shares: 1000, + operator_shares: 150, + operator_min_deposit_percentage: 10, + shares_to_redeem: 100, + fee_shares: 0, + } + + let tx = mock_operator_min_percentage_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + mock_token_map, + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} + +// Operator has 10% of shares (100 of 1000), min is 10% +// Withdraws 50 shares, earns 40 fee_shares -> new: 90/990 = 9.09% < 10% ✗ +// Min percentage check FAILS (90*100 >= 10*990 -> 9000 >= 9900 is FALSE) +test s8_vw_operator_withdrawal_with_fee_still_fails_below_min() fail { + let test_case = + OperatorMinPercentageTestCase { + total_shares: 1000, + operator_shares: 100, + operator_min_deposit_percentage: 10, + shares_to_redeem: 50, + fee_shares: 40, + } + + let tx = mock_operator_min_percentage_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + mock_token_map, + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} + +// Operator has 10% (100 of 1000), min is 10% +// Withdraws 50, earns 50 fee_shares -> new: 100/1000 = 10% == 10% ✓ +// NOTE: Test marked `fail` because merkle/price verification not mocked. +// Min percentage check PASSES (100*100 >= 10*1000 -> 10000 >= 10000) +test s8_vw_operator_withdrawal_with_fee_maintains_exact_min() fail { + let test_case = + OperatorMinPercentageTestCase { + total_shares: 1000, + operator_shares: 100, + operator_min_deposit_percentage: 10, + shares_to_redeem: 50, + fee_shares: 50, + } + + let tx = mock_operator_min_percentage_tx(test_case) + + let mock_token_map: TokenMap = [] + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessVaultWithdrawal( + #"", + [], + mock_token_map, + SharesDelete { proof: [], old_value: #"" }, + SharesInsert { proof: [] }, + ), + Script(""), + tx, + ) +} // ========== TODO: Oracle Datum Update Tests ========== // test s8_vw_failed_total_shares_not_updated() fail { ... } From 86d95d8381e72bdc7409a63825f59a95423b374a Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Fri, 20 Mar 2026 01:54:49 +0800 Subject: [PATCH 12/30] fix: total_fee_share_collected --- lib/hydra_dex/types.ak | 2 +- spec/8_hydra_account/w_vault_withdrawal.md | 2 +- validators/hydra_account/vault_withdrawal.ak | 4 ++-- validators/tests/hydra_account/vault_deposit.ak | 2 +- validators/tests/hydra_account/vault_withdrawal.ak | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index 3e81864..e0a0a9f 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -371,5 +371,5 @@ pub type VaultOracleDatum { operator_shares: Int, total_deposited: Int, shares_merkle_root: ByteArray, - total_fee_collected: Int, + total_fee_share_collected: Int, } diff --git a/spec/8_hydra_account/w_vault_withdrawal.md b/spec/8_hydra_account/w_vault_withdrawal.md index f5372c8..32d7a53 100644 --- a/spec/8_hydra_account/w_vault_withdrawal.md +++ b/spec/8_hydra_account/w_vault_withdrawal.md @@ -46,7 +46,7 @@ - If `withdrawer == operator_account`: `operator_shares - shares_to_redeem + fee_shares` - If `withdrawer != operator_account`: `operator_shares + fee_shares` - `total_deposited -= cost_basis` - - `total_fee_collected += fee` + - `total_fee_share_collected += fee_shares` - `shares_merkle_root = final_root` - The intent token is burnt - Signed by `operation_key` OR `operator_key` diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak index 2c51357..0662d43 100644 --- a/validators/hydra_account/vault_withdrawal.ak +++ b/validators/hydra_account/vault_withdrawal.ak @@ -87,7 +87,7 @@ pub fn vault_withdrawal( operator_shares: input_operator_shares, total_deposited: input_total_deposited, shares_merkle_root: input_merkle_root, - total_fee_collected: input_total_fee_collected, + total_fee_share_collected: input_total_fee_share_collected, .. } = input_oracle_datum @@ -259,7 +259,7 @@ pub fn vault_withdrawal( total_shares: new_total_shares, operator_shares: new_operator_shares, total_deposited: input_total_deposited - cost_basis, - total_fee_collected: input_total_fee_collected + fee, + total_fee_share_collected: input_total_fee_share_collected + fee_shares, shares_merkle_root: final_root, } diff --git a/validators/tests/hydra_account/vault_deposit.ak b/validators/tests/hydra_account/vault_deposit.ak index 4c911e2..9d6055a 100644 --- a/validators/tests/hydra_account/vault_deposit.ak +++ b/validators/tests/hydra_account/vault_deposit.ak @@ -65,7 +65,7 @@ fn mock_vault_oracle_datum_input() -> VaultOracleDatum { operator_shares: 0, total_deposited: 1_000_000_000, shares_merkle_root: #"", - total_fee_collected: 0, + total_fee_share_collected: 0, } } diff --git a/validators/tests/hydra_account/vault_withdrawal.ak b/validators/tests/hydra_account/vault_withdrawal.ak index beb1644..828c383 100644 --- a/validators/tests/hydra_account/vault_withdrawal.ak +++ b/validators/tests/hydra_account/vault_withdrawal.ak @@ -81,7 +81,7 @@ fn mock_vault_oracle_datum_input() -> VaultOracleDatum { operator_shares: 0, total_deposited: 1_000_000_000, shares_merkle_root: #"", - total_fee_collected: 0, + total_fee_share_collected: 0, } } @@ -748,7 +748,7 @@ test s8_vw_operator_withdrawal_with_fee_maintains_exact_min() fail { // test s8_vw_failed_total_shares_not_updated() fail { ... } // test s8_vw_failed_operator_shares_not_updated() fail { ... } // test s8_vw_failed_total_deposited_not_updated() fail { ... } -// test s8_vw_failed_total_fee_collected_not_updated() fail { ... } +// test s8_vw_failed_total_fee_share_collected_not_updated() fail { ... } // test s8_vw_failed_other_fields_changed() fail { ... } // ========== TODO: Value Transfer Tests ========== From 695268a58852efd13493a3a61ce994b177606c29 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 23 Mar 2026 14:36:31 +0800 Subject: [PATCH 13/30] fix: withdrawer == operator no share --- lib/hydra_dex/price_oracle_utils.ak | 13 +++- lib/hydra_dex/types.ak | 5 +- spec/8_hydra_account/w_vault_withdrawal.md | 37 ++++++---- validators/hydra_account/vault_withdrawal.ak | 73 ++++++++++++------- .../tests/hydra_account/vault_deposit.ak | 1 - .../tests/hydra_account/vault_withdrawal.ak | 67 ++++++++--------- 6 files changed, 114 insertions(+), 82 deletions(-) diff --git a/lib/hydra_dex/price_oracle_utils.ak b/lib/hydra_dex/price_oracle_utils.ak index 2a1903e..5975977 100644 --- a/lib/hydra_dex/price_oracle_utils.ak +++ b/lib/hydra_dex/price_oracle_utils.ak @@ -1,6 +1,7 @@ use aiken/cbor use aiken/collection/list use aiken/collection/pairs +use aiken/crypto.{VerificationKey} use cardano/assets.{AssetName, PolicyId, Value} use cardano/transaction.{Input} use cocktail.{verify_pub_keys, verify_signatures} @@ -9,8 +10,8 @@ use hydra_dex/types.{MValue, Message} pub fn verify_prices_oracle_messages( prices_message: ByteArray, inputs: List, - hydra_signers: List, - hydra_node_pub_keys: List, + hydra_signers: List, + hydra_node_pub_keys: List, signatures: List, ) -> (Int, Pairs<(PolicyId, AssetName), Int>, Bool) { expect Some(signed_data) = cbor.deserialise(prices_message) @@ -19,9 +20,13 @@ pub fn verify_prices_oracle_messages( let is_utxo_consumed = list.any(inputs, fn(input) { input.output_reference == utxo_ref }) - let keys_check = verify_pub_keys(hydra_node_pub_keys, hydra_signers) + // Convert VerificationKey to ByteArray for cocktail functions + let pub_keys_bytes = list.map(hydra_node_pub_keys, fn(vk) { vk }) + let signers_bytes = list.map(hydra_signers, fn(vk) { vk }) + + let keys_check = verify_pub_keys(pub_keys_bytes, signers_bytes) let signatures_check = - verify_signatures(hydra_node_pub_keys, prices_message, signatures) + verify_signatures(pub_keys_bytes, prices_message, signatures) let message_verified = is_utxo_consumed? && keys_check? && signatures_check? diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index e0a0a9f..ea96d95 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -1,4 +1,4 @@ -use aiken/crypto.{ScriptHash, VerificationKeyHash} +use aiken/crypto.{ScriptHash, VerificationKey, VerificationKeyHash} use aiken/merkle_patricia_forestry.{Proof} use cardano/address.{Address, Credential} use cardano/assets.{AssetName, PolicyId} @@ -360,11 +360,10 @@ pub type VaultOracleDatum { l2_withdrawal_intent_script_hash: ByteArray, pluggable_logic: ByteArray, vault_stake_rotation_script_hash: ByteArray, - operator_key: VerificationKeyHash, operator_account: UserAccount, operator_charge_percentage: Int, operator_min_deposit_percentage: Int, - hydra_node_pub_keys: List, + hydra_node_pub_keys: List, is_active: Bool, // State (mutable) total_shares: Int, diff --git a/spec/8_hydra_account/w_vault_withdrawal.md b/spec/8_hydra_account/w_vault_withdrawal.md index 32d7a53..27028fb 100644 --- a/spec/8_hydra_account/w_vault_withdrawal.md +++ b/spec/8_hydra_account/w_vault_withdrawal.md @@ -12,9 +12,13 @@ - Calculate withdrawal values: - `gross_value = (shares_to_redeem * vault_equity) / total_shares` (round DOWN) - `cost_basis` from merkle proof (proportional for partial withdrawal) - - `fee = ceil((profit * operator_charge_percentage) / 100)` if profit > 0 - - `fee_shares = ceil((fee * total_shares) / vault_equity)` - - `user_receives = gross_value - fee` + - **If `withdrawer == operator_account`**: Skip fee (economically neutral) + - `fee = 0`, `fee_shares = 0` + - `user_receives = gross_value` + - **If `withdrawer != operator_account`**: Calculate fee on profit + - `fee = ceil((profit * operator_charge_percentage) / 100)` if profit > 0 + - `fee_shares = ceil((fee * total_shares) / vault_equity)` + - `user_receives = gross_value - fee` - Categorize inputs into - `WI` - Withdrawer Inputs (by full `UserAccount`) - `VI` - Vault Inputs (by `master_key == Script(vault_script_hash)`) @@ -32,38 +36,41 @@ - Key: `cbor.serialise(withdrawer)` (UserAccount) - SharesDelete: full withdrawal, `shares_to_redeem == old_entry.shares` - SharesUpdate: partial withdrawal, deduct shares and proportional cost_basis -- Apply Operator Fee Shares (if `fee_shares > 0`) +- Apply Operator Fee Shares (only when `withdrawer != operator_account` and `fee_shares > 0`) - Key: `cbor.serialise(operator_account)` (UserAccount) - SharesInsert: New entry with `{ shares: fee_shares, total_deposited: 0 }` - SharesUpdate: Add fee_shares to existing entry, **`total_deposited` remains unchanged** - Fee shares represent earned fees, not new capital deposits + - **Skipped when operator withdraws** (no fee collected from self) - **Operator minimum share percentage check** (only when operator withdraws): - `new_operator_shares * 100 >= operator_min_deposit_percentage * new_total_shares` - Ensures operator maintains minimum stake in the vault - Vault Oracle output datum updated: - `total_shares = input_total_shares - shares_to_redeem + fee_shares` - `operator_shares`: - - If `withdrawer == operator_account`: `operator_shares - shares_to_redeem + fee_shares` + - If `withdrawer == operator_account`: `operator_shares - shares_to_redeem` (no fee from self) - If `withdrawer != operator_account`: `operator_shares + fee_shares` - `total_deposited -= cost_basis` - - `total_fee_share_collected += fee_shares` + - `total_fee_share_collected += fee_shares` (0 when operator withdraws) - `shares_merkle_root = final_root` - The intent token is burnt -- Signed by `operation_key` OR `operator_key` +- Signed by `operation_key` OR operator's `master_key` (from `operator_account`) ## Edge Case: Operator == Withdrawer -When the operator is also the withdrawer, both MPF transitions operate on the **same entry**: +When the operator is also the withdrawer: -1. **Step 1 (User MPF)**: Update/delete the withdrawer's entry → `new_user_root` -2. **Step 2 (Operator MPF)**: Insert/update the operator's entry using `new_user_root` → `final_root` +- **Fee is skipped** (economically neutral - operator paying fee to themselves) +- `fee_shares = 0`, so no operator MPF action is needed +- Only the user MPF transition is performed (update/delete withdrawer's entry) +- `final_root = new_user_root` (no second MPF step) -| Scenario | Step 1 | Step 2 | Final Entry | -|----------|--------|--------|-------------| -| Full withdrawal | Delete entry | SharesInsert | `{ shares: fee_shares, total_deposited: 0 }` | -| Partial withdrawal | Update (reduce shares/deposited) | SharesUpdate | `{ shares: remaining + fee_shares, total_deposited: reduced }` | +| Scenario | User MPF Action | Operator MPF Action | Result | +| ------------------ | --------------- | ------------------- | -------------- | +| Full withdrawal | SharesDelete | None | Entry removed | +| Partial withdrawal | SharesUpdate | None | Shares reduced | -**Important**: The `operator_mpf_action.from` value must reflect the state **AFTER** step 1's transition. +This simplifies the transaction and reduces computation compared to the case where operator pays fees to themselves. ## L1 vs L2 Asset Units diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak index 0662d43..b4b923e 100644 --- a/validators/hydra_account/vault_withdrawal.ak +++ b/validators/hydra_account/vault_withdrawal.ak @@ -1,6 +1,6 @@ use aiken/cbor use aiken/merkle_patricia_forestry as mpf -use cardano/address.{Script, from_script} +use cardano/address.{Script, VerificationKey, from_script} use cardano/assets.{PolicyId, flatten, merge, negate} use cardano/transaction.{Transaction} use cocktail.{ @@ -11,7 +11,7 @@ use cocktail.{ use hydra_dex/account_utils.{ create_account_inputs_filter, create_account_outputs_filter, create_master_key_inputs_filter, create_master_key_outputs_filter, - from_hydra_balance_to_value, + from_hydra_balance_to_value, get_master_key, } use hydra_dex/price_oracle_utils.{ convert_value_to_usd, verify_prices_oracle_messages, @@ -79,7 +79,6 @@ pub fn vault_withdrawal( l2_withdrawal_intent_script_hash, hydra_node_pub_keys, operator_account, - operator_key, vault_script_hash, operator_charge_percentage, operator_min_deposit_percentage, @@ -104,7 +103,10 @@ pub fn vault_withdrawal( signatures, ) - // 6. Calculate withdrawal values (Division Order: multiply first!) + // 6. Check if operator is withdrawing (skip fee if so) + let is_operator_withdrawing = withdrawer == operator_account + + // 7. Calculate withdrawal values (Division Order: multiply first!) // Gross value: Round DOWN (integer division) - protects vault let gross_value = convert_shares_to_usd(shares_to_redeem, input_total_shares, vault_equity) @@ -144,19 +146,34 @@ pub fn vault_withdrawal( _ -> fail @"Invalid MPF action for withdrawal" } - // Calculate fee based on profit - Round UP to protect operator - let fee = - cal_per_user_operator_fee( - gross_value, - cost_basis, - operator_charge_percentage, - ) - - // Fee shares - Round UP to protect operator - let fee_shares = compute_fee_shares(fee, input_total_shares, vault_equity) + // Calculate fee based on profit - Skip fee when operator withdraws (economically neutral) + let fee_shares = + if is_operator_withdrawing { + 0 + } else { + let fee = + cal_per_user_operator_fee( + gross_value, + cost_basis, + operator_charge_percentage, + ) + // Fee shares - Round UP to protect operator + compute_fee_shares(fee, input_total_shares, vault_equity) + } - // User receives (naturally rounds DOWN) - let user_receives = gross_value - fee + // User receives: gross_value when operator, gross_value - fee otherwise + let user_receives = + if is_operator_withdrawing { + gross_value + } else { + let fee = + cal_per_user_operator_fee( + gross_value, + cost_basis, + operator_charge_percentage, + ) + gross_value - fee + } // 7. Group Account UTxOs // Vault UTxOs are filtered by master_key == intent script hash @@ -215,7 +232,8 @@ pub fn vault_withdrawal( let is_value_transfer_correct = vault_deducted_usd == user_receives && withdrawer_added_usd == user_receives - // 10. Apply Operator Fee Shares (if fee > 0) + // 10. Apply Operator Fee Shares (only when non-operator withdraws with profit) + // When operator withdraws, fee_shares is 0, so no operator MPF action needed let final_root = if fee_shares > 0 { apply_operator_fee_share( @@ -229,12 +247,11 @@ pub fn vault_withdrawal( } // 11. Calculate new operator_shares - // If withdrawer == operator: shares decrease by shares_to_redeem, increase by fee_shares - // If withdrawer != operator: shares only increase by fee_shares - let is_operator_withdrawing = withdrawer == operator_account + // If withdrawer == operator: shares decrease by shares_to_redeem (no fee earned from self) + // If withdrawer != operator: shares increase by fee_shares let new_operator_shares = if is_operator_withdrawing { - input_operator_shares - shares_to_redeem + fee_shares + input_operator_shares - shares_to_redeem } else { input_operator_shares + fee_shares } @@ -263,12 +280,16 @@ pub fn vault_withdrawal( shares_merkle_root: final_root, } - // 12. Verify signature (operation_key OR operator_key) + // 12. Verify signature (operation_key OR operator's master_key) + // Operator key is derived from operator_account's master_key + let is_operator_signed = + when get_master_key(operator_account) is { + VerificationKey(operator_key_hash) -> + key_signed(extra_signatories, operator_key_hash) + _ -> False + } let is_signed = - key_signed(extra_signatories, operation_key) || key_signed( - extra_signatories, - operator_key, - ) + key_signed(extra_signatories, operation_key) || is_operator_signed and { is_intent_valid?, diff --git a/validators/tests/hydra_account/vault_deposit.ak b/validators/tests/hydra_account/vault_deposit.ak index 9d6055a..90f1bb1 100644 --- a/validators/tests/hydra_account/vault_deposit.ak +++ b/validators/tests/hydra_account/vault_deposit.ak @@ -55,7 +55,6 @@ fn mock_vault_oracle_datum_input() -> VaultOracleDatum { l2_withdrawal_intent_script_hash: #"", pluggable_logic: #"", vault_stake_rotation_script_hash: #"", - operator_key: mock_operation_key, operator_account: mock_user_account(mock_account), operator_charge_percentage: 10, operator_min_deposit_percentage: 0, diff --git a/validators/tests/hydra_account/vault_withdrawal.ak b/validators/tests/hydra_account/vault_withdrawal.ak index 828c383..24e4390 100644 --- a/validators/tests/hydra_account/vault_withdrawal.ak +++ b/validators/tests/hydra_account/vault_withdrawal.ak @@ -71,7 +71,6 @@ fn mock_vault_oracle_datum_input() -> VaultOracleDatum { l2_withdrawal_intent_script_hash: mock_l2_withdrawal_intent_script_hash, pluggable_logic: #"", vault_stake_rotation_script_hash: #"", - operator_key: mock_operator_key, operator_account: mock_operator_user_account(), operator_charge_percentage: 10, operator_min_deposit_percentage: 0, @@ -456,45 +455,52 @@ test s8_vw_failed_with_other_account_output() fail { // test s8_vw_fee_shares_rounds_up() { ... } // ========== TODO: Operator Fee Share Tests ========== -// Operator receives fee_shares when profit > 0 +// Operator receives fee_shares ONLY from non-operator withdrawals (when profit > 0) // Key behavior: operator's total_deposited remains UNCHANGED (fee shares are earned, not deposited) +// NOTE: Fee is SKIPPED when operator withdraws (economically neutral - paying fee to self) // // test s8_vw_operator_fee_share_insert() { ... } +// - Non-operator withdraws with profit // - Operator has no existing MPF entry // - New entry created: { shares: fee_shares, total_deposited: 0 } // // test s8_vw_operator_fee_share_update() { ... } +// - Non-operator withdraws with profit // - Operator has existing MPF entry // - Entry updated: { shares: old_shares + fee_shares, total_deposited: old_deposited } (unchanged) // // test s8_vw_no_operator_fee_when_no_profit() { ... } // - No fee when withdrawal_value <= cost_basis +// +// test s8_vw_no_operator_fee_when_operator_withdraws() { ... } +// - Fee is skipped when operator is the withdrawer (fee_shares = 0) // ========== TODO: Operator == Withdrawer Edge Case ========== -// When operator is also the withdrawer, both MPF transitions affect the same entry -// Step 1 (user MPF) runs first, Step 2 (operator MPF) uses the resulting root -// operator_shares = input_operator_shares - shares_to_redeem + fee_shares +// When operator is also the withdrawer: +// - Fee is SKIPPED (economically neutral - operator paying fee to themselves) +// - Only user MPF transition is performed (no operator MPF action needed) +// - operator_shares = input_operator_shares - shares_to_redeem (no fee_shares offset) // // test s8_vw_operator_is_withdrawer_full_withdrawal() { ... } -// - Step 1: SharesDelete (remove operator's entry) -// - Step 2: SharesInsert (re-insert with fee_shares only) -// - Final entry: { shares: fee_shares, total_deposited: 0 } -// - operator_shares = input_operator_shares - shares_to_redeem + fee_shares +// - SharesDelete (remove operator's entry completely) +// - No operator MPF action (fee_shares = 0) +// - operator_shares = 0 // // test s8_vw_operator_is_withdrawer_partial_withdrawal() { ... } -// - Step 1: SharesUpdate (reduce shares and proportional cost_basis) -// - Step 2: SharesUpdate (add fee_shares, total_deposited unchanged from step 1) -// - Final entry: { shares: remaining + fee_shares, total_deposited: reduced } -// - operator_shares = input_operator_shares - shares_to_redeem + fee_shares +// - SharesUpdate (reduce shares and proportional cost_basis) +// - No operator MPF action (fee_shares = 0) +// - Final entry: { shares: remaining, total_deposited: reduced } +// - operator_shares = input_operator_shares - shares_to_redeem // -// test s8_vw_operator_shares_updated_when_operator_withdraws() { ... } -// - Verify operator_shares = input - shares_to_redeem + fee_shares +// test s8_vw_operator_shares_decreases_when_operator_withdraws() { ... } +// - Verify operator_shares = input - shares_to_redeem (no fee offset) // // test s8_vw_operator_shares_only_adds_fee_when_non_operator_withdraws() { ... } // - Verify operator_shares = input + fee_shares when withdrawer != operator // ========== Operator Minimum Percentage Tests ========== // When operator withdraws, must maintain: new_operator_shares / new_total_shares >= operator_min_deposit_percentage / 100 +// NOTE: Fee is skipped when operator withdraws (fee_shares = 0), so no fee offset type OperatorMinPercentageTestCase { // Vault state @@ -503,7 +509,6 @@ type OperatorMinPercentageTestCase { operator_min_deposit_percentage: Int, // Withdrawal params shares_to_redeem: Int, - fee_shares: Int, } fn mock_operator_min_percentage_tx(test_case: OperatorMinPercentageTestCase) -> Transaction { @@ -512,7 +517,6 @@ fn mock_operator_min_percentage_tx(test_case: OperatorMinPercentageTestCase) -> operator_shares, operator_min_deposit_percentage, shares_to_redeem, - fee_shares, } = test_case let withdrawal_value = mock_hydra_lovelace(100_000_000) @@ -535,8 +539,9 @@ fn mock_operator_min_percentage_tx(test_case: OperatorMinPercentageTestCase) -> } // Calculate new values after withdrawal - let new_total_shares = total_shares - shares_to_redeem + fee_shares - let new_operator_shares = operator_shares - shares_to_redeem + fee_shares + // NOTE: fee_shares = 0 when operator withdraws (fee is skipped) + let new_total_shares = total_shares - shares_to_redeem + let new_operator_shares = operator_shares - shares_to_redeem let output_oracle_datum = VaultOracleDatum { @@ -623,7 +628,7 @@ fn mock_operator_min_percentage_tx(test_case: OperatorMinPercentageTestCase) -> } // Operator has 20% of shares (200 of 1000), min is 10% -// Withdraws 50 shares -> new: 150/950 = 15.7% >= 10% ✓ +// Withdraws 50 shares -> new: 150/950 = 15.8% >= 10% ✓ // NOTE: Test marked `fail` because merkle/price verification not mocked. // Min percentage check PASSES in this scenario (150*100 >= 10*950 -> 15000 >= 9500) test s8_vw_operator_withdrawal_respects_min_percentage() fail { @@ -633,7 +638,6 @@ test s8_vw_operator_withdrawal_respects_min_percentage() fail { operator_shares: 200, operator_min_deposit_percentage: 10, shares_to_redeem: 50, - fee_shares: 0, } let tx = mock_operator_min_percentage_tx(test_case) @@ -663,7 +667,6 @@ test s8_vw_operator_withdrawal_fails_below_min_percentage() fail { operator_shares: 150, operator_min_deposit_percentage: 10, shares_to_redeem: 100, - fee_shares: 0, } let tx = mock_operator_min_percentage_tx(test_case) @@ -684,16 +687,16 @@ test s8_vw_operator_withdrawal_fails_below_min_percentage() fail { } // Operator has 10% of shares (100 of 1000), min is 10% -// Withdraws 50 shares, earns 40 fee_shares -> new: 90/990 = 9.09% < 10% ✗ -// Min percentage check FAILS (90*100 >= 10*990 -> 9000 >= 9900 is FALSE) -test s8_vw_operator_withdrawal_with_fee_still_fails_below_min() fail { +// Withdraws 50 shares -> new: 50/950 = 5.3% < 10% ✗ +// Min percentage check FAILS (50*100 >= 10*950 -> 5000 >= 9500 is FALSE) +// NOTE: Fee is skipped when operator withdraws, so no fee_shares offset +test s8_vw_operator_withdrawal_at_min_fails_below() fail { let test_case = OperatorMinPercentageTestCase { total_shares: 1000, operator_shares: 100, operator_min_deposit_percentage: 10, shares_to_redeem: 50, - fee_shares: 40, } let tx = mock_operator_min_percentage_tx(test_case) @@ -713,18 +716,16 @@ test s8_vw_operator_withdrawal_with_fee_still_fails_below_min() fail { ) } -// Operator has 10% (100 of 1000), min is 10% -// Withdraws 50, earns 50 fee_shares -> new: 100/1000 = 10% == 10% ✓ -// NOTE: Test marked `fail` because merkle/price verification not mocked. -// Min percentage check PASSES (100*100 >= 10*1000 -> 10000 >= 10000) -test s8_vw_operator_withdrawal_with_fee_maintains_exact_min() fail { +// Operator has exactly 10% (100 of 1000), min is 10% +// Cannot withdraw ANY shares without falling below minimum +// Withdraws 1 share -> new: 99/999 = 9.9% < 10% ✗ +test s8_vw_operator_at_exact_min_cannot_withdraw() fail { let test_case = OperatorMinPercentageTestCase { total_shares: 1000, operator_shares: 100, operator_min_deposit_percentage: 10, - shares_to_redeem: 50, - fee_shares: 50, + shares_to_redeem: 1, } let tx = mock_operator_min_percentage_tx(test_case) From 8ad0bb5e0a4f1a0d33319b81c834453ba7321772 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 23 Mar 2026 17:02:53 +0800 Subject: [PATCH 14/30] feat: convert decimal prices to integers with dynamic scale --- lib/hydra_dex/price_oracle_utils.ak | 23 +++++++++++++------ lib/hydra_dex/types.ak | 4 +++- lib/hydra_dex/withdraw_utils.ak | 14 ++++++++--- spec/8_hydra_account/w_vault_deposit.md | 19 ++++++++++++++- spec/8_hydra_account/w_vault_withdrawal.md | 17 +++++++++++++- .../deposit_utils/convert_m_value_to_usd.ak | 11 +++++---- .../withdraw_utils/check_output_value.ak | 13 ++++++----- 7 files changed, 77 insertions(+), 24 deletions(-) diff --git a/lib/hydra_dex/price_oracle_utils.ak b/lib/hydra_dex/price_oracle_utils.ak index 5975977..b937fd7 100644 --- a/lib/hydra_dex/price_oracle_utils.ak +++ b/lib/hydra_dex/price_oracle_utils.ak @@ -2,18 +2,24 @@ use aiken/cbor use aiken/collection/list use aiken/collection/pairs use aiken/crypto.{VerificationKey} +use aiken/math use cardano/assets.{AssetName, PolicyId, Value} use cardano/transaction.{Input} use cocktail.{verify_pub_keys, verify_signatures} use hydra_dex/types.{MValue, Message} +// Power of 10: returns 10^n +fn pow10(n: Int) -> Int { + math.pow(10, n) +} + pub fn verify_prices_oracle_messages( prices_message: ByteArray, inputs: List, hydra_signers: List, hydra_node_pub_keys: List, signatures: List, -) -> (Int, Pairs<(PolicyId, AssetName), Int>, Bool) { +) -> (Int, Pairs<(PolicyId, AssetName), (Int, Int)>, Bool) { expect Some(signed_data) = cbor.deserialise(prices_message) expect Message { vault_equity, prices, utxo_ref }: Message = signed_data @@ -33,24 +39,27 @@ pub fn verify_prices_oracle_messages( (vault_equity, prices, message_verified) } +// USD calculation: usd_value = Σ(amount * price / 10^scale) for each asset pub fn convert_value_to_usd( value: Value, - prices: Pairs<(PolicyId, AssetName), Int>, + prices: Pairs<(PolicyId, AssetName), (Int, Int)>, ) -> Int { assets.reduce( value, 0, fn(policy_id, asset_name, amount, acc) { - expect Some(price) = prices |> pairs.get_first((policy_id, asset_name)) + expect Some((price, scale)) = + prices |> pairs.get_first((policy_id, asset_name)) - acc + amount * price + acc + amount * price / pow10(scale) }, ) } +// USD calculation: usd_value = Σ(amount * price / 10^scale) for each asset pub fn convert_m_value_to_usd( m_value: MValue, - prices: Pairs<(PolicyId, AssetName), Int>, + prices: Pairs<(PolicyId, AssetName), (Int, Int)>, ) -> Int { list.foldl( m_value, @@ -60,10 +69,10 @@ pub fn convert_m_value_to_usd( policy_pair.2nd, acc, fn(asset_pair: Pair, nested_acc: Int) { - expect Some(price) = + expect Some((price, scale)) = prices |> pairs.get_first((policy_pair.1st, asset_pair.1st)) - nested_acc + price * asset_pair.2nd + nested_acc + asset_pair.2nd * price / pow10(scale) }, ) }, diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index ea96d95..e54daff 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -331,9 +331,11 @@ pub type SharesRecordEntry { } // Price oracle message +// prices: Pairs<(PolicyId, AssetName), (Int, Int)> where tuple is (price, scale) +// USD calculation: usd_value = Σ(amount * price / 10^scale) for each asset pub type Message { vault_equity: Int, - prices: Pairs<(PolicyId, AssetName), Int>, + prices: Pairs<(PolicyId, AssetName), (Int, Int)>, utxo_ref: OutputReference, } diff --git a/lib/hydra_dex/withdraw_utils.ak b/lib/hydra_dex/withdraw_utils.ak index 71d5d37..0e56ea2 100644 --- a/lib/hydra_dex/withdraw_utils.ak +++ b/lib/hydra_dex/withdraw_utils.ak @@ -1,11 +1,17 @@ use aiken/cbor use aiken/collection/pairs +use aiken/math use aiken/merkle_patricia_forestry as mpf use cardano/assets.{AssetName, PolicyId, Value} use hydra_dex/types.{ SharesInsert, SharesMPFAction, SharesRecordEntry, SharesUpdate, UserAccount, } +// Power of 10: returns 10^n +fn pow10(n: Int) -> Int { + math.pow(10, n) +} + pub fn convert_shares_to_usd( shares_amount: Int, total_shares: Int, @@ -38,18 +44,20 @@ pub fn compute_fee_shares(fee: Int, total_shares: Int, vault_equity: Int) -> Int ceil_div(fee * total_shares, vault_equity) } +// USD calculation: usd_value = Σ(amount * price / 10^scale) for each asset pub fn check_output_value_equal_to_shares_usd_value( output_value: Value, shares_usd_value: Int, - prices: Pairs<(PolicyId, AssetName), Int>, + prices: Pairs<(PolicyId, AssetName), (Int, Int)>, ) -> Bool { assets.reduce( output_value, 0, fn(policy_id, asset_name, amount, acc) { - expect Some(price) = prices |> pairs.get_first((policy_id, asset_name)) + expect Some((price, scale)) = + prices |> pairs.get_first((policy_id, asset_name)) - acc + amount * price + acc + amount * price / pow10(scale) }, ) == shares_usd_value } diff --git a/spec/8_hydra_account/w_vault_deposit.md b/spec/8_hydra_account/w_vault_deposit.md index e7829d6..62e5332 100644 --- a/spec/8_hydra_account/w_vault_deposit.md +++ b/spec/8_hydra_account/w_vault_deposit.md @@ -48,6 +48,7 @@ Supports both initial deposit (when `total_shares == 0`) and regular deposits. ## Edge Case: Operator == Depositor If the operator deposits (after previously receiving fee shares from withdrawals): + - Existing entry might be: `{ shares: fee_shares, total_deposited: 0 }` (fees don't add to deposited) - After deposit: `{ shares: fee_shares + new_shares, total_deposited: 0 + deposit_usd_value }` @@ -57,9 +58,25 @@ This is handled correctly by `SharesUpdate` which adds to both `shares` and `tot - **Intent datum** contains `deposit_amount` in **L2 format**: `MValue = Pairs>` - **Account UTxOs** contain values in **L2 format**: `(hydra_token_policy_id, hash_token(policy_id, asset_name), qty)` -- **Price message** contains prices in **L1 format**: `Pairs<(PolicyId, AssetName), Int>` +- **Price message** contains prices in **L1 format**: `Pairs<(PolicyId, AssetName), (Int, Int)>` where tuple is `(price, scale)` - **Token map** (`TokenMap`) maps L2 asset hash → L1 asset identity for price lookup - Validator converts L2 deposit amount to L1 using `from_hydra_balance_to_value(l2_value, hydra_token_policy_id, token_map)` for USD calculation +- **USD calculation**: `usd_value = Σ(amount * price / 10^scale)` for each asset + +## Price Format + +Each asset's price entry is a tuple `(price, scale)` where: + +- `price`: Integer price value +- `scale`: Exponent for power of 10 divisor (10^scale) + +| Token | Real Price | price | scale | Example Calculation | +| ----- | ---------- | ----- | ----- | -------------------------------------------- | +| USDC | $1.00 | 1 | 0 | `1000000 * 1 / 10^0 = 1000000` (1 USD) | +| ADA | $0.50 | 5 | 1 | `1000000 * 5 / 10^1 = 500000` (0.50 USD) | +| BTC | $50,000 | 50000 | 0 | `100000000 * 50000 / 10^0 = 5000000000000` | + +This allows each token to have its own scale factor (as power of 10) to prevent integer overflow in the backend while maintaining integer-only arithmetic on-chain. ## Redeemer diff --git a/spec/8_hydra_account/w_vault_withdrawal.md b/spec/8_hydra_account/w_vault_withdrawal.md index 27028fb..19c628e 100644 --- a/spec/8_hydra_account/w_vault_withdrawal.md +++ b/spec/8_hydra_account/w_vault_withdrawal.md @@ -74,10 +74,25 @@ This simplifies the transaction and reduces computation compared to the case whe ## L1 vs L2 Asset Units -- **Price message** contains prices in **L1 format**: `Pairs<(PolicyId, AssetName), Int>` +- **Price message** contains prices in **L1 format**: `Pairs<(PolicyId, AssetName), (Int, Int)>` where tuple is `(price, scale)` - **Account UTxOs** contain values in **L2 format**: `(hydra_token_policy_id, hash_token(policy_id, asset_name), qty)` - **Token map** (`TokenMap = Pairs`) maps L2 asset hash → L1 asset identity - Validator converts L2 UTxO values to L1 using `from_hydra_balance_to_value(l2_value, hydra_token_policy_id, token_map)` before price lookup +- **USD calculation**: `usd_value = Σ(amount * price / 10^scale)` for each asset + +## Price Format + +Each asset's price entry is a tuple `(price, scale)` where: +- `price`: Integer price value +- `scale`: Exponent for power of 10 divisor (10^scale) + +| Token | Real Price | price | scale | Example Calculation | +|-------|------------|-------|-------|---------------------| +| USDC | $1.00 | 1 | 0 | `1000000 * 1 / 10^0 = 1000000` (1 USD) | +| ADA | $0.50 | 5 | 1 | `1000000 * 5 / 10^1 = 500000` (0.50 USD) | +| BTC | $50,000 | 50000 | 0 | `100000000 * 50000 / 10^0 = 5000000000000` | + +This allows each token to have its own scale factor (as power of 10) to prevent integer overflow in the backend while maintaining integer-only arithmetic on-chain. ## Redeemer diff --git a/validators/tests/deposit_utils/convert_m_value_to_usd.ak b/validators/tests/deposit_utils/convert_m_value_to_usd.ak index 999754c..a6edf39 100644 --- a/validators/tests/deposit_utils/convert_m_value_to_usd.ak +++ b/validators/tests/deposit_utils/convert_m_value_to_usd.ak @@ -2,12 +2,13 @@ use cardano/assets.{AssetName, PolicyId} use hydra_dex/price_oracle_utils.{convert_m_value_to_usd} use hydra_dex/types.{MValue} -const prices: Pairs<(PolicyId, AssetName), Int> = +// prices: (price, scale) tuple - USD = amount * price / 10^scale +const prices: Pairs<(PolicyId, AssetName), (Int, Int)> = [ - Pair((#"", #""), 2), + Pair((#"", #""), (2, 0)), Pair( (#"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", #"5553444d"), - 1, + (1, 0), ), ] @@ -44,10 +45,10 @@ const m_value_c = ), ] -// m_value_a: 100 * 2 (ADA) + 100 * 1 (USDM) = 300 +// m_value_a: 100 * 2 / 10^0 (ADA) + 100 * 1 / 10^0 (USDM) = 300 const m_value_a_in_usd = 300 -// m_value_b: 200 * 2 (ADA) + 200 * 1 (USDM) = 600 +// m_value_b: 200 * 2 / 10^0 (ADA) + 200 * 1 / 10^0 (USDM) = 600 const m_value_b_in_usd = 600 test du_convert_m_value_to_usd_a() { diff --git a/validators/tests/withdraw_utils/check_output_value.ak b/validators/tests/withdraw_utils/check_output_value.ak index a56ed8c..1fecc31 100644 --- a/validators/tests/withdraw_utils/check_output_value.ak +++ b/validators/tests/withdraw_utils/check_output_value.ak @@ -5,13 +5,14 @@ const usdm_policy = #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913" const usdm_name = #"5553444d" -const prices: Pairs<(PolicyId, AssetName), Int> = - [Pair((#"", #""), 2), Pair((usdm_policy, usdm_name), 1)] +// prices: (price, scale) tuple - USD = amount * price / 10^scale +const prices: Pairs<(PolicyId, AssetName), (Int, Int)> = + [Pair((#"", #""), (2, 0)), Pair((usdm_policy, usdm_name), (1, 0))] // ========== check_output_value_equal_to_shares_usd_value tests ========== -// Output value: 1000000 USDM (price=1) + 2000000 ADA (price=2) -// USD value = 1000000 * 1 + 2000000 * 2 = 5000000 +// Output value: 1000000 USDM (price=1, scale=0) + 2000000 ADA (price=2, scale=0) +// USD value = 1000000 * 1 / 10^0 + 2000000 * 2 / 10^0 = 5000000 const output_value_a = from_asset(usdm_policy, usdm_name, 1000000) |> add(#"", #"", 2000000) @@ -26,8 +27,8 @@ test wu_check_output_value_mixed_a() { ) } -// Output value: 2000000 USDM (price=1) + 1000000 ADA (price=2) -// USD value = 2000000 * 1 + 1000000 * 2 = 4000000 +// Output value: 2000000 USDM (price=1, scale=0) + 1000000 ADA (price=2, scale=0) +// USD value = 2000000 * 1 / 10^0 + 1000000 * 2 / 10^0 = 4000000 const output_value_b = from_asset(usdm_policy, usdm_name, 2000000) |> add(#"", #"", 1000000) From 5fc231b3cdaa836c96029f8af72ef86f43d42587 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Tue, 24 Mar 2026 16:51:39 +0800 Subject: [PATCH 15/30] fix: initial deposit equity = 0 --- lib/hydra_dex/deposit_utils.ak | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/hydra_dex/deposit_utils.ak b/lib/hydra_dex/deposit_utils.ak index 2bd5e1f..aa30653 100644 --- a/lib/hydra_dex/deposit_utils.ak +++ b/lib/hydra_dex/deposit_utils.ak @@ -33,13 +33,17 @@ pub fn combine_m_value(left_m_value: MValue, right_m_value: MValue) -> MValue { |> dict.to_pairs() } +// Calculate shares to mint for a deposit +// Initial deposit (total_shares == 0): share price = 1.0, so shares = usd_value +// Subsequent deposits: shares = (usd_value * total_shares) / vault_equity (round DOWN) pub fn cal_shares_amount( usd_value: Int, vault_equity: Int, total_shares: Int, ) -> Int { - when total_shares is { - 0 -> fail @"Total shares cannot be zero" - _ -> usd_value * total_shares / vault_equity + if total_shares == 0 { + usd_value + } else { + usd_value * total_shares / vault_equity } } From 2f3f23a19f9808d377071bd10c0b2e3a9ba36a05 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 25 Mar 2026 11:03:28 +0800 Subject: [PATCH 16/30] fix: remove hydra phk check --- lib/hydra_dex/price_oracle_utils.ak | 7 ++----- validators/hydra_account/vault_deposit.ak | 1 - validators/hydra_account/vault_withdrawal.ak | 1 - 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/hydra_dex/price_oracle_utils.ak b/lib/hydra_dex/price_oracle_utils.ak index b937fd7..f84f558 100644 --- a/lib/hydra_dex/price_oracle_utils.ak +++ b/lib/hydra_dex/price_oracle_utils.ak @@ -5,7 +5,7 @@ use aiken/crypto.{VerificationKey} use aiken/math use cardano/assets.{AssetName, PolicyId, Value} use cardano/transaction.{Input} -use cocktail.{verify_pub_keys, verify_signatures} +use cocktail.{verify_signatures} use hydra_dex/types.{MValue, Message} // Power of 10: returns 10^n @@ -16,7 +16,6 @@ fn pow10(n: Int) -> Int { pub fn verify_prices_oracle_messages( prices_message: ByteArray, inputs: List, - hydra_signers: List, hydra_node_pub_keys: List, signatures: List, ) -> (Int, Pairs<(PolicyId, AssetName), (Int, Int)>, Bool) { @@ -28,13 +27,11 @@ pub fn verify_prices_oracle_messages( // Convert VerificationKey to ByteArray for cocktail functions let pub_keys_bytes = list.map(hydra_node_pub_keys, fn(vk) { vk }) - let signers_bytes = list.map(hydra_signers, fn(vk) { vk }) - let keys_check = verify_pub_keys(pub_keys_bytes, signers_bytes) let signatures_check = verify_signatures(pub_keys_bytes, prices_message, signatures) - let message_verified = is_utxo_consumed? && keys_check? && signatures_check? + let message_verified = is_utxo_consumed? && signatures_check? (vault_equity, prices, message_verified) } diff --git a/validators/hydra_account/vault_deposit.ak b/validators/hydra_account/vault_deposit.ak index d2bd919..f596bf3 100644 --- a/validators/hydra_account/vault_deposit.ak +++ b/validators/hydra_account/vault_deposit.ak @@ -96,7 +96,6 @@ pub fn vault_deposit( prices_message, inputs, hydra_node_pub_keys, - hydra_node_pub_keys, signatures, ) diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak index b4b923e..062b8db 100644 --- a/validators/hydra_account/vault_withdrawal.ak +++ b/validators/hydra_account/vault_withdrawal.ak @@ -99,7 +99,6 @@ pub fn vault_withdrawal( prices_message, inputs, hydra_node_pub_keys, - hydra_node_pub_keys, signatures, ) From 2dc64fb054c65bde5c2f42ff9b67c08637281a76 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 25 Mar 2026 16:11:41 +0800 Subject: [PATCH 17/30] chore: aiken build --- lib/hydra_dex/price_oracle_utils.ak | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/hydra_dex/price_oracle_utils.ak b/lib/hydra_dex/price_oracle_utils.ak index f84f558..548c9fd 100644 --- a/lib/hydra_dex/price_oracle_utils.ak +++ b/lib/hydra_dex/price_oracle_utils.ak @@ -25,11 +25,8 @@ pub fn verify_prices_oracle_messages( let is_utxo_consumed = list.any(inputs, fn(input) { input.output_reference == utxo_ref }) - // Convert VerificationKey to ByteArray for cocktail functions - let pub_keys_bytes = list.map(hydra_node_pub_keys, fn(vk) { vk }) - let signatures_check = - verify_signatures(pub_keys_bytes, prices_message, signatures) + verify_signatures(hydra_node_pub_keys, prices_message, signatures) let message_verified = is_utxo_consumed? && signatures_check? From 55817f76beda3bcf3ef931444755294d7b7e9fde Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 25 Mar 2026 17:01:51 +0800 Subject: [PATCH 18/30] fix: debug datum --- validators/hydra_account/vault_deposit.ak | 26 +++++++++++------ validators/hydra_account/vault_withdrawal.ak | 30 ++++++++++++++------ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/validators/hydra_account/vault_deposit.ak b/validators/hydra_account/vault_deposit.ak index f596bf3..b02f507 100644 --- a/validators/hydra_account/vault_deposit.ak +++ b/validators/hydra_account/vault_deposit.ak @@ -202,14 +202,24 @@ pub fn vault_deposit( input_operator_shares } - // Verify Vault Oracle output datum - let is_oracle_datum_updated = - output_oracle_datum == VaultOracleDatum { - ..input_oracle_datum, - total_shares: input_total_shares + shares_minted, - operator_shares: new_operator_shares, - total_deposited: input_total_deposited + deposit_usd_value, - shares_merkle_root: computed_new_root, + // Verify Vault Oracle output datum (field by field for debugging) + let is_total_shares_correct = + output_oracle_datum.total_shares == input_total_shares + shares_minted + let is_operator_shares_correct = + output_oracle_datum.operator_shares == new_operator_shares + let is_total_deposited_correct = + output_oracle_datum.total_deposited == input_total_deposited + deposit_usd_value + let is_merkle_root_correct = + output_oracle_datum.shares_merkle_root == computed_new_root + let is_other_fields_unchanged = + output_oracle_datum.app_oracle == input_oracle_datum.app_oracle && output_oracle_datum.vault_script_hash == input_oracle_datum.vault_script_hash && output_oracle_datum.l1_deposit_intent_script_hash == input_oracle_datum.l1_deposit_intent_script_hash && output_oracle_datum.l1_withdrawal_intent_script_hash == input_oracle_datum.l1_withdrawal_intent_script_hash && output_oracle_datum.l2_deposit_intent_script_hash == input_oracle_datum.l2_deposit_intent_script_hash && output_oracle_datum.l2_withdrawal_intent_script_hash == input_oracle_datum.l2_withdrawal_intent_script_hash && output_oracle_datum.pluggable_logic == input_oracle_datum.pluggable_logic && output_oracle_datum.vault_stake_rotation_script_hash == input_oracle_datum.vault_stake_rotation_script_hash && output_oracle_datum.operator_account == input_oracle_datum.operator_account && output_oracle_datum.operator_charge_percentage == input_oracle_datum.operator_charge_percentage && output_oracle_datum.operator_min_deposit_percentage == input_oracle_datum.operator_min_deposit_percentage && output_oracle_datum.hydra_node_pub_keys == input_oracle_datum.hydra_node_pub_keys && output_oracle_datum.is_active == input_oracle_datum.is_active && output_oracle_datum.total_fee_share_collected == input_oracle_datum.total_fee_share_collected + + let is_oracle_datum_updated = and { + is_total_shares_correct?, + is_operator_shares_correct?, + is_total_deposited_correct?, + is_merkle_root_correct?, + is_other_fields_unchanged?, } // 11. Verify signature (operation_key) diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak index 062b8db..60bb0a3 100644 --- a/validators/hydra_account/vault_withdrawal.ak +++ b/validators/hydra_account/vault_withdrawal.ak @@ -268,15 +268,27 @@ pub fn vault_withdrawal( True } - // Verify Vault Oracle output datum - let is_oracle_datum_updated = - output_oracle_datum == VaultOracleDatum { - ..input_oracle_datum, - total_shares: new_total_shares, - operator_shares: new_operator_shares, - total_deposited: input_total_deposited - cost_basis, - total_fee_share_collected: input_total_fee_share_collected + fee_shares, - shares_merkle_root: final_root, + // Verify Vault Oracle output datum (field by field for debugging) + let is_total_shares_correct = + output_oracle_datum.total_shares == new_total_shares + let is_operator_shares_correct = + output_oracle_datum.operator_shares == new_operator_shares + let is_total_deposited_correct = + output_oracle_datum.total_deposited == input_total_deposited - cost_basis + let is_total_fee_share_collected_correct = + output_oracle_datum.total_fee_share_collected == input_total_fee_share_collected + fee_shares + let is_merkle_root_correct = + output_oracle_datum.shares_merkle_root == final_root + let is_other_fields_unchanged = + output_oracle_datum.app_oracle == input_oracle_datum.app_oracle && output_oracle_datum.vault_script_hash == input_oracle_datum.vault_script_hash && output_oracle_datum.l1_deposit_intent_script_hash == input_oracle_datum.l1_deposit_intent_script_hash && output_oracle_datum.l1_withdrawal_intent_script_hash == input_oracle_datum.l1_withdrawal_intent_script_hash && output_oracle_datum.l2_deposit_intent_script_hash == input_oracle_datum.l2_deposit_intent_script_hash && output_oracle_datum.l2_withdrawal_intent_script_hash == input_oracle_datum.l2_withdrawal_intent_script_hash && output_oracle_datum.pluggable_logic == input_oracle_datum.pluggable_logic && output_oracle_datum.vault_stake_rotation_script_hash == input_oracle_datum.vault_stake_rotation_script_hash && output_oracle_datum.operator_account == input_oracle_datum.operator_account && output_oracle_datum.operator_charge_percentage == input_oracle_datum.operator_charge_percentage && output_oracle_datum.operator_min_deposit_percentage == input_oracle_datum.operator_min_deposit_percentage && output_oracle_datum.hydra_node_pub_keys == input_oracle_datum.hydra_node_pub_keys && output_oracle_datum.is_active == input_oracle_datum.is_active + + let is_oracle_datum_updated = and { + is_total_shares_correct?, + is_operator_shares_correct?, + is_total_deposited_correct?, + is_total_fee_share_collected_correct?, + is_merkle_root_correct?, + is_other_fields_unchanged?, } // 12. Verify signature (operation_key OR operator's master_key) From 41e3e4cbf9a94f52e950737ced32a6b03af6c4ff Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 25 Mar 2026 17:46:48 +0800 Subject: [PATCH 19/30] chore: add trace --- validators/hydra_account/vault_deposit.ak | 2 ++ 1 file changed, 2 insertions(+) diff --git a/validators/hydra_account/vault_deposit.ak b/validators/hydra_account/vault_deposit.ak index b02f507..197ec8a 100644 --- a/validators/hydra_account/vault_deposit.ak +++ b/validators/hydra_account/vault_deposit.ak @@ -160,6 +160,7 @@ pub fn vault_deposit( // 9. Verify Merkle root transition let mpf_key = cbor.serialise(depositor) + trace @"mpf_key": mpf_key let computed_new_root = when mpf_action is { SharesInsert { proof } -> { @@ -170,6 +171,7 @@ pub fn vault_deposit( total_deposited: deposit_usd_value, } let new_value = cbor.serialise(new_entry) + trace @"new_value": new_value let trie = mpf.from_root(input_merkle_root) let new_trie = mpf.insert(trie, mpf_key, new_value, proof) mpf.root(new_trie) From 6d3a258c194f47d1215f917121302af319f1b986 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 26 Mar 2026 11:14:03 +0800 Subject: [PATCH 20/30] fix: operator withdrawal mpf type --- lib/hydra_dex/types.ak | 2 +- spec/8_hydra_account/w_vault_withdrawal.md | 5 ++++- validators/hydra_account/vault_withdrawal.ak | 5 +++-- .../tests/hydra_account/vault_withdrawal.ak | 20 +++++++++---------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index e54daff..9dd6b33 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -255,7 +255,7 @@ pub type HydraAccountOperation { List, TokenMap, SharesMPFAction, - SharesMPFAction, + Option, ) } diff --git a/spec/8_hydra_account/w_vault_withdrawal.md b/spec/8_hydra_account/w_vault_withdrawal.md index 19c628e..5fc2641 100644 --- a/spec/8_hydra_account/w_vault_withdrawal.md +++ b/spec/8_hydra_account/w_vault_withdrawal.md @@ -102,6 +102,9 @@ ProcessVaultWithdrawal( signatures: List, token_map: TokenMap, mpf_action: SharesMPFAction, - operator_mpf_action: SharesMPFAction, + operator_mpf_action: Option, ) ``` + +- `operator_mpf_action` is `Some(action)` when `fee_shares > 0` (non-operator withdrawal with profit) +- `operator_mpf_action` is `None` when `fee_shares == 0` (operator withdrawal or no profit) diff --git a/validators/hydra_account/vault_withdrawal.ak b/validators/hydra_account/vault_withdrawal.ak index 60bb0a3..4b6e007 100644 --- a/validators/hydra_account/vault_withdrawal.ak +++ b/validators/hydra_account/vault_withdrawal.ak @@ -32,7 +32,7 @@ pub fn vault_withdrawal( signatures: List, token_map: TokenMap, mpf_action: SharesMPFAction, - operator_mpf_action: SharesMPFAction, + operator_mpf_action: Option, tx: Transaction, ) -> Bool { let Transaction { @@ -235,11 +235,12 @@ pub fn vault_withdrawal( // When operator withdraws, fee_shares is 0, so no operator MPF action needed let final_root = if fee_shares > 0 { + expect Some(action) = operator_mpf_action apply_operator_fee_share( new_user_root, fee_shares, operator_account, - operator_mpf_action, + action, ) } else { new_user_root diff --git a/validators/tests/hydra_account/vault_withdrawal.ak b/validators/tests/hydra_account/vault_withdrawal.ak index 24e4390..6459a1f 100644 --- a/validators/tests/hydra_account/vault_withdrawal.ak +++ b/validators/tests/hydra_account/vault_withdrawal.ak @@ -282,7 +282,7 @@ test s8_vw_failed_without_any_signature() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + Some(SharesInsert { proof: [] }), ), Script(""), tx, @@ -311,7 +311,7 @@ test s8_vw_failed_without_withdrawer_balance_increased() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + Some(SharesInsert { proof: [] }), ), Script(""), tx, @@ -340,7 +340,7 @@ test s8_vw_failed_without_vault_balance_deducted() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + Some(SharesInsert { proof: [] }), ), Script(""), tx, @@ -369,7 +369,7 @@ test s8_vw_failed_without_intent_token_burnt() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + Some(SharesInsert { proof: [] }), ), Script(""), tx, @@ -398,7 +398,7 @@ test s8_vw_failed_with_other_account_input() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + Some(SharesInsert { proof: [] }), ), Script(""), tx, @@ -427,7 +427,7 @@ test s8_vw_failed_with_other_account_output() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + Some(SharesInsert { proof: [] }), ), Script(""), tx, @@ -650,7 +650,7 @@ test s8_vw_operator_withdrawal_respects_min_percentage() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + None, ), Script(""), tx, @@ -679,7 +679,7 @@ test s8_vw_operator_withdrawal_fails_below_min_percentage() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + None, ), Script(""), tx, @@ -709,7 +709,7 @@ test s8_vw_operator_withdrawal_at_min_fails_below() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + None, ), Script(""), tx, @@ -738,7 +738,7 @@ test s8_vw_operator_at_exact_min_cannot_withdraw() fail { [], mock_token_map, SharesDelete { proof: [], old_value: #"" }, - SharesInsert { proof: [] }, + None, ), Script(""), tx, From 329910c7ab6aed047dd7da9355d616232a7408bb Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 26 Mar 2026 11:14:16 +0800 Subject: [PATCH 21/30] chore: merkle test --- .../deposit_utils/compute_merkle_root.ak | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 validators/tests/deposit_utils/compute_merkle_root.ak diff --git a/validators/tests/deposit_utils/compute_merkle_root.ak b/validators/tests/deposit_utils/compute_merkle_root.ak new file mode 100644 index 0000000..1523072 --- /dev/null +++ b/validators/tests/deposit_utils/compute_merkle_root.ak @@ -0,0 +1,166 @@ +use aiken/cbor +use aiken/merkle_patricia_forestry as mpf +use cardano/address.{VerificationKey} +use hydra_dex/types.{Account, SharesRecordEntry, UserTradeAccount} + +// ========== compute_merkle_root tests ========== +// Test the merkle root computation for vault deposits + +// Depositor account from actual CBOR: +// accountId: bddac449efee4ba2b8303762835f04aa +// masterKey: fdeb4bf0e8c077114a4553f1e05395e9fb7114db177f02f7b65c8de4 (Script) +// operationKey: b21f857716821354725bc2bd255dc2e5d5fdfa202556039b76c080a5 (VerificationKey) +// accountType: spot_account (UserTradeAccount) +// trading_logic: 130a4c436f91d5cb0f0ddfccac88d656d4301383c7b1cd8ae7f79e27 + +const test_account_id = #"bddac449efee4ba2b8303762835f04aa" + +const test_master_key = + #"fdeb4bf0e8c077114a4553f1e05395e9fb7114db177f02f7b65c8de4" + +const test_operation_key = + #"b21f857716821354725bc2bd255dc2e5d5fdfa202556039b76c080a5" + +const test_trading_logic = + #"130a4c436f91d5cb0f0ddfccac88d656d4301383c7b1cd8ae7f79e27" + +fn test_depositor() { + UserTradeAccount { + account: Account { + account_id: test_account_id, + master_key: VerificationKey(test_master_key), + operation_key: VerificationKey(test_operation_key), + }, + trading_logic: test_trading_logic, + } +} + +// Test: Verify CBOR serialization of the depositor (MPF key) +test du_compute_merkle_key_serialization() { + let depositor = test_depositor() + let mpf_key = cbor.serialise(depositor) + // Trace the key to see its value + trace @"mpf_key": mpf_key + True +} + +// Test: Verify CBOR serialization of SharesRecordEntry (MPF value) +test du_compute_merkle_value_serialization() { + let shares_minted = 10000000 + let deposit_usd_value = 10000000 + let new_entry = + SharesRecordEntry { + shares: shares_minted, + total_deposited: deposit_usd_value, + } + let new_value = cbor.serialise(new_entry) + // Trace the value to see its serialization + trace @"new_value": new_value + True +} + +// Test: Full merkle root computation for empty trie insert +test du_compute_merkle_root_empty_trie_insert() { + let depositor = test_depositor() + let mpf_key = cbor.serialise(depositor) + + let shares_minted = 10000000 + let deposit_usd_value = 10000000 + let new_entry = + SharesRecordEntry { + shares: shares_minted, + total_deposited: deposit_usd_value, + } + let new_value = cbor.serialise(new_entry) + + // Empty trie - use mpf.empty instead of empty bytearray + let trie = mpf.empty + let proof = [] + + let new_trie = mpf.insert(trie, mpf_key, new_value, proof) + let computed_root = mpf.root(new_trie) + + // Expected from offchain: 40748f1aaa42a65ef33de830179ec943642eae818fa93d3424c92a95946f0256 + let expected_root = + #"fdc0305f2f749e8d69f069fabf3e09b1432e310373ab037e3330702176011580" + + trace @"mpf_key": mpf_key + trace @"new_value": new_value + trace @"computed_root": computed_root + trace @"expected_root": expected_root + + computed_root == expected_root +} + +// Test: Just compute and trace the root (always passes) +test du_compute_merkle_root_trace_only() { + let depositor = test_depositor() + let mpf_key = cbor.serialise(depositor) + + let shares_minted = 10000000 + let deposit_usd_value = 10000000 + let new_entry = + SharesRecordEntry { + shares: shares_minted, + total_deposited: deposit_usd_value, + } + let new_value = cbor.serialise(new_entry) + + // Empty trie - use mpf.empty instead of empty bytearray + let trie = mpf.empty + let proof = [] + + let new_trie = mpf.insert(trie, mpf_key, new_value, proof) + let computed_root = mpf.root(new_trie) + + // Also trace the empty root for reference + let empty_root = mpf.root(mpf.empty) + + // Trace individual components for debugging + let account = + Account { + account_id: test_account_id, + master_key: VerificationKey(test_master_key), + operation_key: VerificationKey(test_operation_key), + } + let account_cbor = cbor.serialise(account) + + trace @"===== MPF Debug =====" + trace @"empty_root": empty_root + trace @"account_id": test_account_id + trace @"master_key (VerificationKey)": test_master_key + trace @"operation_key (VK)": test_operation_key + trace @"trading_logic": test_trading_logic + trace @"account_cbor": account_cbor + trace @"mpf_key (full UserAccount)": mpf_key + trace @"shares_minted": shares_minted + trace @"deposit_usd_value": deposit_usd_value + trace @"new_value (SharesRecordEntry)": new_value + trace @"computed_root": computed_root + True +} + +// Test: Trace Account CBOR separately +test du_trace_account_serialization() { + let account = + Account { + account_id: test_account_id, + master_key: VerificationKey(test_master_key), + operation_key: VerificationKey(test_operation_key), + } + let account_cbor = cbor.serialise(account) + + trace @"===== Account CBOR =====" + trace @"account_cbor": account_cbor + True +} + +// Test: Trace SharesRecordEntry CBOR +test du_trace_shares_entry_serialization() { + let entry = SharesRecordEntry { shares: 10000000, total_deposited: 10000000 } + let entry_cbor = cbor.serialise(entry) + + trace @"===== SharesRecordEntry CBOR =====" + trace @"entry_cbor": entry_cbor + True +} From 84346ca11c74eec4882452554d797f9e5d87473f Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Fri, 27 Mar 2026 15:10:01 +0800 Subject: [PATCH 22/30] fix: remove migration in account --- validators/hydra_account/migration.ak | 108 ---------- .../deposit_utils/compute_merkle_root.ak | 22 +++ validators/tests/hydra_account/migration.ak | 187 ------------------ 3 files changed, 22 insertions(+), 295 deletions(-) delete mode 100644 validators/hydra_account/migration.ak delete mode 100644 validators/tests/hydra_account/migration.ak diff --git a/validators/hydra_account/migration.ak b/validators/hydra_account/migration.ak deleted file mode 100644 index d73642b..0000000 --- a/validators/hydra_account/migration.ak +++ /dev/null @@ -1,108 +0,0 @@ -use aiken/collection/list -use cardano/address.{Credential, Script, from_script} -use cardano/assets.{PolicyId, without_lovelace} -use cardano/transaction.{Input, Output, Transaction} -use cocktail.{ - group_inputs, group_outputs, input_inline_datum, key_signed, - output_inline_datum, -} -use cocktail/vodka_value.{inputs_value, outputs_value} -use hydra_dex/types.{ - DexOrderBookDatum, UserAccount, UserFundingAccount, UserMobileAccount, - UserTradeAccount, -} -use hydra_dex/utils.{get_dex_order_book_datum} - -pub fn migration( - oracle_nft: PolicyId, - account: UserAccount, - credential: Credential, - tx: Transaction, -) -> Bool { - let Transaction { inputs, outputs, reference_inputs, extra_signatories, .. } = - tx - - // - Ref input with `oracle_nft` - let DexOrderBookDatum { - operation_key, - hydra_account_script_hash, - hydra_order_book_script_hash, - .. - }: DexOrderBookDatum = - reference_inputs |> get_dex_order_book_datum(oracle_nft) - - // - Old script hash from own credential (this withdrawal script) - expect Script(old_script_hash) = credential - let old_account_address = from_script(old_script_hash) - - // - New script hash from oracle - let new_account_address = from_script(hydra_account_script_hash) - - // - Categorize inputs into - // - `AI` - Account Inputs at old script hash with matching `account` datum - // - Other inputs - let ai_filter = - fn(input: Input) { - if input.output.address == old_account_address { - expect input_datum: UserAccount = input_inline_datum(input) - input_datum == account - } else { - False - } - } - let (account_inputs, other_inputs) = inputs |> group_inputs(ai_filter) - - // - Categorize outputs into - // - `AO` - Account Outputs at new `hydra_account_script_hash` - // - Other outputs - let migrated_account = migrate_account(account, hydra_order_book_script_hash) - let ao_filter = - fn(output: Output) { - if output.address == new_account_address { - expect output_datum: UserAccount = output_inline_datum(output) - output_datum == migrated_account - } else { - False - } - } - let (account_outputs, _other_outputs) = outputs |> group_outputs(ao_filter) - - // - No other inputs at old script hash (single account per tx) - let no_other_old_script_inputs = - other_inputs - |> list.all(fn(input) { input.output.address != old_account_address }) - - // - No inputs at new `hydra_account_script_hash` (prevent mixing with normal operations) - let no_new_script_inputs = - inputs - |> list.all(fn(input) { input.output.address != new_account_address }) - - // - Total value preserved - let ai_value = inputs_value(account_inputs) |> without_lovelace() - let ao_value = outputs_value(account_outputs) |> without_lovelace() - let is_value_preserved = ai_value == ao_value - - // - Signed by `operation_key` - let is_authorized = key_signed(extra_signatories, operation_key) - - and { - no_other_old_script_inputs?, - no_new_script_inputs?, - is_value_preserved?, - is_authorized?, - } -} - -fn migrate_account( - account: UserAccount, - new_trading_logic: ByteArray, -) -> UserAccount { - when account is { - UserTradeAccount { account, .. } -> - UserTradeAccount { account, trading_logic: new_trading_logic } - UserFundingAccount { account, .. } -> - UserFundingAccount { account, trading_logic: new_trading_logic } - UserMobileAccount { account, .. } -> - UserMobileAccount { account, trading_logic: new_trading_logic } - } -} diff --git a/validators/tests/deposit_utils/compute_merkle_root.ak b/validators/tests/deposit_utils/compute_merkle_root.ak index 1523072..f2dd9e9 100644 --- a/validators/tests/deposit_utils/compute_merkle_root.ak +++ b/validators/tests/deposit_utils/compute_merkle_root.ak @@ -164,3 +164,25 @@ test du_trace_shares_entry_serialization() { trace @"entry_cbor": entry_cbor True } + +// ========== cost_basis calculation tests ========== +// Formula: cost_basis = old_entry.total_deposited * shares_to_redeem / old_entry.shares + +test du_cost_basis_calculation() { + let old_entry_total_deposited = 2999999500 + let shares_to_redeem = 500 + let old_entry_shares = 2909090381 + + // cost_basis = 2999999500 * 500 / 2909090381 + // = 1499999750000 / 2909090381 + // = 515 (integer division, rounds down) + let cost_basis = old_entry_total_deposited * shares_to_redeem / old_entry_shares + + trace @"===== Cost Basis Calculation =====" + trace @"old_entry.total_deposited": old_entry_total_deposited + trace @"shares_to_redeem": shares_to_redeem + trace @"old_entry.shares": old_entry_shares + trace @"cost_basis": cost_basis + + cost_basis == 515 +} diff --git a/validators/tests/hydra_account/migration.ak b/validators/tests/hydra_account/migration.ak deleted file mode 100644 index 454c6e4..0000000 --- a/validators/tests/hydra_account/migration.ak +++ /dev/null @@ -1,187 +0,0 @@ -use cardano/address.{Script} -use cardano/assets.{from_asset} -use cardano/transaction.{Transaction} -use hydra_account/core as ha -use hydra_dex/types.{ProcessMigration} -use mocktail.{ - complete, mock_tx_hash, mocktail_tx, ref_tx_in, ref_tx_in_inline_datum, - required_signer_hash, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, -} -use tests/utils.{ - mock_account, mock_account_2, mock_dex_order_book_address, - mock_dex_order_book_token, mock_hydra_account, mock_hydra_account_address, - mock_hydra_lovelace, mock_migrated_user_account, - mock_migration_dex_order_book_datum, mock_new_hydra_account_address, - mock_operation_key, mock_user_account, -} - -type MigrationTestCase { - is_operation_key_signed: Bool, - is_datum_migrated: Bool, - is_value_preserved: Bool, - is_no_other_old_script_inputs: Bool, - is_no_new_script_inputs: Bool, -} - -fn mock_migration_tx(test_case: MigrationTestCase) -> Transaction { - let MigrationTestCase { - is_operation_key_signed, - is_datum_migrated, - is_value_preserved, - is_no_other_old_script_inputs, - is_no_new_script_inputs, - } = test_case - - let input_value = mock_hydra_lovelace(1_000_000_000) - let output_value = - if is_value_preserved { - mock_hydra_lovelace(1_000_000_000) - } else { - mock_hydra_lovelace(500_000_000) - } - - let output_datum = - if is_datum_migrated { - mock_migrated_user_account(mock_account) - } else { - mock_user_account(mock_account) - } - - mocktail_tx() - |> ref_tx_in( - True, - mock_tx_hash(1), - 0, - from_asset(mock_dex_order_book_token, "", 1), - mock_dex_order_book_address, - ) - |> ref_tx_in_inline_datum(True, mock_migration_dex_order_book_datum) - |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_hydra_account_address) - |> tx_in_inline_datum(True, mock_user_account(mock_account)) - |> tx_in( - !is_no_other_old_script_inputs, - mock_tx_hash(0), - 1, - mock_hydra_lovelace(500_000_000), - mock_hydra_account_address, - ) - |> tx_in_inline_datum( - !is_no_other_old_script_inputs, - mock_user_account(mock_account_2), - ) - |> tx_in( - !is_no_new_script_inputs, - mock_tx_hash(0), - 2, - mock_hydra_lovelace(500_000_000), - mock_new_hydra_account_address, - ) - |> tx_in_inline_datum( - !is_no_new_script_inputs, - mock_migrated_user_account(mock_account_2), - ) - |> tx_out(True, mock_new_hydra_account_address, output_value) - |> tx_out_inline_datum(True, output_datum) - |> required_signer_hash(is_operation_key_signed, mock_operation_key) - |> complete() -} - -fn default_test_case() -> MigrationTestCase { - MigrationTestCase { - is_operation_key_signed: True, - is_datum_migrated: True, - is_value_preserved: True, - is_no_other_old_script_inputs: True, - is_no_new_script_inputs: True, - } -} - -test s8_wm_success() { - let tx = mock_migration_tx(default_test_case()) - - ha.hydra_account.withdraw( - mock_dex_order_book_token, - ProcessMigration { account: mock_user_account(mock_account) }, - Script(mock_hydra_account), - tx, - ) -} - -test s8_wm_failed_without_operation_key_signed() { - let tx = - mock_migration_tx( - MigrationTestCase { - ..default_test_case(), - is_operation_key_signed: False, - }, - ) - - !ha.hydra_account.withdraw( - mock_dex_order_book_token, - ProcessMigration { account: mock_user_account(mock_account) }, - Script(mock_hydra_account), - tx, - ) -} - -test s8_wm_failed_without_datum_migrated() { - let tx = - mock_migration_tx( - MigrationTestCase { ..default_test_case(), is_datum_migrated: False }, - ) - - !ha.hydra_account.withdraw( - mock_dex_order_book_token, - ProcessMigration { account: mock_user_account(mock_account) }, - Script(mock_hydra_account), - tx, - ) -} - -test s8_wm_failed_without_value_preserved() { - let tx = - mock_migration_tx( - MigrationTestCase { ..default_test_case(), is_value_preserved: False }, - ) - - !ha.hydra_account.withdraw( - mock_dex_order_book_token, - ProcessMigration { account: mock_user_account(mock_account) }, - Script(mock_hydra_account), - tx, - ) -} - -test s8_wm_failed_with_other_old_script_inputs() { - let tx = - mock_migration_tx( - MigrationTestCase { - ..default_test_case(), - is_no_other_old_script_inputs: False, - }, - ) - - !ha.hydra_account.withdraw( - mock_dex_order_book_token, - ProcessMigration { account: mock_user_account(mock_account) }, - Script(mock_hydra_account), - tx, - ) -} - -test s8_wm_failed_with_new_script_inputs() { - let tx = - mock_migration_tx( - MigrationTestCase { - ..default_test_case(), - is_no_new_script_inputs: False, - }, - ) - - !ha.hydra_account.withdraw( - mock_dex_order_book_token, - ProcessMigration { account: mock_user_account(mock_account) }, - Script(mock_hydra_account), - tx, - ) -} From 9cd10748706b6d1b71495374975889c99bfa8e61 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Fri, 27 Mar 2026 15:29:32 +0800 Subject: [PATCH 23/30] Revert "fix: remove migration in account" This reverts commit 4b5f906741fbf6a78ae69d683fecc347a0297a27. --- validators/hydra_account/migration.ak | 108 ++++++++++ .../deposit_utils/compute_merkle_root.ak | 22 --- validators/tests/hydra_account/migration.ak | 187 ++++++++++++++++++ 3 files changed, 295 insertions(+), 22 deletions(-) create mode 100644 validators/hydra_account/migration.ak create mode 100644 validators/tests/hydra_account/migration.ak diff --git a/validators/hydra_account/migration.ak b/validators/hydra_account/migration.ak new file mode 100644 index 0000000..d73642b --- /dev/null +++ b/validators/hydra_account/migration.ak @@ -0,0 +1,108 @@ +use aiken/collection/list +use cardano/address.{Credential, Script, from_script} +use cardano/assets.{PolicyId, without_lovelace} +use cardano/transaction.{Input, Output, Transaction} +use cocktail.{ + group_inputs, group_outputs, input_inline_datum, key_signed, + output_inline_datum, +} +use cocktail/vodka_value.{inputs_value, outputs_value} +use hydra_dex/types.{ + DexOrderBookDatum, UserAccount, UserFundingAccount, UserMobileAccount, + UserTradeAccount, +} +use hydra_dex/utils.{get_dex_order_book_datum} + +pub fn migration( + oracle_nft: PolicyId, + account: UserAccount, + credential: Credential, + tx: Transaction, +) -> Bool { + let Transaction { inputs, outputs, reference_inputs, extra_signatories, .. } = + tx + + // - Ref input with `oracle_nft` + let DexOrderBookDatum { + operation_key, + hydra_account_script_hash, + hydra_order_book_script_hash, + .. + }: DexOrderBookDatum = + reference_inputs |> get_dex_order_book_datum(oracle_nft) + + // - Old script hash from own credential (this withdrawal script) + expect Script(old_script_hash) = credential + let old_account_address = from_script(old_script_hash) + + // - New script hash from oracle + let new_account_address = from_script(hydra_account_script_hash) + + // - Categorize inputs into + // - `AI` - Account Inputs at old script hash with matching `account` datum + // - Other inputs + let ai_filter = + fn(input: Input) { + if input.output.address == old_account_address { + expect input_datum: UserAccount = input_inline_datum(input) + input_datum == account + } else { + False + } + } + let (account_inputs, other_inputs) = inputs |> group_inputs(ai_filter) + + // - Categorize outputs into + // - `AO` - Account Outputs at new `hydra_account_script_hash` + // - Other outputs + let migrated_account = migrate_account(account, hydra_order_book_script_hash) + let ao_filter = + fn(output: Output) { + if output.address == new_account_address { + expect output_datum: UserAccount = output_inline_datum(output) + output_datum == migrated_account + } else { + False + } + } + let (account_outputs, _other_outputs) = outputs |> group_outputs(ao_filter) + + // - No other inputs at old script hash (single account per tx) + let no_other_old_script_inputs = + other_inputs + |> list.all(fn(input) { input.output.address != old_account_address }) + + // - No inputs at new `hydra_account_script_hash` (prevent mixing with normal operations) + let no_new_script_inputs = + inputs + |> list.all(fn(input) { input.output.address != new_account_address }) + + // - Total value preserved + let ai_value = inputs_value(account_inputs) |> without_lovelace() + let ao_value = outputs_value(account_outputs) |> without_lovelace() + let is_value_preserved = ai_value == ao_value + + // - Signed by `operation_key` + let is_authorized = key_signed(extra_signatories, operation_key) + + and { + no_other_old_script_inputs?, + no_new_script_inputs?, + is_value_preserved?, + is_authorized?, + } +} + +fn migrate_account( + account: UserAccount, + new_trading_logic: ByteArray, +) -> UserAccount { + when account is { + UserTradeAccount { account, .. } -> + UserTradeAccount { account, trading_logic: new_trading_logic } + UserFundingAccount { account, .. } -> + UserFundingAccount { account, trading_logic: new_trading_logic } + UserMobileAccount { account, .. } -> + UserMobileAccount { account, trading_logic: new_trading_logic } + } +} diff --git a/validators/tests/deposit_utils/compute_merkle_root.ak b/validators/tests/deposit_utils/compute_merkle_root.ak index f2dd9e9..1523072 100644 --- a/validators/tests/deposit_utils/compute_merkle_root.ak +++ b/validators/tests/deposit_utils/compute_merkle_root.ak @@ -164,25 +164,3 @@ test du_trace_shares_entry_serialization() { trace @"entry_cbor": entry_cbor True } - -// ========== cost_basis calculation tests ========== -// Formula: cost_basis = old_entry.total_deposited * shares_to_redeem / old_entry.shares - -test du_cost_basis_calculation() { - let old_entry_total_deposited = 2999999500 - let shares_to_redeem = 500 - let old_entry_shares = 2909090381 - - // cost_basis = 2999999500 * 500 / 2909090381 - // = 1499999750000 / 2909090381 - // = 515 (integer division, rounds down) - let cost_basis = old_entry_total_deposited * shares_to_redeem / old_entry_shares - - trace @"===== Cost Basis Calculation =====" - trace @"old_entry.total_deposited": old_entry_total_deposited - trace @"shares_to_redeem": shares_to_redeem - trace @"old_entry.shares": old_entry_shares - trace @"cost_basis": cost_basis - - cost_basis == 515 -} diff --git a/validators/tests/hydra_account/migration.ak b/validators/tests/hydra_account/migration.ak new file mode 100644 index 0000000..454c6e4 --- /dev/null +++ b/validators/tests/hydra_account/migration.ak @@ -0,0 +1,187 @@ +use cardano/address.{Script} +use cardano/assets.{from_asset} +use cardano/transaction.{Transaction} +use hydra_account/core as ha +use hydra_dex/types.{ProcessMigration} +use mocktail.{ + complete, mock_tx_hash, mocktail_tx, ref_tx_in, ref_tx_in_inline_datum, + required_signer_hash, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use tests/utils.{ + mock_account, mock_account_2, mock_dex_order_book_address, + mock_dex_order_book_token, mock_hydra_account, mock_hydra_account_address, + mock_hydra_lovelace, mock_migrated_user_account, + mock_migration_dex_order_book_datum, mock_new_hydra_account_address, + mock_operation_key, mock_user_account, +} + +type MigrationTestCase { + is_operation_key_signed: Bool, + is_datum_migrated: Bool, + is_value_preserved: Bool, + is_no_other_old_script_inputs: Bool, + is_no_new_script_inputs: Bool, +} + +fn mock_migration_tx(test_case: MigrationTestCase) -> Transaction { + let MigrationTestCase { + is_operation_key_signed, + is_datum_migrated, + is_value_preserved, + is_no_other_old_script_inputs, + is_no_new_script_inputs, + } = test_case + + let input_value = mock_hydra_lovelace(1_000_000_000) + let output_value = + if is_value_preserved { + mock_hydra_lovelace(1_000_000_000) + } else { + mock_hydra_lovelace(500_000_000) + } + + let output_datum = + if is_datum_migrated { + mock_migrated_user_account(mock_account) + } else { + mock_user_account(mock_account) + } + + mocktail_tx() + |> ref_tx_in( + True, + mock_tx_hash(1), + 0, + from_asset(mock_dex_order_book_token, "", 1), + mock_dex_order_book_address, + ) + |> ref_tx_in_inline_datum(True, mock_migration_dex_order_book_datum) + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_hydra_account_address) + |> tx_in_inline_datum(True, mock_user_account(mock_account)) + |> tx_in( + !is_no_other_old_script_inputs, + mock_tx_hash(0), + 1, + mock_hydra_lovelace(500_000_000), + mock_hydra_account_address, + ) + |> tx_in_inline_datum( + !is_no_other_old_script_inputs, + mock_user_account(mock_account_2), + ) + |> tx_in( + !is_no_new_script_inputs, + mock_tx_hash(0), + 2, + mock_hydra_lovelace(500_000_000), + mock_new_hydra_account_address, + ) + |> tx_in_inline_datum( + !is_no_new_script_inputs, + mock_migrated_user_account(mock_account_2), + ) + |> tx_out(True, mock_new_hydra_account_address, output_value) + |> tx_out_inline_datum(True, output_datum) + |> required_signer_hash(is_operation_key_signed, mock_operation_key) + |> complete() +} + +fn default_test_case() -> MigrationTestCase { + MigrationTestCase { + is_operation_key_signed: True, + is_datum_migrated: True, + is_value_preserved: True, + is_no_other_old_script_inputs: True, + is_no_new_script_inputs: True, + } +} + +test s8_wm_success() { + let tx = mock_migration_tx(default_test_case()) + + ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_without_operation_key_signed() { + let tx = + mock_migration_tx( + MigrationTestCase { + ..default_test_case(), + is_operation_key_signed: False, + }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_without_datum_migrated() { + let tx = + mock_migration_tx( + MigrationTestCase { ..default_test_case(), is_datum_migrated: False }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_without_value_preserved() { + let tx = + mock_migration_tx( + MigrationTestCase { ..default_test_case(), is_value_preserved: False }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_with_other_old_script_inputs() { + let tx = + mock_migration_tx( + MigrationTestCase { + ..default_test_case(), + is_no_other_old_script_inputs: False, + }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} + +test s8_wm_failed_with_new_script_inputs() { + let tx = + mock_migration_tx( + MigrationTestCase { + ..default_test_case(), + is_no_new_script_inputs: False, + }, + ) + + !ha.hydra_account.withdraw( + mock_dex_order_book_token, + ProcessMigration { account: mock_user_account(mock_account) }, + Script(mock_hydra_account), + tx, + ) +} From f880c77ea72ba020dc06bb89021bcadf27bab042 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 1 Apr 2026 11:10:33 +0800 Subject: [PATCH 24/30] fix: missing merkle and message test --- docs/aiken-mpf-fixture-guide.md | 192 +++++++++++-- validators/tests/alice_bob/merkle_proofs.ak | 303 ++++++++++++++++++++ validators/tests/alice_bob/price_message.ak | 168 +++++++++++ 3 files changed, 635 insertions(+), 28 deletions(-) create mode 100644 validators/tests/alice_bob/merkle_proofs.ak create mode 100644 validators/tests/alice_bob/price_message.ak diff --git a/docs/aiken-mpf-fixture-guide.md b/docs/aiken-mpf-fixture-guide.md index c3b2a75..ed42794 100644 --- a/docs/aiken-mpf-fixture-guide.md +++ b/docs/aiken-mpf-fixture-guide.md @@ -18,6 +18,7 @@ npm install @anastasia-labs/cardano-merkle-patricia-forestry ### 1. MPF Tree Structure MPF trees store key-value pairs where: + - **Key**: A ByteArray (e.g., `order_id`, `account_id`) - **Value**: CBOR-serialized data - **Path**: `blake2b_256(key)` - determines position in tree @@ -27,19 +28,25 @@ MPF trees store key-value pairs where: Aiken and TypeScript serialize data differently. Here's how to match Aiken's format: -| Aiken Type | Aiken CBOR | TypeScript Equivalent | -|------------|------------|----------------------| -| Tuple `(a, b)` | Indefinite array `9f...ff` | `{ list: [a, b] }` | -| Bool `False` | `d87980` (conStr0) | `conStr0([])` | -| Bool `True` | `d87a80` (conStr1) | `conStr1([])` | -| Integer | Direct encoding | `{ int: value }` | -| ByteArray | Direct encoding | `byteString(hex)` | -| Constructor | `d879xx` / `d87axx` | `conStr0([...])` / `conStr1([...])` | +| Aiken Type | Aiken CBOR | TypeScript Equivalent | +| -------------- | -------------------------- | ----------------------------------- | +| Tuple `(a, b)` | Indefinite array `9f...ff` | `{ list: [a, b] }` | +| Bool `False` | `d87980` (conStr0) | `conStr0([])` | +| Bool `True` | `d87a80` (conStr1) | `conStr1([])` | +| Integer | Direct encoding | `{ int: value }` | +| ByteArray | Direct encoding | `byteString(hex)` | +| Constructor | `d879xx` / `d87axx` | `conStr0([...])` / `conStr1([...])` | ## TypeScript Helper Functions ```typescript -import { Cbor, CborBytes, CborArray, CborUInt, CborTag } from "@harmoniclabs/cbor"; +import { + Cbor, + CborBytes, + CborArray, + CborUInt, + CborTag, +} from "@harmoniclabs/cbor"; import * as crypto from "crypto"; // Helper to create ByteString @@ -129,17 +136,17 @@ For order merkle trees, the value is `MerklizedOrderDatum`, not just `Order`: const mvalue = { map: [ { - k: byteString(""), // policy_id (empty for ADA) + k: byteString(""), // policy_id (empty for ADA) v: { map: [ { - k: byteString(""), // asset_name (empty for lovelace) - v: { int: BigInt(250000000) } // amount - } - ] - } - } - ] + k: byteString(""), // asset_name (empty for lovelace) + v: { int: BigInt(250000000) }, // amount + }, + ], + }, + }, + ], }; // MerklizedOrderDatum = conStr0([order, mvalue]) @@ -152,7 +159,9 @@ const value = Cbor.encode(merklizedOrderDatum); ```typescript import { Trie } from "@anastasia-labs/cardano-merkle-patricia-forestry"; -async function computeRootHash(keyValuePairs: Array<{ key: Buffer; value: Buffer }>) { +async function computeRootHash( + keyValuePairs: Array<{ key: Buffer; value: Buffer }>, +) { let trie = new Trie(); for (const { key, value } of keyValuePairs) { @@ -173,12 +182,20 @@ console.log("Root hash:", rootHash); ## Generating MPF Proofs ```typescript -async function generateInsertProof(existingTrie: Trie, key: Buffer, value: Buffer) { +async function generateInsertProof( + existingTrie: Trie, + key: Buffer, + value: Buffer, +) { const proof = await existingTrie.insert(key, value); - return proof.proof; // Array of proof steps + return proof.proof; // Array of proof steps } -async function generateDeleteProof(existingTrie: Trie, key: Buffer, value: Buffer) { +async function generateDeleteProof( + existingTrie: Trie, + key: Buffer, + value: Buffer, +) { const proof = await existingTrie.delete(key, value); return proof.proof; } @@ -192,6 +209,7 @@ async function generateDeleteProof(existingTrie: Trie, key: Buffer, value: Buffe ### 1. Single-Key Trie Deletion When deleting the only key in a trie: + - `new_root` = `null_hash` (empty trie) - `proof` = `[]` (empty proof) @@ -221,7 +239,7 @@ const hydraTokenName = blake2b256(Buffer.concat([policyId, assetName])); // Token map lookup converts back to L1 tokens const tokenMap = new Map([ - ["", ["", ""]], // ADA + ["", ["", ""]], // ADA [hydraUsdxHash, [USDX_POLICY_ID, USDX_ASSET_NAME]], ]); ``` @@ -235,6 +253,7 @@ console.log("TypeScript CBOR:", Cbor.encode(data).toString("hex")); ``` Compare with Aiken debug test: + ```aiken test debug_cbor() { trace cbor.serialise(my_data) @@ -252,12 +271,12 @@ console.log(`Key: ${key}, Path: ${path.toString("hex")}, Nibble: ${nibble}`); ### 3. Common CBOR Mismatches -| Issue | Symptom | Fix | -|-------|---------|-----| -| Tuple as constructor | `d8799f...ff` instead of `9f...ff` | Use `{ list: [...] }` not `conStr0([...])` | -| Bool encoding | Wrong root hash | `False` = `conStr0([])`, `True` = `conStr1([])` | -| Missing int wrapper | Type error | Use `{ int: BigInt(n) }` not just `n` | -| String vs ByteArray | Wrong serialization | Always use `byteString(hex)` | +| Issue | Symptom | Fix | +| -------------------- | ---------------------------------- | ----------------------------------------------- | +| Tuple as constructor | `d8799f...ff` instead of `9f...ff` | Use `{ list: [...] }` not `conStr0([...])` | +| Bool encoding | Wrong root hash | `False` = `conStr0([])`, `True` = `conStr1([])` | +| Missing int wrapper | Type error | Use `{ int: BigInt(n) }` not just `n` | +| String vs ByteArray | Wrong serialization | Always use `byteString(hex)` | ## Complete Example: Order Cancel Test @@ -310,9 +329,126 @@ test my_mpf_test() { } ``` +## Alice & Bob Test Suite + +A comprehensive test suite demonstrating all MPF operations and Ed25519 signature verification is located in `validators/tests/alice_bob/`. + +### Test Files + +| File | Description | +| ------------------ | -------------------------------------------------------- | +| `merkle_proofs.ak` | All MPF operations (insert, update, delete) | +| `price_message.ak` | Ed25519 signature verification for price oracle messages | + +### Keypairs Used + +| User | Private Key | Public Key | Key Hash (Blake2b-224) | +| ----- | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ---------------------------------------------------------- | +| Alice | `f9fddf3603743e56af455da28a63999451011cc443ea09134a97089a8775e153` | `f665d3a9cbb3d8068aece5700771893780dbbf30302eb7ff6835ae68c9efe690` | `376ca49fdbff2ebc082141951e55038468b51230e90cfc0000004204` | +| Bob | `644674b75aba7f1faa3af927a4ec99648f6b5c8cf03d74f0bef11c4d23fd66e6` | `827444459fa6466ad8fd670179e23b00ea0566547a44cd67a1b37675634280f1` | `9720b632701aabb325d5928b66811d624d650287c2e0e099e1eeb510` | + +**Note:** Key hash is computed using Blake2b-224 (28 bytes) of the public key: + +```typescript +import { blake2bHex } from "blakejs"; +const keyHash = blake2bHex(Buffer.from(publicKey, "hex"), undefined, 28); +``` + +### MPF Operations Tested + +| Test | Operation | Description | Root Hash | +| ------------------------------- | ------------ | -------------------------------- | ------------- | +| `ab_alice_insert_empty_trie` | `mpf.insert` | Insert Alice into empty trie | `512be26f...` | +| `ab_bob_insert_after_alice` | `mpf.insert` | Insert Bob into non-empty trie | `7287001c...` | +| `ab_alice_update_add_shares` | `mpf.update` | Alice deposits more shares | `a5172b6c...` | +| `ab_bob_partial_withdrawal` | `mpf.update` | Bob withdraws partial shares | `29769521...` | +| `ab_bob_full_withdrawal_delete` | `mpf.delete` | Bob withdraws all (delete entry) | `5bb79ce6...` | + +### Data Structures + +```aiken +// MPF Key - UserTradeAccount serialized with cbor.serialise() +type UserTradeAccount { + account: Account { account_id, master_key, operation_key }, + trading_logic: ScriptHash, +} + +// MPF Value - SharesRecordEntry serialized with cbor.serialise() +type SharesRecordEntry { + shares: Int, + total_deposited: Int, +} +``` + +### Regenerating MPF Fixtures + +Use the belvedere test to regenerate merkle proofs: + +```bash +cd /path/to/belvedere/backend/mesh +npm test -- generateAliceBobProof.test.ts +``` + +The test outputs all root hashes and proofs needed for Aiken tests. + +### Regenerating Signature Fixtures + +Use the distiller test to regenerate signed messages: + +```bash +cd /path/to/distiller +ALICE_KEY="f9fddf3603743e56af455da28a63999451011cc443ea09134a97089a8775e153" \ +BOB_KEY="644674b75aba7f1faa3af927a4ec99648f6b5c8cf03d74f0bef11c4d23fd66e6" \ +cargo test test_generate_aiken_sigs -- --nocapture +``` + +The test outputs CBOR messages and Ed25519 signatures in Aiken constant format. + +### MPF Proof Format + +The Aiken MPF library uses these proof step types: + +```aiken +type Proof = + List + +type ProofStep { + Branch { skip: Int, neighbors: ByteArray } + Fork { skip: Int, neighbor: Neighbor } + Leaf { skip: Int, key: ByteArray, value: ByteArray } +} +``` + +Example proof for Bob insert (sibling is Alice's leaf): + +```aiken +let proof = [ + mpf.Leaf { + skip: 0, + key: #"9a286602a7a703340604bba770eb01da6196925fe5a7f0f20cefd7422a9d1640", + value: #"89d017515bd4cc392d560d2cb009359b944c1ee6826e379ecfe7cc09165477ea", + }, +] +``` + +### Ed25519 Signature Verification + +```aiken +use aiken/builtin + +test verify_signature() { + let pub_key = #"f665d3a9cbb3d8068aece5700771893780dbbf30302eb7ff6835ae68c9efe690" + let message = #"d8799f1a59682f00..." // CBOR-encoded price message + let signature = #"fbb6537a77aa2fa4..." // 64-byte Ed25519 signature + + builtin.verify_ed25519_signature(pub_key, message, signature) +} +``` + ## Summary 1. **Understand the data structure** - Know what Aiken expects (Order vs MerklizedOrderDatum) 2. **Match CBOR serialization** - Tuples as arrays, booleans as constructors 3. **Compute correct hashes** - Use blake2b_256 for paths, MPF library for roots 4. **Test incrementally** - Use debug traces to compare CBOR hex values +5. **Use Alice/Bob tests** - Reference `validators/tests/alice_bob/` for complete MPF operation coverage diff --git a/validators/tests/alice_bob/merkle_proofs.ak b/validators/tests/alice_bob/merkle_proofs.ak new file mode 100644 index 0000000..b5f9bfe --- /dev/null +++ b/validators/tests/alice_bob/merkle_proofs.ak @@ -0,0 +1,303 @@ +use aiken/cbor +use aiken/merkle_patricia_forestry as mpf +use cardano/address.{VerificationKey} +use hydra_dex/types.{Account, SharesRecordEntry, UserTradeAccount} + +// ========== Alice and Bob Merkle Proof Tests ========== +// Generated from belvedere test: generateAliceBobProof.test.ts +// +// Alice keypair: +// - Private: f9fddf3603743e56af455da28a63999451011cc443ea09134a97089a8775e153 +// - Public: f665d3a9cbb3d8068aece5700771893780dbbf30302eb7ff6835ae68c9efe690 +// - KeyHash: 376ca49fdbff2ebc082141951e55038468b51230e90cfc0000004204 (Blake2b-224) +// +// Bob keypair: +// - Private: 644674b75aba7f1faa3af927a4ec99648f6b5c8cf03d74f0bef11c4d23fd66e6 +// - Public: 827444459fa6466ad8fd670179e23b00ea0566547a44cd67a1b37675634280f1 +// - KeyHash: 9720b632701aabb325d5928b66811d624d650287c2e0e099e1eeb510 (Blake2b-224) + +// Trading logic (constant across all accounts) +const trading_logic = + #"130a4c436f91d5cb0f0ddfccac88d656d4301383c7b1cd8ae7f79e27" + +// Alice account +const alice_account_id = #"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1" + +const alice_key_hash = + #"376ca49fdbff2ebc082141951e55038468b51230e90cfc0000004204" + +fn alice_account() { + UserTradeAccount { + account: Account { + account_id: alice_account_id, + master_key: VerificationKey(alice_key_hash), + operation_key: VerificationKey(alice_key_hash), + }, + trading_logic, + } +} + +// Bob account +const bob_account_id = #"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + +const bob_key_hash = #"9720b632701aabb325d5928b66811d624d650287c2e0e099e1eeb510" + +fn bob_account() { + UserTradeAccount { + account: Account { + account_id: bob_account_id, + master_key: VerificationKey(bob_key_hash), + operation_key: VerificationKey(bob_key_hash), + }, + trading_logic, + } +} + +// ========== Test 1: Alice Insert (Empty Trie) ========== +// Alice deposits 1000 USD (1000000000 with 6 decimals) +// Shares: 1000000000 +// Expected root: 512be26ff9e974483dce99731b88f662578023793c7474cfa081255f25dcb30c + +test ab_alice_insert_empty_trie() { + let alice = alice_account() + let mpf_key = cbor.serialise(alice) + + let shares = 1000000000 + let total_deposited = 1000000000 + let entry = SharesRecordEntry { shares, total_deposited } + let value = cbor.serialise(entry) + + // Empty trie - no proof needed + let trie = mpf.empty + let proof = [] + + let new_trie = mpf.insert(trie, mpf_key, value, proof) + let computed_root = mpf.root(new_trie) + + let expected_root = + #"512be26ff9e974483dce99731b88f662578023793c7474cfa081255f25dcb30c" + + trace @"Alice Insert - Key": mpf_key + trace @"Alice Insert - Value": value + trace @"Alice Insert - Computed Root": computed_root + trace @"Alice Insert - Expected Root": expected_root + + computed_root == expected_root +} + +// ========== Test 2: Bob Insert (After Alice) ========== +// Bob deposits 500 USD (500000000 with 6 decimals) +// Shares: 500000000 +// Previous root: 512be26ff9e974483dce99731b88f662578023793c7474cfa081255f25dcb30c +// Expected root: 7287001c35dee04b34ad6756c69a7e76b02480e309f2e02e861eda037a8dc55f +// +// Proof from offchain: +// [Skip(0), Left(9a286602a7a703340604bba770eb01da6196925fe5a7f0f20cefd7422a9d1640), +// Right(89d017515bd4cc392d560d2cb009359b944c1ee6826e379ecfe7cc09165477ea)] + +test ab_bob_insert_after_alice() { + let bob = bob_account() + let mpf_key = cbor.serialise(bob) + + let shares = 500000000 + let total_deposited = 500000000 + let entry = SharesRecordEntry { shares, total_deposited } + let value = cbor.serialise(entry) + + // Start from Alice's root + let initial_root = + #"512be26ff9e974483dce99731b88f662578023793c7474cfa081255f25dcb30c" + + // Proof from offchain - Leaf { skip, key, value } + // constructor 2 = Leaf + let proof = + [ + mpf.Leaf { + skip: 0, + key: #"9a286602a7a703340604bba770eb01da6196925fe5a7f0f20cefd7422a9d1640", + value: #"89d017515bd4cc392d560d2cb009359b944c1ee6826e379ecfe7cc09165477ea", + }, + ] + + let trie = mpf.from_root(initial_root) + let new_trie = mpf.insert(trie, mpf_key, value, proof) + let computed_root = mpf.root(new_trie) + + let expected_root = + #"7287001c35dee04b34ad6756c69a7e76b02480e309f2e02e861eda037a8dc55f" + + trace @"Bob Insert - Key": mpf_key + trace @"Bob Insert - Value": value + trace @"Bob Insert - Computed Root": computed_root + trace @"Bob Insert - Expected Root": expected_root + + computed_root == expected_root +} + +// ========== Test 3: Alice Update (Add More Shares) ========== +// Alice adds 500 USD more (500000000) +// Previous: shares=1000000000, total_deposited=1000000000 +// New: shares=1500000000, total_deposited=1500000000 +// Previous root: 7287001c35dee04b34ad6756c69a7e76b02480e309f2e02e861eda037a8dc55f +// Expected root: a5172b6c809ac4c12992851680d5de37f5819e73fe9613ea7d5aa137a4d2848f +// +// Proof from offchain (after update): +// [Skip(0), Left(8751465de93e2a74c4910c140e4c6c13a6f7259971d902ea2b10f91b5015ad85), +// Right(c940040c98da9bd1480fcdc9abd41b747173dbc0d8ea49e5637a8a0258019eb2)] + +test ab_alice_update_add_shares() { + let alice = alice_account() + let mpf_key = cbor.serialise(alice) + + // Old entry + let old_entry = + SharesRecordEntry { shares: 1000000000, total_deposited: 1000000000 } + let old_value = cbor.serialise(old_entry) + + // New entry + let new_entry = + SharesRecordEntry { shares: 1500000000, total_deposited: 1500000000 } + let new_value = cbor.serialise(new_entry) + + // Start from previous root (Alice + Bob) + let initial_root = + #"7287001c35dee04b34ad6756c69a7e76b02480e309f2e02e861eda037a8dc55f" + + // Proof AFTER update (proof of new state) - Leaf { skip, key, value } + let proof = + [ + mpf.Leaf { + skip: 0, + key: #"8751465de93e2a74c4910c140e4c6c13a6f7259971d902ea2b10f91b5015ad85", + value: #"c940040c98da9bd1480fcdc9abd41b747173dbc0d8ea49e5637a8a0258019eb2", + }, + ] + + let trie = mpf.from_root(initial_root) + let new_trie = mpf.update(trie, mpf_key, proof, old_value, new_value) + let computed_root = mpf.root(new_trie) + + let expected_root = + #"a5172b6c809ac4c12992851680d5de37f5819e73fe9613ea7d5aa137a4d2848f" + + trace @"Alice Update - Old Value": old_value + trace @"Alice Update - New Value": new_value + trace @"Alice Update - Computed Root": computed_root + trace @"Alice Update - Expected Root": expected_root + + computed_root == expected_root +} + +// ========== Test 4: Bob Partial Withdrawal (Update) ========== +// Bob withdraws 200 USD (200000000) +// Previous: shares=500000000, total_deposited=500000000 +// New: shares=300000000, total_deposited=300000000 +// Previous root: a5172b6c809ac4c12992851680d5de37f5819e73fe9613ea7d5aa137a4d2848f +// Expected root: 297695211c6d2e8f8b6c9ec37871498ffbb52bfe29e048aaffa421022cbed7b8 +// +// Proof from offchain (after update): +// [Skip(0), Left(9a286602a7a703340604bba770eb01da6196925fe5a7f0f20cefd7422a9d1640), +// Right(9cbf7a4e01dee5c3b4c521b47782526bfc7f46c543da6fc21e2d89330811050b)] + +test ab_bob_partial_withdrawal() { + let bob = bob_account() + let mpf_key = cbor.serialise(bob) + + // Old entry + let old_entry = + SharesRecordEntry { shares: 500000000, total_deposited: 500000000 } + let old_value = cbor.serialise(old_entry) + + // New entry (after withdrawing 200M) + let new_entry = + SharesRecordEntry { shares: 300000000, total_deposited: 300000000 } + let new_value = cbor.serialise(new_entry) + + // Start from previous root + let initial_root = + #"a5172b6c809ac4c12992851680d5de37f5819e73fe9613ea7d5aa137a4d2848f" + + // Proof AFTER update - Leaf { skip, key, value } + let proof = + [ + mpf.Leaf { + skip: 0, + key: #"9a286602a7a703340604bba770eb01da6196925fe5a7f0f20cefd7422a9d1640", + value: #"9cbf7a4e01dee5c3b4c521b47782526bfc7f46c543da6fc21e2d89330811050b", + }, + ] + + let trie = mpf.from_root(initial_root) + let new_trie = mpf.update(trie, mpf_key, proof, old_value, new_value) + let computed_root = mpf.root(new_trie) + + let expected_root = + #"297695211c6d2e8f8b6c9ec37871498ffbb52bfe29e048aaffa421022cbed7b8" + + trace @"Bob Withdraw - Old Value": old_value + trace @"Bob Withdraw - New Value": new_value + trace @"Bob Withdraw - Computed Root": computed_root + trace @"Bob Withdraw - Expected Root": expected_root + + computed_root == expected_root +} + +// ========== Test 5: Bob Full Withdrawal (Delete) ========== +// Bob withdraws all remaining 300 USD (300000000) +// Previous: shares=300000000, total_deposited=300000000 +// New: Entry deleted from trie +// Previous root: 297695211c6d2e8f8b6c9ec37871498ffbb52bfe29e048aaffa421022cbed7b8 +// Expected root: 5bb79ce6b41c271bb91676a5616b737e7d4c3c722d68ffd1857d6f703bec85d3 +// +// Proof from offchain (BEFORE delete): +// [Skip(0), Left(9a286602a7a703340604bba770eb01da6196925fe5a7f0f20cefd7422a9d1640), +// Right(9cbf7a4e01dee5c3b4c521b47782526bfc7f46c543da6fc21e2d89330811050b)] + +test ab_bob_full_withdrawal_delete() { + let bob = bob_account() + let mpf_key = cbor.serialise(bob) + + // Old entry (to be deleted) + let old_entry = + SharesRecordEntry { shares: 300000000, total_deposited: 300000000 } + let old_value = cbor.serialise(old_entry) + + // Start from previous root + let initial_root = + #"297695211c6d2e8f8b6c9ec37871498ffbb52bfe29e048aaffa421022cbed7b8" + + // Proof BEFORE delete (proof of existence) - Leaf { skip, key, value } + let proof = + [ + mpf.Leaf { + skip: 0, + key: #"9a286602a7a703340604bba770eb01da6196925fe5a7f0f20cefd7422a9d1640", + value: #"9cbf7a4e01dee5c3b4c521b47782526bfc7f46c543da6fc21e2d89330811050b", + }, + ] + + let trie = mpf.from_root(initial_root) + let new_trie = mpf.delete(trie, mpf_key, old_value, proof) + let computed_root = mpf.root(new_trie) + + let expected_root = + #"5bb79ce6b41c271bb91676a5616b737e7d4c3c722d68ffd1857d6f703bec85d3" + + trace @"Bob Delete - Old Value": old_value + trace @"Bob Delete - Computed Root": computed_root + trace @"Bob Delete - Expected Root": expected_root + + computed_root == expected_root +} + +// ========== Summary Test ========== +test ab_merkle_summary() { + trace @"===== Alice and Bob Merkle Proof Summary =====" + trace @"Empty Root": #"0000000000000000000000000000000000000000000000000000000000000000" + trace @"After Alice Insert": #"512be26ff9e974483dce99731b88f662578023793c7474cfa081255f25dcb30c" + trace @"After Bob Insert": #"7287001c35dee04b34ad6756c69a7e76b02480e309f2e02e861eda037a8dc55f" + trace @"After Alice Update": #"a5172b6c809ac4c12992851680d5de37f5819e73fe9613ea7d5aa137a4d2848f" + trace @"After Bob Partial Withdraw": #"297695211c6d2e8f8b6c9ec37871498ffbb52bfe29e048aaffa421022cbed7b8" + trace @"After Bob Delete": #"5bb79ce6b41c271bb91676a5616b737e7d4c3c722d68ffd1857d6f703bec85d3" + True +} diff --git a/validators/tests/alice_bob/price_message.ak b/validators/tests/alice_bob/price_message.ak new file mode 100644 index 0000000..4d37b78 --- /dev/null +++ b/validators/tests/alice_bob/price_message.ak @@ -0,0 +1,168 @@ +use aiken/builtin +use cardano/assets.{AssetName, PolicyId} +use hydra_dex/price_oracle_utils.{convert_m_value_to_usd} +use hydra_dex/types.{MValue} + +// ========== Alice and Bob Price Message Tests ========== +// These tests verify Ed25519 signature verification for price oracle messages +// +// Alice keypair: +// - Public: f665d3a9cbb3d8068aece5700771893780dbbf30302eb7ff6835ae68c9efe690 +// - KeyHash: 376ca49fdbff2ebc082141951e55038468b51230e90cfc0000004204 (Blake2b-224) +// +// Bob keypair: +// - Public: 827444459fa6466ad8fd670179e23b00ea0566547a44cd67a1b37675634280f1 +// - KeyHash: 9720b632701aabb325d5928b66811d624d650287c2e0e099e1eeb510 (Blake2b-224) + +// Alice's full public key (Ed25519, 32 bytes) +const alice_pub_key = + #"f665d3a9cbb3d8068aece5700771893780dbbf30302eb7ff6835ae68c9efe690" + +// Bob's full public key (Ed25519, 32 bytes) +const bob_pub_key = + #"827444459fa6466ad8fd670179e23b00ea0566547a44cd67a1b37675634280f1" + +// ========== Generated Signatures from Distiller ========== +// Message 1 (vault_equity=1500000000) +const msg1_cbor = + #"d8799f1a59682f00a29f4040ff9f0501ff9f581cc69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913445553444dff9f0100ffd8799f5820aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa00ffff" + +const alice_sig_1 = + #"fbb6537a77aa2fa4c99cda827fda738610d7f9c64b915df7a216d884af534eb250fa826db87ba3b66b9d040cf8bf9837b7963f63ea0bfcc8a6ec7eb1a4a45504" + +const bob_sig_1 = + #"dd00226efff0da6387d12e10464a53b221ef40c128d7f54403bfb66d3000a68dbf5bfbf303678201fbc47a03aea5853c83c04d7084a5f9bc6710f05e2a02f904" + +// Message 2 (vault_equity=1800000000) +const msg2_cbor = + #"d8799f1a6b49d200a29f4040ff9f0501ff9f581cc69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913445553444dff9f0100ffd8799f5820bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01ffff" + +const alice_sig_2 = + #"6c864008c16bfef445af2d6711790ca57744367f851d7065f85cac842b7da40fdbda6eb9e6e3df4f322b8bc92f24f56628068d689e31bb9be988adaa95924f04" + +const bob_sig_2 = + #"e5dbbfd09404d77b1999c5b0e750d15b7ce715f6436af4b45878a2fb75b860e7c90a301d3d3eef1ed7353bb71a71ebce057e06a2100af39615c58a8448363f02" + +// ========== Prices Definition ========== +// ADA price = $0.50 (price=5, scale=1 -> 5/10^1 = 0.5) +// USDM price = $1.00 (price=1, scale=0 -> 1/10^0 = 1.0) +const prices: Pairs<(PolicyId, AssetName), (Int, Int)> = + [ + Pair((#"", #""), (5, 1)), + Pair( + (#"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", #"5553444d"), + (1, 0), + ), + ] + +// ========== Test 1: Verify Alice Signature on Message 1 ========== +// Uses builtin.verify_ed25519_signature to verify the signature + +test ab_verify_alice_signature_message_1() { + let is_valid = + builtin.verify_ed25519_signature(alice_pub_key, msg1_cbor, alice_sig_1) + + trace @"Alice Signature Valid": is_valid + is_valid +} + +// ========== Test 2: Verify Bob Signature on Message 1 ========== +test ab_verify_bob_signature_message_1() { + let is_valid = + builtin.verify_ed25519_signature(bob_pub_key, msg1_cbor, bob_sig_1) + + trace @"Bob Signature Valid": is_valid + is_valid +} + +// ========== Test 3: Verify Both Signatures on Message 1 ========== +test ab_verify_both_signatures_message_1() { + let alice_valid = + builtin.verify_ed25519_signature(alice_pub_key, msg1_cbor, alice_sig_1) + let bob_valid = + builtin.verify_ed25519_signature(bob_pub_key, msg1_cbor, bob_sig_1) + + trace @"Alice Valid": alice_valid + trace @"Bob Valid": bob_valid + + alice_valid && bob_valid +} + +// ========== Test 4: Verify Signatures on Message 2 ========== +test ab_verify_both_signatures_message_2() { + let alice_valid = + builtin.verify_ed25519_signature(alice_pub_key, msg2_cbor, alice_sig_2) + let bob_valid = + builtin.verify_ed25519_signature(bob_pub_key, msg2_cbor, bob_sig_2) + + trace @"Alice Valid": alice_valid + trace @"Bob Valid": bob_valid + + alice_valid && bob_valid +} + +// ========== Test 5: Signature Verification Should Fail with Wrong Key ========== +test ab_verify_signature_fails_wrong_key() { + // Verify Alice's signature with Bob's key - should return False + let should_be_false = + builtin.verify_ed25519_signature(bob_pub_key, msg1_cbor, alice_sig_1) + + trace @"Wrong Key Result (should be false)": should_be_false + + !should_be_false +} + +// ========== Test 6: Signature Verification Should Fail with Wrong Message ========== +test ab_verify_signature_fails_wrong_message() { + // Verify Alice's signature for msg1 against msg2 - should return False + let should_be_false = + builtin.verify_ed25519_signature(alice_pub_key, msg2_cbor, alice_sig_1) + + trace @"Wrong Message Result (should be false)": should_be_false + + !should_be_false +} + +// ========== Test 7: Convert MValue to USD ========== +// Test USD calculation with the prices +// Example: 1000 ADA + 500 USDM = 1000 * 0.5 + 500 * 1.0 = 1000 USD + +test ab_convert_mvalue_to_usd() { + // MValue with 1000 ADA (lovelace) and 500 USDM + let m_value: MValue = + [ + Pair("", [Pair("", 1000)]), + Pair( + #"c69b981db7a65e339a6d783755f85a2e03afa1cece9714c55fe4c913", + [Pair(#"5553444d", 500)], + ), + ] + + // Calculate USD value + // USD = 1000 * 5 / 10^1 + 500 * 1 / 10^0 + // = 1000 * 0.5 + 500 * 1.0 + // = 500 + 500 + // = 1000 + let usd_value = convert_m_value_to_usd(m_value, prices) + let expected_usd = 1000 + + trace @"USD Value": usd_value + trace @"Expected": expected_usd + + usd_value == expected_usd +} + +// ========== Test 8: Trace Message CBOR Format ========== +test ab_trace_message_format() { + trace @"=== Message 1 (Vault Equity 1500 USD) ===" + trace @"CBOR": msg1_cbor + trace @"Alice Sig": alice_sig_1 + trace @"Bob Sig": bob_sig_1 + + trace @"=== Message 2 (Vault Equity 1800 USD) ===" + trace @"CBOR": msg2_cbor + trace @"Alice Sig": alice_sig_2 + trace @"Bob Sig": bob_sig_2 + + True +} From 1d6db2b077bf06deaac7ddf433e80d6ae8092779 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 1 Apr 2026 13:47:33 +0800 Subject: [PATCH 25/30] feat: dexOrderBook migration --- lib/hydra_dex/types.ak | 1 + plutus.json | 14 ++++++++++---- validators/dex_order_book/spend.ak | 9 +++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index 9dd6b33..f3b0fd9 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -188,6 +188,7 @@ pub type DexOrderBookRedeemer { DexOrderBookHydraCommit DexOrderBookSpamPreventionWithdraw DexOrderBookEmergencyCancelOrder + DexOrderBookMigration } pub type DexOrderBookDatum { diff --git a/plutus.json b/plutus.json index 50d1823..b373204 100644 --- a/plutus.json +++ b/plutus.json @@ -542,8 +542,8 @@ } } ], - "compiledCode": "5917bb0101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a4011370e90024dc3a40013013375400e9111192cc004c00c00a2b300130193754019001807a0348acc004c02800a2b300130193754019001807a0348acc004c01000a2b300130193754019001807a0348acc004cdc3a400c005159800980c9baa00c800c03d01a4566002600a005159800980c9baa00c800c03d01a403d016202c405880b10160cc004c060dd50044888c966002600c00313259800800c00e264b300100180240120090048992cc004c08c00e00d00540806eb80050231810000a03c301c37540091598009806800c4c9660020030038992cc0040060090048024012264b3001302300380340150201bae001408c604000280f0c070dd500240090192032301a3754007223233001001003223300300130020029ba54800246038603a0033017375401722232598009803000c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e264b30013026003804c0210231bae001409860460028108dd6800981100140110231810000a03c301c37540091598009806800c4c9660020030038992cc00400600900480244cc89660020030068992cc0040062b300130250028acc004c02cc080dd5000c4c9660020030088992cc004006013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f132598009817001c0460208158dd7000a05c302b00140a46eb8004c0a800902b1814000a04c375a002604e00500940a0604a0028118c084dd5000c01d01e401d022401e00f007803a04c302300140846eb4004c08800a0088118c08000501e180e1baa0048acc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f1332259800800c026264b3001001805402a01500a8992cc004c0a400e01900b40986eb80050291813000a048375c002604a0048130c08c0050211bad001302200280220463020001407860386ea801200480c90192032301a37540072301c301d301d301d301d301d301d301d301d301d301d0019ba54800922222222298009812804c88c8cc00400400c896600200314c0103d87a8000899192cc004cdc8802800c56600266e3c0140062601866052604e00497ae08a60103d87a80004091133004004302b00340906eb8c094004c0a0005026488966002601c60466ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0b000a330010038992cc004c04c006264b3001001803c4c966002003159800981780144c966002602c00313259800800c02a264b30010018acc004c0c800a33001001806402d015402d02f402e01700b805a066303000140b860586ea800a2b3001301d0018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c0e400e02701240d86eb400602281c8c0d80050341bad0013035002807206c303300140c46eb4004c0c800a0168198c0c000502e18161baa002804a05240a460546ea8006010816201100880440210301816800a05630293754005159800980d000c56600260526ea800a00f00640a900640988130c09cdd5000c01500f4015029401600b005802a05a302a00140a06054005003801c00e0068158c0a000502618121baa003800a042911919800800801912cc004006298103d87a80008992cc004c010006260166605000297ae0899801801981500120463028001409922259800980718119baa0038992cc00400600513259800800c00e007003801c4cc89660020030058992cc004006264b3001001803c4c966002003159800981780146600200719800800c02601080920108092010816201100880440210301816800a056302d002803401a00d00640b860560028148dd7000981500120563028001409860486ea800e002810a444b3001300e3023375400713259800800c00a264b30010018992cc00400600913259800800c016264b3001302d003899912cc004c054006264b3001001804c4c966002003159800981880144ca6002003002802a0022223259800980d800c4c96600200300f8992cc004006021010808404226644b300100180944c9660020030138992cc004c0ec00e26603a00244b300100280544c8c96600200301880c406226644b30010018cc004042003130053041006404101a80d406a0348210dd6800981d8014061040181c800981e001207480a20703756003013809c04d03b181c000a06c375c002606e00481c0c0d400503318189baa0038acc004c088006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c04e027013899912cc00400602b13259800800c05a02d01680b44c966002607c00700b80ba076375c00281f0c0ec0050391bae001303a00240ec607000281b0dd7000981b8012070303500140cc60626ea800e01c817102e18179baa002805205c805402a01500a40c8605e0028168c0acdd50034566002603800313259800800c026264b3001001805402a264b3001303200389980a000912cc00400a00f13259800800c4cc8966002603a00313259800800c046264b3001001809404a264b3001303a00389980e000912cc00400a00f13259800800c6600200313002303d00380b203680b405a02d01640f8607600481ca02681b8dd6000c04a02481d0c0dc00503518199baa0038acc004c090006264b3001001808c4c966002003012809404a0251332259800800c052264b300100180ac05602b015899912cc00400602f13259800800c062031132598009820001c4cc088004896600200500d8992cc00400633001001898011821801c071021407203901c80e2088304100240fd01940f46eb00060310184100607a00281d8dd7000981e001207a303a00140e06eb8004c0e400903a181b800a06a30333754007159800980f000c4c9660020030118992cc0040060250128992cc004c0e800e26603800244b3001002803c4c96600200319800800c4c008c0f400e02c80da02d01680b405903e181d8012072809a06e37580030128092074303700140d460666ea800e020818103020601300230350033030375400300e807403a01c81b0c0cc009031402d02f1bac00180540290321817800a05a302b375400d00840a081404cc03c0048966002005009899192cc00400601500a805402a26644b30010018064032264b3001001806c4c96600200300e807403a01d1332259800800c042264b3001001808c0460230118992cc004c0e400e26016607201901240d86eb8005039181b000a068375c002606a00481b0c0cc0050311bac00180640310341bae001302d00240c86056002605c0048160c0a0dd5002401902a1bab001802c01600a8168c0a80050281815001400e007003801a0563028001409860486ea800e00281092222229800981598159815981598158034dd61815003488c966002602860526ea8006264b30010018acc004c054c0a8dd5000c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b3001001816c0b626644b3001001817c4c96600200303081840c20611332259800800c0ca264b30010018992cc00400606913259800800c0d606b03581ac4cc89660020030378992cc00400607103881c40e226644b300100181d44c96600200313259800800c0f2264b300100181ec0f607b03d899912cc00400607f13259800800c4c9660020030418992cc004006085042821410a26644b300100182244c96600200313259800800c11a264b3001001823c11e08f047899912cc00400609313259800800c4c96600200304b8992cc00400609904c826413226644b300100182744c96600200313259800800c142264b30010018992cc0040060a513259800800c56600260ba00513303f02622598008014660020471980080dc6600202d19800808c6600201919800803c566002608a60b46ea8016264b300100182b44c96600200305782bc15e0af1332259800800c166264b300100182d416a0b505a899912cc0040060b913259800800c1760bb05d82ec4cc896600200305f8992cc0040060c10608304182264b3001306b0038acc004c144c198dd5007c4c9660020030628992cc0040060c70638992cc004c1b800e2660a000244b3001002882144c966002003067833c19e0cf13230033072004375c0028390c1bc00906d419106b1bac001831c18d06e1835800a0d23067375401f061419106141a06eb800506b1834000a0cc375c00260ce0048340c1940050631bae0013064002419460c40028300dd7000983080120c4305f001417460b66ea80160aa82c20aa81c20aa81c20aa81c20aa81c20aa81c20aa81c2264b300100182b415a0ad056899180198308021bae001418460bc00482e20a682d20a7053829c14d05e182d800a0b2305b002828c1460a3051417060b200282b8c16400a09f04f827c13d05a182b800a0aa375c00260ac00482b8c150005052182a001412a09504a82520aa305200141406eb8004c1440090521827800a09a304f002822c11608b0454140609a0028258dd70009826001209a304a0014120609400504082041020808258c1200050461bae00130470024120608a0028218c11400a07703b81dc0ed0461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0f400a067033819c0cd03e181d800a072375c002607400481d8c0e00050361bac0013037002816c0b5038181a800a066375c002606800481a8c0c80050301bae001303100240c8605e0028168c0acdd5000c095028409604b025812a060323259800980b000c54cc0a9241274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0740062a66054921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981798161baa00240a48148c0a8dd500098169817181718151baa300e302a3754605a60546ea80062a660509201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a2020202020202020290016409c6600a0044603664b3001301c302a375400314800226eb4c0b8c0acdd5000a0503259800980e18151baa0018a6103d87a8000899198008009bab302f302c375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980a19818981780125eb82298103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e2050330083756601c60546ea8c038c0a8dd50008014888c966002602a00313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606800719800802402200e805a00e8188dd7000a068303100140bc606200500480240120088190c0bc00502d18159baa0048acc004c070006264b3001001801c4c96600200313259800800c016264b3001001803401a00d0068992cc004c0d000e33001004804401d00b401d0311bae00140d060620028178c0c400a00900480240110321817800a05a302b3754009159800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d13259800981a001c66002009008803a016803a062375c00281a0c0c400502f181880140120090048022064302f00140b460566ea801200481410282050302937540069111194c004dd61817800cdd598179818000c888c966002603400313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b300130210018acc004c0c0dd5002400e004818a2b3001301b0018992cc00400600713259800800c01200900480244c966002606e007006802a068375c00281b8c0d000503218181baa0048acc004cdc3a400c00313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b3001301c0018992cc00400600713259800800c566002606c00519800800c0160088062008819a0090048024011037181a000a0643030375400915980099b8748028006264b3001001801c4c966002003159800981b00146600200300580220188022066802401200900440dc60680028190c0c0dd5002400902d205a40b4816902d205a302e37540069112cc004c06404a2b30013019302e375403913259800980d18179baa0018992cc004006330010018acc004cdc3a401460606ea80062946294102e40a900340aa05502a815206c30333030375400302840b464646600200200844b30010018a6103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800981000945660026032605c6ea8072264b3001301a302f375400313259800800c66002003159800980e98181baa0018a518a5040b902a400d02a81540aa05481b0c0ccc0c0dd5000c0a102d191919800800802112cc004006298103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800980d00944c8cc004004dd6181998181baa303330343034303430343034303430343034303430343034303430343034303430343034303037546600e01005844b30010018a518acc004c8c8cc00400401c896600200314a115980099b8f375c606e00200714a3133002002303800140c481a8dd7181a000c4cc008008c0d4006294102e20648acc004c06c04a26464660020026eacc0d0028896600200314a115980099baf003303130350018a51899801001181b000a05e40cc601e660626064606660666066605e6ea8c0c8c0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0bcdd519803003815a5eb82264b3001301a302f3754003159800acc0056600264b300130223030375400314bd6f7b63044dd5981a18189baa00140b86601c6eacc050c0c0dd5180a18181baa30333030375400205714a314a0818a29462a6605c92011b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0816a2b30013232330010010062259800800c528456600266e3cdd7181b000801c528c4cc008008c0dc0050302068375c606660606ea8cc01c0200b229462a6605c92011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0816a294102d454cc0b92413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640b4660166eb0c0c805c8cdd7981998181baa00101e40b0816102c2058181798178020402a01500a8052032301500130153016001301137540071640383010001300b3754023149a2a660129211856616c696461746f722072657475726e65642066616c7365001365640201", - "hash": "60c6788a6d21574f92338b5908be8b763dad113d795127ee493f3bac" + "compiledCode": "5918670101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a400d370e90044dc3a4015370e90004dc3a40093013375400e911111192cc004c01000a2b3001301b375401d001808a0388acc004c03000a2b3001301b375401d001808a0388acc004c00c00a2b3001301b375401d001808a0388acc004c01c00a2b3001301b375401d001808a0388acc004c01800a2b3001301b375401d001808a0388acc004c01400a2b3001301b375401d001808a038808a030406080c10182030406033001301a37540152301e301f001980c9baa00d911192cc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f132598009814001c0260108128dd7000a0503025001408c6eb4004c09000a0088128c088005020180f1baa0048acc004c03c006264b3001001801c4c966002003004802401226644b300100180344c96600200315980098138014566002601860446ea8006264b300100180444c966002003009804c02626644b3001001805c4c96600200300c80640320191332259800800c03a264b3001001807c03e01f00f8992cc004c0c000e02301040b46eb80050301816800a056375c00260580048168c0a80050281bad0013029002804a0543027001409460466ea800600e810200e812200f007803c01d0281812800a046375a0026048005004409460440028100c078dd50024566002600c00313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01500a80544c966002605600700c805a050375c0028158c0a00050261bae001302700240a0604a0028118dd6800981200140110251811000a040301e3754009002406c80d901b180e1baa003911919800800801911980180098010014888c966002600e00313259800800c00e264b300100180240120090048992cc004c09400e00d00540886eb80050251811000a040301e37540091598009807800c4c9660020030038992cc0040060090048024012264b3001302500380340150221bae001409460440028100c078dd5002400901b2036301c37540072301e301f301f301f301f301f301f301f301f301f301f0019ba54800a6e9520004888888888cc8a60026052605260526052605200522232598009809000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009819001c66002009008803a014803a05e375c0028190c0bc00502d181780140120090048022060302d00140ac60526ea80122b3001301a0018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130320038cc004012011007402900740bc6eb80050321817800a05a302f002802401200900440c0605a0028158c0a4dd50024566002602200313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606400719800802402200e805200e8178dd7000a064302f00140b4605e00500480240120088180c0b400502b18149baa004801204c40988130c09cdd5001c889660026022604e6ea800e264b300100180144c96600200313259800800c012264b3001001802c4c96600260620071332259800980c000c4c9660020030098992cc0040062b300130350028994c004006005005400444464b3001301e0018992cc00400601f13259800800c04202101080844cc89660020030128992cc00400602713259800981f801c4cc074004896600200500a899192cc00400603101880c44cc89660020031980080840062600a608a00c808203501a80d40690461bad001303f00280c2088303d001304000240f901440f06eac006027013809a07e303c00140e86eb8004c0ec00903c181c800a06e303537540071598009813000c4c96600200300f8992cc004006021010808404226644b300100180944c966002003013809c04e0271332259800800c056264b300100180b405a02d0168992cc004c10800e01701740fc6eb8005042181f800a07a375c002607c00481f8c0f000503a1bae001303b00240f0607200281b8c0d4dd5001c03903220643033375400500a40c900a805402a01481b0c0cc00503118179baa0068acc004c080006264b3001001804c4c96600200300a80544c966002606c0071330140012259800801401e264b3001001899912cc004c080006264b3001001808c4c96600200301280944c966002607c00713301c0012259800801401e264b30010018cc004006260046082007016408101680b405a02c8210c0fc00903d404d03b1bac001809404903e181d800a072303737540071598009814000c4c9660020030118992cc004006025012809404a26644b300100180a44c96600200301580ac05602b1332259800800c05e264b300100180c4062264b30013044003899811000912cc00400a01b13259800800c6600200313002304700380e204c80e407203901c4120608a004821a0328208dd6000c0620308220c10400503f1bae00130400024104607c00281e0dd7000981e801207c303b00140e4606e6ea800e2b3001301f0018992cc00400602313259800800c04a02513259800981f001c4cc07000489660020050078992cc00400633001001898011820801c059020405a02d01680b2084303f00240f501340ec6eb000602501240f8607600281c8c0dcdd5001c041034206840d026004607200660686ea800601d00e807403903a181b801206a805a066375800300a805206c303300140c4605e6ea801a010816102c099807800912cc00400a0131323259800800c02a01500a80544cc896600200300c80644c96600200300d8992cc00400601d00e807403a26644b300100180844c966002003011808c04602313259800981e801c4c02cc0f403202481d0dd7000a07a303a00140e06eb8004c0e400903a181b800a06a375800300c8062070375c002606200481b0c0bc004c0c800903018161baa004803205c3756003005802c0150311817000a058302e002801c00e00700340bc60580028150c0a0dd5001c00502524446530013758605800337566058605a0033758605800d2223259800980b000c4c9660020030038992cc0040062b300130330028cc00400600b004402500440c1004802401200881a0c0c400502f18169baa0048acc004c0780062b3001302d3754009003801205c8acc004c054006264b3001001801c4c966002003004802401200913259800981a001c01a00a8188dd7000a068303100140bc605a6ea80122b300130190018992cc00400600713259800800c566002606600519800800c016008804a008818200900480240110341818800a05e302d3754009159800980c000c4c9660020030038992cc0040062b300130330028cc00400600b004402100440c1004802401200881a0c0c400502f18169baa0048acc004c05c006264b3001001801c4c966002003159800981980146600200300580220108022060802401200900440d060620028178c0b4dd5002400902a205440a8815102a2054302b375400691112cc004c0580462b30013016302c375403513259800980b98169baa0018992cc004006330010018acc004c064c0b8dd5000c528c5282058814200681440a205102840d06062605c6ea800604c8158c8c8cc004004014896600200314c0103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a9159800980f008c566002602c60586ea806a264b30013017302d375400313259800800c66002003159800980d18171baa0018a518a5040b1028400d02881440a205081a0c0c4c0b8dd5000c09902b191919800800802912cc004006298103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a919800911919800800801912cc0040062980103d87a8000899192cc004cdc8802800c56600266e3c014006260226606a606600497ae08a60103d87a800040c1133004004303700340c06eb8c0c4004c0d00050324889660026032605e6ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0e000a330010038992cc004c078006264b3001001803c4c966002003159800981d80144c966002604200313259800800c02a264b30010018acc004c0f800a33001001806402d01b402d03b402e01700b805a07e303c00140e860706ea800a2b300130290018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c11400e02701241086eb40060228228c1080050401bad00130410028072084303f00140f46eb4004c0f800a01681f8c0f000503a181c1baa002804a06a40d4606c6ea800601081c2011008804402103c181c800a06e303537540051598009813000c566002606a6ea800a00f00640d900640c88190c0ccdd5000c0150154015035401600b005802a072303600140d0606c005003801c00e00681b8c0d000503218181baa003800a05a911919800800801912cc004006298103d87a80008992cc004c010006260206606800297ae0899801801981b001205e303400140c8911192cc004c064056264660020026eb0c0d4c0c8dd5181a981b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b18191baa3300200702e2259800800c528c56600264646600200201844b30010018a508acc004cdc79bae30390010038a51899801001181d000a06640dc6eb8c0d8006266004004606e00314a081810344566002603802b13232330010013756606c01c44b30010018a508acc004cdd78019819981b800c528c4cc008008c0e0005031206a3010330333034303530353035303137546068606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a60626ea8cc0040180b52f5c1159800980e80ac4c966002603660626ea80062b300159800acc004c966002604860646ea8006297adef6c6089bab3036303337540028180cc014dd5980b98191baa301730323754606a60646ea80040b6294629410334528c54cc0c12411b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0817a2b300132323300100100b2259800800c528456600266e3cdd7181c000801c528c4cc008008c0e4005032206c375c606a60646ea8cc00801c0ba29462a6606092011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0817a294102f454cc0c12413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640bc660046eb0c0d005c8cdd7981a98191baa0010208acc004c068c0c0dd500f456600264646600200201444b30010018a508acc004cdc79bae30370010038a51899801001181c000a06240d46eb8c058c0c4dd5181a18189baa01e8a518a99817a481356b65795f7369676e65642865787472615f7369676e61746f726965732c20646174756d2e73746f705f6b657929203f2046616c73650014a08172050817102e205c40b84464b3001301c3032375400313259800800c566002603a60666ea8006264b3001001817c4c96600200303081840c20611332259800800c0ca264b3001001819c0ce067033899912cc00400606b13259800800c0da06d1332259800800c0e2264b300100181cc0e6073039899912cc00400607713259800800c4c96600200303d8992cc00400607d03e81f40fa26644b300100182044c966002003041820c1060831332259800800c10e264b30010018992cc00400608b13259800800c11a08d04682344cc89660020030488992cc004006264b300100182544c96600200304b825c12e0971332259800800c136264b30010018992cc00400609f13259800800c1420a105082844cc89660020030528992cc004006264b300100182a44c96600200305582ac1560ab1332259800800c15e264b30010018992cc0040060b313259800800c4c96600200305b8992cc0040062b30013066002899822013112cc00400a330010238cc00406e330010168cc0040463300100c8cc00401e2b3001304d3063375400b13259800800c17e264b300100183041820c1060899912cc0040060c513259800800c18e0c7063831c4cc89660020030658992cc0040060cd066833419a26644b300100183444c966002003069834c1a60d313259800983a001c56600260b260de6ea803e264b3001001835c4c96600200306c83644c96600260ee00713305500122598008014410a264b300100183841c20e10708991801983d8021bae00141ec60f000483b20da83a0dd6000c1b20d883b8c1d000507218381baa00f83520da83520e2375c00283a0c1c400506f1bae001307000241c460dc0028360dd7000983680120dc306b00141a46eb8004c1a800906b1834000a0cc3064375400b05e418505e40d905e40d905e40d905e40d905e40d905e40d913259800800c17e0bf05f82fc4c8c00cc1a8010dd7000a0d43067002419505c418d05c82e41720b88338c1900050621832001416a0b505a82d20ca3062001418060c400505882c41620b08318c18000505e1bae001305f002418060ba00282d8c17400a0a7053829c14d05e182d800a0b2375c00260b400482d8c160005056182c001413a09d04e82720b2305600141506eb8004c1540090561829800a0a23053002824c126093049415060a20028278dd7000982800120a2304e0014130609c00504482241120888278c13000504a1bae001304b002413060920028238dd70009824001209230460014110608c00503c81e40f20788238c1100050421bae00130430024110608200281f8dd6000982000140da06c8208c0f800503c1bae001303d00240f8607600281c8dd7000981d0012076303800140d860686ea800605c818a05d02e81740b903919192cc004c0780062a660669201274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0980062a66066921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981c181a9baa00240c88190c0ccdd5000981b181b981b98199baa301830333754606c60666ea80062a660629201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640c0660060044604864b300130253033375400314800226eb4c0dcc0d0dd5000a0623259800981298199baa0018a6103d87a8000899198008009bab30383035375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980b1981d181c00125eb82298103d87a800040d5133004004303c00340d46eb8c0d8004c0e40050372062330063756603060666ea8c060c0ccdd5000801102a2054181618160018c09c02488966002601e604a6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002606200519800801c66002003009804201c804201c804205c804402201100840c8605e0028168c0bc00a00d00680340190301816800a056375c00260580048168c0a800502818131baa003800a046201500a8054029019180a800980a980b00098089baa0038b201c180800098059baa0118a4d153300949011856616c696461746f722072657475726e65642066616c7365001365640201", + "hash": "b68cda8afdebac748c8a855c4ceb0ef0be54dea86ec2f0dce2e65214" }, { "title": "dex_order_book/spend.dex_order_book.else", @@ -564,8 +564,8 @@ } } ], - "compiledCode": "5917bb0101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a4011370e90024dc3a40013013375400e9111192cc004c00c00a2b300130193754019001807a0348acc004c02800a2b300130193754019001807a0348acc004c01000a2b300130193754019001807a0348acc004cdc3a400c005159800980c9baa00c800c03d01a4566002600a005159800980c9baa00c800c03d01a403d016202c405880b10160cc004c060dd50044888c966002600c00313259800800c00e264b300100180240120090048992cc004c08c00e00d00540806eb80050231810000a03c301c37540091598009806800c4c9660020030038992cc0040060090048024012264b3001302300380340150201bae001408c604000280f0c070dd500240090192032301a3754007223233001001003223300300130020029ba54800246038603a0033017375401722232598009803000c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e264b30013026003804c0210231bae001409860460028108dd6800981100140110231810000a03c301c37540091598009806800c4c9660020030038992cc00400600900480244cc89660020030068992cc0040062b300130250028acc004c02cc080dd5000c4c9660020030088992cc004006013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f132598009817001c0460208158dd7000a05c302b00140a46eb8004c0a800902b1814000a04c375a002604e00500940a0604a0028118c084dd5000c01d01e401d022401e00f007803a04c302300140846eb4004c08800a0088118c08000501e180e1baa0048acc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f1332259800800c026264b3001001805402a01500a8992cc004c0a400e01900b40986eb80050291813000a048375c002604a0048130c08c0050211bad001302200280220463020001407860386ea801200480c90192032301a37540072301c301d301d301d301d301d301d301d301d301d301d0019ba54800922222222298009812804c88c8cc00400400c896600200314c0103d87a8000899192cc004cdc8802800c56600266e3c0140062601866052604e00497ae08a60103d87a80004091133004004302b00340906eb8c094004c0a0005026488966002601c60466ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0b000a330010038992cc004c04c006264b3001001803c4c966002003159800981780144c966002602c00313259800800c02a264b30010018acc004c0c800a33001001806402d015402d02f402e01700b805a066303000140b860586ea800a2b3001301d0018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c0e400e02701240d86eb400602281c8c0d80050341bad0013035002807206c303300140c46eb4004c0c800a0168198c0c000502e18161baa002804a05240a460546ea8006010816201100880440210301816800a05630293754005159800980d000c56600260526ea800a00f00640a900640988130c09cdd5000c01500f4015029401600b005802a05a302a00140a06054005003801c00e0068158c0a000502618121baa003800a042911919800800801912cc004006298103d87a80008992cc004c010006260166605000297ae0899801801981500120463028001409922259800980718119baa0038992cc00400600513259800800c00e007003801c4cc89660020030058992cc004006264b3001001803c4c966002003159800981780146600200719800800c02601080920108092010816201100880440210301816800a056302d002803401a00d00640b860560028148dd7000981500120563028001409860486ea800e002810a444b3001300e3023375400713259800800c00a264b30010018992cc00400600913259800800c016264b3001302d003899912cc004c054006264b3001001804c4c966002003159800981880144ca6002003002802a0022223259800980d800c4c96600200300f8992cc004006021010808404226644b300100180944c9660020030138992cc004c0ec00e26603a00244b300100280544c8c96600200301880c406226644b30010018cc004042003130053041006404101a80d406a0348210dd6800981d8014061040181c800981e001207480a20703756003013809c04d03b181c000a06c375c002606e00481c0c0d400503318189baa0038acc004c088006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c04e027013899912cc00400602b13259800800c05a02d01680b44c966002607c00700b80ba076375c00281f0c0ec0050391bae001303a00240ec607000281b0dd7000981b8012070303500140cc60626ea800e01c817102e18179baa002805205c805402a01500a40c8605e0028168c0acdd50034566002603800313259800800c026264b3001001805402a264b3001303200389980a000912cc00400a00f13259800800c4cc8966002603a00313259800800c046264b3001001809404a264b3001303a00389980e000912cc00400a00f13259800800c6600200313002303d00380b203680b405a02d01640f8607600481ca02681b8dd6000c04a02481d0c0dc00503518199baa0038acc004c090006264b3001001808c4c966002003012809404a0251332259800800c052264b300100180ac05602b015899912cc00400602f13259800800c062031132598009820001c4cc088004896600200500d8992cc00400633001001898011821801c071021407203901c80e2088304100240fd01940f46eb00060310184100607a00281d8dd7000981e001207a303a00140e06eb8004c0e400903a181b800a06a30333754007159800980f000c4c9660020030118992cc0040060250128992cc004c0e800e26603800244b3001002803c4c96600200319800800c4c008c0f400e02c80da02d01680b405903e181d8012072809a06e37580030128092074303700140d460666ea800e020818103020601300230350033030375400300e807403a01c81b0c0cc009031402d02f1bac00180540290321817800a05a302b375400d00840a081404cc03c0048966002005009899192cc00400601500a805402a26644b30010018064032264b3001001806c4c96600200300e807403a01d1332259800800c042264b3001001808c0460230118992cc004c0e400e26016607201901240d86eb8005039181b000a068375c002606a00481b0c0cc0050311bac00180640310341bae001302d00240c86056002605c0048160c0a0dd5002401902a1bab001802c01600a8168c0a80050281815001400e007003801a0563028001409860486ea800e00281092222229800981598159815981598158034dd61815003488c966002602860526ea8006264b30010018acc004c054c0a8dd5000c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b3001001816c0b626644b3001001817c4c96600200303081840c20611332259800800c0ca264b30010018992cc00400606913259800800c0d606b03581ac4cc89660020030378992cc00400607103881c40e226644b300100181d44c96600200313259800800c0f2264b300100181ec0f607b03d899912cc00400607f13259800800c4c9660020030418992cc004006085042821410a26644b300100182244c96600200313259800800c11a264b3001001823c11e08f047899912cc00400609313259800800c4c96600200304b8992cc00400609904c826413226644b300100182744c96600200313259800800c142264b30010018992cc0040060a513259800800c56600260ba00513303f02622598008014660020471980080dc6600202d19800808c6600201919800803c566002608a60b46ea8016264b300100182b44c96600200305782bc15e0af1332259800800c166264b300100182d416a0b505a899912cc0040060b913259800800c1760bb05d82ec4cc896600200305f8992cc0040060c10608304182264b3001306b0038acc004c144c198dd5007c4c9660020030628992cc0040060c70638992cc004c1b800e2660a000244b3001002882144c966002003067833c19e0cf13230033072004375c0028390c1bc00906d419106b1bac001831c18d06e1835800a0d23067375401f061419106141a06eb800506b1834000a0cc375c00260ce0048340c1940050631bae0013064002419460c40028300dd7000983080120c4305f001417460b66ea80160aa82c20aa81c20aa81c20aa81c20aa81c20aa81c20aa81c2264b300100182b415a0ad056899180198308021bae001418460bc00482e20a682d20a7053829c14d05e182d800a0b2305b002828c1460a3051417060b200282b8c16400a09f04f827c13d05a182b800a0aa375c00260ac00482b8c150005052182a001412a09504a82520aa305200141406eb8004c1440090521827800a09a304f002822c11608b0454140609a0028258dd70009826001209a304a0014120609400504082041020808258c1200050461bae00130470024120608a0028218c11400a07703b81dc0ed0461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0f400a067033819c0cd03e181d800a072375c002607400481d8c0e00050361bac0013037002816c0b5038181a800a066375c002606800481a8c0c80050301bae001303100240c8605e0028168c0acdd5000c095028409604b025812a060323259800980b000c54cc0a9241274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0740062a66054921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981798161baa00240a48148c0a8dd500098169817181718151baa300e302a3754605a60546ea80062a660509201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a2020202020202020290016409c6600a0044603664b3001301c302a375400314800226eb4c0b8c0acdd5000a0503259800980e18151baa0018a6103d87a8000899198008009bab302f302c375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980a19818981780125eb82298103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e2050330083756601c60546ea8c038c0a8dd50008014888c966002602a00313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606800719800802402200e805a00e8188dd7000a068303100140bc606200500480240120088190c0bc00502d18159baa0048acc004c070006264b3001001801c4c96600200313259800800c016264b3001001803401a00d0068992cc004c0d000e33001004804401d00b401d0311bae00140d060620028178c0c400a00900480240110321817800a05a302b3754009159800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d13259800981a001c66002009008803a016803a062375c00281a0c0c400502f181880140120090048022064302f00140b460566ea801200481410282050302937540069111194c004dd61817800cdd598179818000c888c966002603400313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b300130210018acc004c0c0dd5002400e004818a2b3001301b0018992cc00400600713259800800c01200900480244c966002606e007006802a068375c00281b8c0d000503218181baa0048acc004cdc3a400c00313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b3001301c0018992cc00400600713259800800c566002606c00519800800c0160088062008819a0090048024011037181a000a0643030375400915980099b8748028006264b3001001801c4c966002003159800981b00146600200300580220188022066802401200900440dc60680028190c0c0dd5002400902d205a40b4816902d205a302e37540069112cc004c06404a2b30013019302e375403913259800980d18179baa0018992cc004006330010018acc004cdc3a401460606ea80062946294102e40a900340aa05502a815206c30333030375400302840b464646600200200844b30010018a6103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800981000945660026032605c6ea8072264b3001301a302f375400313259800800c66002003159800980e98181baa0018a518a5040b902a400d02a81540aa05481b0c0ccc0c0dd5000c0a102d191919800800802112cc004006298103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800980d00944c8cc004004dd6181998181baa303330343034303430343034303430343034303430343034303430343034303430343034303037546600e01005844b30010018a518acc004c8c8cc00400401c896600200314a115980099b8f375c606e00200714a3133002002303800140c481a8dd7181a000c4cc008008c0d4006294102e20648acc004c06c04a26464660020026eacc0d0028896600200314a115980099baf003303130350018a51899801001181b000a05e40cc601e660626064606660666066605e6ea8c0c8c0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0bcdd519803003815a5eb82264b3001301a302f3754003159800acc0056600264b300130223030375400314bd6f7b63044dd5981a18189baa00140b86601c6eacc050c0c0dd5180a18181baa30333030375400205714a314a0818a29462a6605c92011b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0816a2b30013232330010010062259800800c528456600266e3cdd7181b000801c528c4cc008008c0dc0050302068375c606660606ea8cc01c0200b229462a6605c92011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0816a294102d454cc0b92413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640b4660166eb0c0c805c8cdd7981998181baa00101e40b0816102c2058181798178020402a01500a8052032301500130153016001301137540071640383010001300b3754023149a2a660129211856616c696461746f722072657475726e65642066616c7365001365640201", - "hash": "60c6788a6d21574f92338b5908be8b763dad113d795127ee493f3bac" + "compiledCode": "5918670101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a400d370e90044dc3a4015370e90004dc3a40093013375400e911111192cc004c01000a2b3001301b375401d001808a0388acc004c03000a2b3001301b375401d001808a0388acc004c00c00a2b3001301b375401d001808a0388acc004c01c00a2b3001301b375401d001808a0388acc004c01800a2b3001301b375401d001808a0388acc004c01400a2b3001301b375401d001808a038808a030406080c10182030406033001301a37540152301e301f001980c9baa00d911192cc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f132598009814001c0260108128dd7000a0503025001408c6eb4004c09000a0088128c088005020180f1baa0048acc004c03c006264b3001001801c4c966002003004802401226644b300100180344c96600200315980098138014566002601860446ea8006264b300100180444c966002003009804c02626644b3001001805c4c96600200300c80640320191332259800800c03a264b3001001807c03e01f00f8992cc004c0c000e02301040b46eb80050301816800a056375c00260580048168c0a80050281bad0013029002804a0543027001409460466ea800600e810200e812200f007803c01d0281812800a046375a0026048005004409460440028100c078dd50024566002600c00313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01500a80544c966002605600700c805a050375c0028158c0a00050261bae001302700240a0604a0028118dd6800981200140110251811000a040301e3754009002406c80d901b180e1baa003911919800800801911980180098010014888c966002600e00313259800800c00e264b300100180240120090048992cc004c09400e00d00540886eb80050251811000a040301e37540091598009807800c4c9660020030038992cc0040060090048024012264b3001302500380340150221bae001409460440028100c078dd5002400901b2036301c37540072301e301f301f301f301f301f301f301f301f301f301f0019ba54800a6e9520004888888888cc8a60026052605260526052605200522232598009809000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009819001c66002009008803a014803a05e375c0028190c0bc00502d181780140120090048022060302d00140ac60526ea80122b3001301a0018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130320038cc004012011007402900740bc6eb80050321817800a05a302f002802401200900440c0605a0028158c0a4dd50024566002602200313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606400719800802402200e805200e8178dd7000a064302f00140b4605e00500480240120088180c0b400502b18149baa004801204c40988130c09cdd5001c889660026022604e6ea800e264b300100180144c96600200313259800800c012264b3001001802c4c96600260620071332259800980c000c4c9660020030098992cc0040062b300130350028994c004006005005400444464b3001301e0018992cc00400601f13259800800c04202101080844cc89660020030128992cc00400602713259800981f801c4cc074004896600200500a899192cc00400603101880c44cc89660020031980080840062600a608a00c808203501a80d40690461bad001303f00280c2088303d001304000240f901440f06eac006027013809a07e303c00140e86eb8004c0ec00903c181c800a06e303537540071598009813000c4c96600200300f8992cc004006021010808404226644b300100180944c966002003013809c04e0271332259800800c056264b300100180b405a02d0168992cc004c10800e01701740fc6eb8005042181f800a07a375c002607c00481f8c0f000503a1bae001303b00240f0607200281b8c0d4dd5001c03903220643033375400500a40c900a805402a01481b0c0cc00503118179baa0068acc004c080006264b3001001804c4c96600200300a80544c966002606c0071330140012259800801401e264b3001001899912cc004c080006264b3001001808c4c96600200301280944c966002607c00713301c0012259800801401e264b30010018cc004006260046082007016408101680b405a02c8210c0fc00903d404d03b1bac001809404903e181d800a072303737540071598009814000c4c9660020030118992cc004006025012809404a26644b300100180a44c96600200301580ac05602b1332259800800c05e264b300100180c4062264b30013044003899811000912cc00400a01b13259800800c6600200313002304700380e204c80e407203901c4120608a004821a0328208dd6000c0620308220c10400503f1bae00130400024104607c00281e0dd7000981e801207c303b00140e4606e6ea800e2b3001301f0018992cc00400602313259800800c04a02513259800981f001c4cc07000489660020050078992cc00400633001001898011820801c059020405a02d01680b2084303f00240f501340ec6eb000602501240f8607600281c8c0dcdd5001c041034206840d026004607200660686ea800601d00e807403903a181b801206a805a066375800300a805206c303300140c4605e6ea801a010816102c099807800912cc00400a0131323259800800c02a01500a80544cc896600200300c80644c96600200300d8992cc00400601d00e807403a26644b300100180844c966002003011808c04602313259800981e801c4c02cc0f403202481d0dd7000a07a303a00140e06eb8004c0e400903a181b800a06a375800300c8062070375c002606200481b0c0bc004c0c800903018161baa004803205c3756003005802c0150311817000a058302e002801c00e00700340bc60580028150c0a0dd5001c00502524446530013758605800337566058605a0033758605800d2223259800980b000c4c9660020030038992cc0040062b300130330028cc00400600b004402500440c1004802401200881a0c0c400502f18169baa0048acc004c0780062b3001302d3754009003801205c8acc004c054006264b3001001801c4c966002003004802401200913259800981a001c01a00a8188dd7000a068303100140bc605a6ea80122b300130190018992cc00400600713259800800c566002606600519800800c016008804a008818200900480240110341818800a05e302d3754009159800980c000c4c9660020030038992cc0040062b300130330028cc00400600b004402100440c1004802401200881a0c0c400502f18169baa0048acc004c05c006264b3001001801c4c966002003159800981980146600200300580220108022060802401200900440d060620028178c0b4dd5002400902a205440a8815102a2054302b375400691112cc004c0580462b30013016302c375403513259800980b98169baa0018992cc004006330010018acc004c064c0b8dd5000c528c5282058814200681440a205102840d06062605c6ea800604c8158c8c8cc004004014896600200314c0103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a9159800980f008c566002602c60586ea806a264b30013017302d375400313259800800c66002003159800980d18171baa0018a518a5040b1028400d02881440a205081a0c0c4c0b8dd5000c09902b191919800800802912cc004006298103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a919800911919800800801912cc0040062980103d87a8000899192cc004cdc8802800c56600266e3c014006260226606a606600497ae08a60103d87a800040c1133004004303700340c06eb8c0c4004c0d00050324889660026032605e6ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0e000a330010038992cc004c078006264b3001001803c4c966002003159800981d80144c966002604200313259800800c02a264b30010018acc004c0f800a33001001806402d01b402d03b402e01700b805a07e303c00140e860706ea800a2b300130290018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c11400e02701241086eb40060228228c1080050401bad00130410028072084303f00140f46eb4004c0f800a01681f8c0f000503a181c1baa002804a06a40d4606c6ea800601081c2011008804402103c181c800a06e303537540051598009813000c566002606a6ea800a00f00640d900640c88190c0ccdd5000c0150154015035401600b005802a072303600140d0606c005003801c00e00681b8c0d000503218181baa003800a05a911919800800801912cc004006298103d87a80008992cc004c010006260206606800297ae0899801801981b001205e303400140c8911192cc004c064056264660020026eb0c0d4c0c8dd5181a981b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b18191baa3300200702e2259800800c528c56600264646600200201844b30010018a508acc004cdc79bae30390010038a51899801001181d000a06640dc6eb8c0d8006266004004606e00314a081810344566002603802b13232330010013756606c01c44b30010018a508acc004cdd78019819981b800c528c4cc008008c0e0005031206a3010330333034303530353035303137546068606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a60626ea8cc0040180b52f5c1159800980e80ac4c966002603660626ea80062b300159800acc004c966002604860646ea8006297adef6c6089bab3036303337540028180cc014dd5980b98191baa301730323754606a60646ea80040b6294629410334528c54cc0c12411b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0817a2b300132323300100100b2259800800c528456600266e3cdd7181c000801c528c4cc008008c0e4005032206c375c606a60646ea8cc00801c0ba29462a6606092011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0817a294102f454cc0c12413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640bc660046eb0c0d005c8cdd7981a98191baa0010208acc004c068c0c0dd500f456600264646600200201444b30010018a508acc004cdc79bae30370010038a51899801001181c000a06240d46eb8c058c0c4dd5181a18189baa01e8a518a99817a481356b65795f7369676e65642865787472615f7369676e61746f726965732c20646174756d2e73746f705f6b657929203f2046616c73650014a08172050817102e205c40b84464b3001301c3032375400313259800800c566002603a60666ea8006264b3001001817c4c96600200303081840c20611332259800800c0ca264b3001001819c0ce067033899912cc00400606b13259800800c0da06d1332259800800c0e2264b300100181cc0e6073039899912cc00400607713259800800c4c96600200303d8992cc00400607d03e81f40fa26644b300100182044c966002003041820c1060831332259800800c10e264b30010018992cc00400608b13259800800c11a08d04682344cc89660020030488992cc004006264b300100182544c96600200304b825c12e0971332259800800c136264b30010018992cc00400609f13259800800c1420a105082844cc89660020030528992cc004006264b300100182a44c96600200305582ac1560ab1332259800800c15e264b30010018992cc0040060b313259800800c4c96600200305b8992cc0040062b30013066002899822013112cc00400a330010238cc00406e330010168cc0040463300100c8cc00401e2b3001304d3063375400b13259800800c17e264b300100183041820c1060899912cc0040060c513259800800c18e0c7063831c4cc89660020030658992cc0040060cd066833419a26644b300100183444c966002003069834c1a60d313259800983a001c56600260b260de6ea803e264b3001001835c4c96600200306c83644c96600260ee00713305500122598008014410a264b300100183841c20e10708991801983d8021bae00141ec60f000483b20da83a0dd6000c1b20d883b8c1d000507218381baa00f83520da83520e2375c00283a0c1c400506f1bae001307000241c460dc0028360dd7000983680120dc306b00141a46eb8004c1a800906b1834000a0cc3064375400b05e418505e40d905e40d905e40d905e40d905e40d905e40d913259800800c17e0bf05f82fc4c8c00cc1a8010dd7000a0d43067002419505c418d05c82e41720b88338c1900050621832001416a0b505a82d20ca3062001418060c400505882c41620b08318c18000505e1bae001305f002418060ba00282d8c17400a0a7053829c14d05e182d800a0b2375c00260b400482d8c160005056182c001413a09d04e82720b2305600141506eb8004c1540090561829800a0a23053002824c126093049415060a20028278dd7000982800120a2304e0014130609c00504482241120888278c13000504a1bae001304b002413060920028238dd70009824001209230460014110608c00503c81e40f20788238c1100050421bae00130430024110608200281f8dd6000982000140da06c8208c0f800503c1bae001303d00240f8607600281c8dd7000981d0012076303800140d860686ea800605c818a05d02e81740b903919192cc004c0780062a660669201274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0980062a66066921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981c181a9baa00240c88190c0ccdd5000981b181b981b98199baa301830333754606c60666ea80062a660629201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640c0660060044604864b300130253033375400314800226eb4c0dcc0d0dd5000a0623259800981298199baa0018a6103d87a8000899198008009bab30383035375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980b1981d181c00125eb82298103d87a800040d5133004004303c00340d46eb8c0d8004c0e40050372062330063756603060666ea8c060c0ccdd5000801102a2054181618160018c09c02488966002601e604a6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002606200519800801c66002003009804201c804201c804205c804402201100840c8605e0028168c0bc00a00d00680340190301816800a056375c00260580048168c0a800502818131baa003800a046201500a8054029019180a800980a980b00098089baa0038b201c180800098059baa0118a4d153300949011856616c696461746f722072657475726e65642066616c7365001365640201", + "hash": "b68cda8afdebac748c8a855c4ceb0ef0be54dea86ec2f0dce2e65214" }, { "title": "emergency_request/cancel_order_mint.emergency_cancel_order_request.mint", @@ -1711,6 +1711,12 @@ "dataType": "constructor", "index": 4, "fields": [] + }, + { + "title": "DexOrderBookMigration", + "dataType": "constructor", + "index": 5, + "fields": [] } ] }, diff --git a/validators/dex_order_book/spend.ak b/validators/dex_order_book/spend.ak index 257b4e6..db22061 100644 --- a/validators/dex_order_book/spend.ak +++ b/validators/dex_order_book/spend.ak @@ -6,8 +6,9 @@ use hydra_dex/hydra_commit_utils.{validate_hydra_commit} use hydra_dex/types.{ AppOracleDatum, CombineOrderMerkle, DexOrderBookCombineMerkleTree, DexOrderBookDatum, DexOrderBookEmergencyCancelOrder, DexOrderBookHydraCommit, - DexOrderBookRedeemer, DexOrderBookSpamPreventionWithdraw, - DexOrderBookSplitMerkleTree, HydraOrderBookRedeemer, SplitOrderMerkle, + DexOrderBookMigration, DexOrderBookRedeemer, + DexOrderBookSpamPreventionWithdraw, DexOrderBookSplitMerkleTree, + HydraOrderBookRedeemer, SplitOrderMerkle, } use hydra_dex/utils.{get_app_oracle_datum} @@ -77,6 +78,10 @@ validator dex_order_book(oracle_nft: PolicyId, dex_order_book_nft: PolicyId) { no_auth_token_check? && is_operation_key_signed? } + DexOrderBookMigration -> { + expect Some(datum) = datum_opt + key_signed(extra_signatories, datum.stop_key)? + } } } From 485e86b7f02d22a5aad1b891588446a05f7f643a Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 2 Apr 2026 01:29:04 +0800 Subject: [PATCH 26/30] Revert "feat: dexOrderBook migration" This reverts commit 0fd899c6410d1bc523fd1f7164882bc3adfa8644. --- lib/hydra_dex/types.ak | 1 - plutus.json | 14 ++++---------- validators/dex_order_book/spend.ak | 9 ++------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index f3b0fd9..9dd6b33 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -188,7 +188,6 @@ pub type DexOrderBookRedeemer { DexOrderBookHydraCommit DexOrderBookSpamPreventionWithdraw DexOrderBookEmergencyCancelOrder - DexOrderBookMigration } pub type DexOrderBookDatum { diff --git a/plutus.json b/plutus.json index b373204..50d1823 100644 --- a/plutus.json +++ b/plutus.json @@ -542,8 +542,8 @@ } } ], - "compiledCode": "5918670101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a400d370e90044dc3a4015370e90004dc3a40093013375400e911111192cc004c01000a2b3001301b375401d001808a0388acc004c03000a2b3001301b375401d001808a0388acc004c00c00a2b3001301b375401d001808a0388acc004c01c00a2b3001301b375401d001808a0388acc004c01800a2b3001301b375401d001808a0388acc004c01400a2b3001301b375401d001808a038808a030406080c10182030406033001301a37540152301e301f001980c9baa00d911192cc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f132598009814001c0260108128dd7000a0503025001408c6eb4004c09000a0088128c088005020180f1baa0048acc004c03c006264b3001001801c4c966002003004802401226644b300100180344c96600200315980098138014566002601860446ea8006264b300100180444c966002003009804c02626644b3001001805c4c96600200300c80640320191332259800800c03a264b3001001807c03e01f00f8992cc004c0c000e02301040b46eb80050301816800a056375c00260580048168c0a80050281bad0013029002804a0543027001409460466ea800600e810200e812200f007803c01d0281812800a046375a0026048005004409460440028100c078dd50024566002600c00313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01500a80544c966002605600700c805a050375c0028158c0a00050261bae001302700240a0604a0028118dd6800981200140110251811000a040301e3754009002406c80d901b180e1baa003911919800800801911980180098010014888c966002600e00313259800800c00e264b300100180240120090048992cc004c09400e00d00540886eb80050251811000a040301e37540091598009807800c4c9660020030038992cc0040060090048024012264b3001302500380340150221bae001409460440028100c078dd5002400901b2036301c37540072301e301f301f301f301f301f301f301f301f301f301f0019ba54800a6e9520004888888888cc8a60026052605260526052605200522232598009809000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009819001c66002009008803a014803a05e375c0028190c0bc00502d181780140120090048022060302d00140ac60526ea80122b3001301a0018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130320038cc004012011007402900740bc6eb80050321817800a05a302f002802401200900440c0605a0028158c0a4dd50024566002602200313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606400719800802402200e805200e8178dd7000a064302f00140b4605e00500480240120088180c0b400502b18149baa004801204c40988130c09cdd5001c889660026022604e6ea800e264b300100180144c96600200313259800800c012264b3001001802c4c96600260620071332259800980c000c4c9660020030098992cc0040062b300130350028994c004006005005400444464b3001301e0018992cc00400601f13259800800c04202101080844cc89660020030128992cc00400602713259800981f801c4cc074004896600200500a899192cc00400603101880c44cc89660020031980080840062600a608a00c808203501a80d40690461bad001303f00280c2088303d001304000240f901440f06eac006027013809a07e303c00140e86eb8004c0ec00903c181c800a06e303537540071598009813000c4c96600200300f8992cc004006021010808404226644b300100180944c966002003013809c04e0271332259800800c056264b300100180b405a02d0168992cc004c10800e01701740fc6eb8005042181f800a07a375c002607c00481f8c0f000503a1bae001303b00240f0607200281b8c0d4dd5001c03903220643033375400500a40c900a805402a01481b0c0cc00503118179baa0068acc004c080006264b3001001804c4c96600200300a80544c966002606c0071330140012259800801401e264b3001001899912cc004c080006264b3001001808c4c96600200301280944c966002607c00713301c0012259800801401e264b30010018cc004006260046082007016408101680b405a02c8210c0fc00903d404d03b1bac001809404903e181d800a072303737540071598009814000c4c9660020030118992cc004006025012809404a26644b300100180a44c96600200301580ac05602b1332259800800c05e264b300100180c4062264b30013044003899811000912cc00400a01b13259800800c6600200313002304700380e204c80e407203901c4120608a004821a0328208dd6000c0620308220c10400503f1bae00130400024104607c00281e0dd7000981e801207c303b00140e4606e6ea800e2b3001301f0018992cc00400602313259800800c04a02513259800981f001c4cc07000489660020050078992cc00400633001001898011820801c059020405a02d01680b2084303f00240f501340ec6eb000602501240f8607600281c8c0dcdd5001c041034206840d026004607200660686ea800601d00e807403903a181b801206a805a066375800300a805206c303300140c4605e6ea801a010816102c099807800912cc00400a0131323259800800c02a01500a80544cc896600200300c80644c96600200300d8992cc00400601d00e807403a26644b300100180844c966002003011808c04602313259800981e801c4c02cc0f403202481d0dd7000a07a303a00140e06eb8004c0e400903a181b800a06a375800300c8062070375c002606200481b0c0bc004c0c800903018161baa004803205c3756003005802c0150311817000a058302e002801c00e00700340bc60580028150c0a0dd5001c00502524446530013758605800337566058605a0033758605800d2223259800980b000c4c9660020030038992cc0040062b300130330028cc00400600b004402500440c1004802401200881a0c0c400502f18169baa0048acc004c0780062b3001302d3754009003801205c8acc004c054006264b3001001801c4c966002003004802401200913259800981a001c01a00a8188dd7000a068303100140bc605a6ea80122b300130190018992cc00400600713259800800c566002606600519800800c016008804a008818200900480240110341818800a05e302d3754009159800980c000c4c9660020030038992cc0040062b300130330028cc00400600b004402100440c1004802401200881a0c0c400502f18169baa0048acc004c05c006264b3001001801c4c966002003159800981980146600200300580220108022060802401200900440d060620028178c0b4dd5002400902a205440a8815102a2054302b375400691112cc004c0580462b30013016302c375403513259800980b98169baa0018992cc004006330010018acc004c064c0b8dd5000c528c5282058814200681440a205102840d06062605c6ea800604c8158c8c8cc004004014896600200314c0103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a9159800980f008c566002602c60586ea806a264b30013017302d375400313259800800c66002003159800980d18171baa0018a518a5040b1028400d02881440a205081a0c0c4c0b8dd5000c09902b191919800800802912cc004006298103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a919800911919800800801912cc0040062980103d87a8000899192cc004cdc8802800c56600266e3c014006260226606a606600497ae08a60103d87a800040c1133004004303700340c06eb8c0c4004c0d00050324889660026032605e6ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0e000a330010038992cc004c078006264b3001001803c4c966002003159800981d80144c966002604200313259800800c02a264b30010018acc004c0f800a33001001806402d01b402d03b402e01700b805a07e303c00140e860706ea800a2b300130290018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c11400e02701241086eb40060228228c1080050401bad00130410028072084303f00140f46eb4004c0f800a01681f8c0f000503a181c1baa002804a06a40d4606c6ea800601081c2011008804402103c181c800a06e303537540051598009813000c566002606a6ea800a00f00640d900640c88190c0ccdd5000c0150154015035401600b005802a072303600140d0606c005003801c00e00681b8c0d000503218181baa003800a05a911919800800801912cc004006298103d87a80008992cc004c010006260206606800297ae0899801801981b001205e303400140c8911192cc004c064056264660020026eb0c0d4c0c8dd5181a981b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b18191baa3300200702e2259800800c528c56600264646600200201844b30010018a508acc004cdc79bae30390010038a51899801001181d000a06640dc6eb8c0d8006266004004606e00314a081810344566002603802b13232330010013756606c01c44b30010018a508acc004cdd78019819981b800c528c4cc008008c0e0005031206a3010330333034303530353035303137546068606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a60626ea8cc0040180b52f5c1159800980e80ac4c966002603660626ea80062b300159800acc004c966002604860646ea8006297adef6c6089bab3036303337540028180cc014dd5980b98191baa301730323754606a60646ea80040b6294629410334528c54cc0c12411b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0817a2b300132323300100100b2259800800c528456600266e3cdd7181c000801c528c4cc008008c0e4005032206c375c606a60646ea8cc00801c0ba29462a6606092011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0817a294102f454cc0c12413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640bc660046eb0c0d005c8cdd7981a98191baa0010208acc004c068c0c0dd500f456600264646600200201444b30010018a508acc004cdc79bae30370010038a51899801001181c000a06240d46eb8c058c0c4dd5181a18189baa01e8a518a99817a481356b65795f7369676e65642865787472615f7369676e61746f726965732c20646174756d2e73746f705f6b657929203f2046616c73650014a08172050817102e205c40b84464b3001301c3032375400313259800800c566002603a60666ea8006264b3001001817c4c96600200303081840c20611332259800800c0ca264b3001001819c0ce067033899912cc00400606b13259800800c0da06d1332259800800c0e2264b300100181cc0e6073039899912cc00400607713259800800c4c96600200303d8992cc00400607d03e81f40fa26644b300100182044c966002003041820c1060831332259800800c10e264b30010018992cc00400608b13259800800c11a08d04682344cc89660020030488992cc004006264b300100182544c96600200304b825c12e0971332259800800c136264b30010018992cc00400609f13259800800c1420a105082844cc89660020030528992cc004006264b300100182a44c96600200305582ac1560ab1332259800800c15e264b30010018992cc0040060b313259800800c4c96600200305b8992cc0040062b30013066002899822013112cc00400a330010238cc00406e330010168cc0040463300100c8cc00401e2b3001304d3063375400b13259800800c17e264b300100183041820c1060899912cc0040060c513259800800c18e0c7063831c4cc89660020030658992cc0040060cd066833419a26644b300100183444c966002003069834c1a60d313259800983a001c56600260b260de6ea803e264b3001001835c4c96600200306c83644c96600260ee00713305500122598008014410a264b300100183841c20e10708991801983d8021bae00141ec60f000483b20da83a0dd6000c1b20d883b8c1d000507218381baa00f83520da83520e2375c00283a0c1c400506f1bae001307000241c460dc0028360dd7000983680120dc306b00141a46eb8004c1a800906b1834000a0cc3064375400b05e418505e40d905e40d905e40d905e40d905e40d905e40d913259800800c17e0bf05f82fc4c8c00cc1a8010dd7000a0d43067002419505c418d05c82e41720b88338c1900050621832001416a0b505a82d20ca3062001418060c400505882c41620b08318c18000505e1bae001305f002418060ba00282d8c17400a0a7053829c14d05e182d800a0b2375c00260b400482d8c160005056182c001413a09d04e82720b2305600141506eb8004c1540090561829800a0a23053002824c126093049415060a20028278dd7000982800120a2304e0014130609c00504482241120888278c13000504a1bae001304b002413060920028238dd70009824001209230460014110608c00503c81e40f20788238c1100050421bae00130430024110608200281f8dd6000982000140da06c8208c0f800503c1bae001303d00240f8607600281c8dd7000981d0012076303800140d860686ea800605c818a05d02e81740b903919192cc004c0780062a660669201274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0980062a66066921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981c181a9baa00240c88190c0ccdd5000981b181b981b98199baa301830333754606c60666ea80062a660629201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640c0660060044604864b300130253033375400314800226eb4c0dcc0d0dd5000a0623259800981298199baa0018a6103d87a8000899198008009bab30383035375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980b1981d181c00125eb82298103d87a800040d5133004004303c00340d46eb8c0d8004c0e40050372062330063756603060666ea8c060c0ccdd5000801102a2054181618160018c09c02488966002601e604a6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002606200519800801c66002003009804201c804201c804205c804402201100840c8605e0028168c0bc00a00d00680340190301816800a056375c00260580048168c0a800502818131baa003800a046201500a8054029019180a800980a980b00098089baa0038b201c180800098059baa0118a4d153300949011856616c696461746f722072657475726e65642066616c7365001365640201", - "hash": "b68cda8afdebac748c8a855c4ceb0ef0be54dea86ec2f0dce2e65214" + "compiledCode": "5917bb0101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a4011370e90024dc3a40013013375400e9111192cc004c00c00a2b300130193754019001807a0348acc004c02800a2b300130193754019001807a0348acc004c01000a2b300130193754019001807a0348acc004cdc3a400c005159800980c9baa00c800c03d01a4566002600a005159800980c9baa00c800c03d01a403d016202c405880b10160cc004c060dd50044888c966002600c00313259800800c00e264b300100180240120090048992cc004c08c00e00d00540806eb80050231810000a03c301c37540091598009806800c4c9660020030038992cc0040060090048024012264b3001302300380340150201bae001408c604000280f0c070dd500240090192032301a3754007223233001001003223300300130020029ba54800246038603a0033017375401722232598009803000c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e264b30013026003804c0210231bae001409860460028108dd6800981100140110231810000a03c301c37540091598009806800c4c9660020030038992cc00400600900480244cc89660020030068992cc0040062b300130250028acc004c02cc080dd5000c4c9660020030088992cc004006013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f132598009817001c0460208158dd7000a05c302b00140a46eb8004c0a800902b1814000a04c375a002604e00500940a0604a0028118c084dd5000c01d01e401d022401e00f007803a04c302300140846eb4004c08800a0088118c08000501e180e1baa0048acc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f1332259800800c026264b3001001805402a01500a8992cc004c0a400e01900b40986eb80050291813000a048375c002604a0048130c08c0050211bad001302200280220463020001407860386ea801200480c90192032301a37540072301c301d301d301d301d301d301d301d301d301d301d0019ba54800922222222298009812804c88c8cc00400400c896600200314c0103d87a8000899192cc004cdc8802800c56600266e3c0140062601866052604e00497ae08a60103d87a80004091133004004302b00340906eb8c094004c0a0005026488966002601c60466ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0b000a330010038992cc004c04c006264b3001001803c4c966002003159800981780144c966002602c00313259800800c02a264b30010018acc004c0c800a33001001806402d015402d02f402e01700b805a066303000140b860586ea800a2b3001301d0018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c0e400e02701240d86eb400602281c8c0d80050341bad0013035002807206c303300140c46eb4004c0c800a0168198c0c000502e18161baa002804a05240a460546ea8006010816201100880440210301816800a05630293754005159800980d000c56600260526ea800a00f00640a900640988130c09cdd5000c01500f4015029401600b005802a05a302a00140a06054005003801c00e0068158c0a000502618121baa003800a042911919800800801912cc004006298103d87a80008992cc004c010006260166605000297ae0899801801981500120463028001409922259800980718119baa0038992cc00400600513259800800c00e007003801c4cc89660020030058992cc004006264b3001001803c4c966002003159800981780146600200719800800c02601080920108092010816201100880440210301816800a056302d002803401a00d00640b860560028148dd7000981500120563028001409860486ea800e002810a444b3001300e3023375400713259800800c00a264b30010018992cc00400600913259800800c016264b3001302d003899912cc004c054006264b3001001804c4c966002003159800981880144ca6002003002802a0022223259800980d800c4c96600200300f8992cc004006021010808404226644b300100180944c9660020030138992cc004c0ec00e26603a00244b300100280544c8c96600200301880c406226644b30010018cc004042003130053041006404101a80d406a0348210dd6800981d8014061040181c800981e001207480a20703756003013809c04d03b181c000a06c375c002606e00481c0c0d400503318189baa0038acc004c088006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c04e027013899912cc00400602b13259800800c05a02d01680b44c966002607c00700b80ba076375c00281f0c0ec0050391bae001303a00240ec607000281b0dd7000981b8012070303500140cc60626ea800e01c817102e18179baa002805205c805402a01500a40c8605e0028168c0acdd50034566002603800313259800800c026264b3001001805402a264b3001303200389980a000912cc00400a00f13259800800c4cc8966002603a00313259800800c046264b3001001809404a264b3001303a00389980e000912cc00400a00f13259800800c6600200313002303d00380b203680b405a02d01640f8607600481ca02681b8dd6000c04a02481d0c0dc00503518199baa0038acc004c090006264b3001001808c4c966002003012809404a0251332259800800c052264b300100180ac05602b015899912cc00400602f13259800800c062031132598009820001c4cc088004896600200500d8992cc00400633001001898011821801c071021407203901c80e2088304100240fd01940f46eb00060310184100607a00281d8dd7000981e001207a303a00140e06eb8004c0e400903a181b800a06a30333754007159800980f000c4c9660020030118992cc0040060250128992cc004c0e800e26603800244b3001002803c4c96600200319800800c4c008c0f400e02c80da02d01680b405903e181d8012072809a06e37580030128092074303700140d460666ea800e020818103020601300230350033030375400300e807403a01c81b0c0cc009031402d02f1bac00180540290321817800a05a302b375400d00840a081404cc03c0048966002005009899192cc00400601500a805402a26644b30010018064032264b3001001806c4c96600200300e807403a01d1332259800800c042264b3001001808c0460230118992cc004c0e400e26016607201901240d86eb8005039181b000a068375c002606a00481b0c0cc0050311bac00180640310341bae001302d00240c86056002605c0048160c0a0dd5002401902a1bab001802c01600a8168c0a80050281815001400e007003801a0563028001409860486ea800e00281092222229800981598159815981598158034dd61815003488c966002602860526ea8006264b30010018acc004c054c0a8dd5000c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b3001001816c0b626644b3001001817c4c96600200303081840c20611332259800800c0ca264b30010018992cc00400606913259800800c0d606b03581ac4cc89660020030378992cc00400607103881c40e226644b300100181d44c96600200313259800800c0f2264b300100181ec0f607b03d899912cc00400607f13259800800c4c9660020030418992cc004006085042821410a26644b300100182244c96600200313259800800c11a264b3001001823c11e08f047899912cc00400609313259800800c4c96600200304b8992cc00400609904c826413226644b300100182744c96600200313259800800c142264b30010018992cc0040060a513259800800c56600260ba00513303f02622598008014660020471980080dc6600202d19800808c6600201919800803c566002608a60b46ea8016264b300100182b44c96600200305782bc15e0af1332259800800c166264b300100182d416a0b505a899912cc0040060b913259800800c1760bb05d82ec4cc896600200305f8992cc0040060c10608304182264b3001306b0038acc004c144c198dd5007c4c9660020030628992cc0040060c70638992cc004c1b800e2660a000244b3001002882144c966002003067833c19e0cf13230033072004375c0028390c1bc00906d419106b1bac001831c18d06e1835800a0d23067375401f061419106141a06eb800506b1834000a0cc375c00260ce0048340c1940050631bae0013064002419460c40028300dd7000983080120c4305f001417460b66ea80160aa82c20aa81c20aa81c20aa81c20aa81c20aa81c20aa81c2264b300100182b415a0ad056899180198308021bae001418460bc00482e20a682d20a7053829c14d05e182d800a0b2305b002828c1460a3051417060b200282b8c16400a09f04f827c13d05a182b800a0aa375c00260ac00482b8c150005052182a001412a09504a82520aa305200141406eb8004c1440090521827800a09a304f002822c11608b0454140609a0028258dd70009826001209a304a0014120609400504082041020808258c1200050461bae00130470024120608a0028218c11400a07703b81dc0ed0461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0f400a067033819c0cd03e181d800a072375c002607400481d8c0e00050361bac0013037002816c0b5038181a800a066375c002606800481a8c0c80050301bae001303100240c8605e0028168c0acdd5000c095028409604b025812a060323259800980b000c54cc0a9241274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0740062a66054921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981798161baa00240a48148c0a8dd500098169817181718151baa300e302a3754605a60546ea80062a660509201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a2020202020202020290016409c6600a0044603664b3001301c302a375400314800226eb4c0b8c0acdd5000a0503259800980e18151baa0018a6103d87a8000899198008009bab302f302c375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980a19818981780125eb82298103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e2050330083756601c60546ea8c038c0a8dd50008014888c966002602a00313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606800719800802402200e805a00e8188dd7000a068303100140bc606200500480240120088190c0bc00502d18159baa0048acc004c070006264b3001001801c4c96600200313259800800c016264b3001001803401a00d0068992cc004c0d000e33001004804401d00b401d0311bae00140d060620028178c0c400a00900480240110321817800a05a302b3754009159800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d13259800981a001c66002009008803a016803a062375c00281a0c0c400502f181880140120090048022064302f00140b460566ea801200481410282050302937540069111194c004dd61817800cdd598179818000c888c966002603400313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b300130210018acc004c0c0dd5002400e004818a2b3001301b0018992cc00400600713259800800c01200900480244c966002606e007006802a068375c00281b8c0d000503218181baa0048acc004cdc3a400c00313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b3001301c0018992cc00400600713259800800c566002606c00519800800c0160088062008819a0090048024011037181a000a0643030375400915980099b8748028006264b3001001801c4c966002003159800981b00146600200300580220188022066802401200900440dc60680028190c0c0dd5002400902d205a40b4816902d205a302e37540069112cc004c06404a2b30013019302e375403913259800980d18179baa0018992cc004006330010018acc004cdc3a401460606ea80062946294102e40a900340aa05502a815206c30333030375400302840b464646600200200844b30010018a6103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800981000945660026032605c6ea8072264b3001301a302f375400313259800800c66002003159800980e98181baa0018a518a5040b902a400d02a81540aa05481b0c0ccc0c0dd5000c0a102d191919800800802112cc004006298103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800980d00944c8cc004004dd6181998181baa303330343034303430343034303430343034303430343034303430343034303430343034303037546600e01005844b30010018a518acc004c8c8cc00400401c896600200314a115980099b8f375c606e00200714a3133002002303800140c481a8dd7181a000c4cc008008c0d4006294102e20648acc004c06c04a26464660020026eacc0d0028896600200314a115980099baf003303130350018a51899801001181b000a05e40cc601e660626064606660666066605e6ea8c0c8c0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0bcdd519803003815a5eb82264b3001301a302f3754003159800acc0056600264b300130223030375400314bd6f7b63044dd5981a18189baa00140b86601c6eacc050c0c0dd5180a18181baa30333030375400205714a314a0818a29462a6605c92011b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0816a2b30013232330010010062259800800c528456600266e3cdd7181b000801c528c4cc008008c0dc0050302068375c606660606ea8cc01c0200b229462a6605c92011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0816a294102d454cc0b92413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640b4660166eb0c0c805c8cdd7981998181baa00101e40b0816102c2058181798178020402a01500a8052032301500130153016001301137540071640383010001300b3754023149a2a660129211856616c696461746f722072657475726e65642066616c7365001365640201", + "hash": "60c6788a6d21574f92338b5908be8b763dad113d795127ee493f3bac" }, { "title": "dex_order_book/spend.dex_order_book.else", @@ -564,8 +564,8 @@ } } ], - "compiledCode": "5918670101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a400d370e90044dc3a4015370e90004dc3a40093013375400e911111192cc004c01000a2b3001301b375401d001808a0388acc004c03000a2b3001301b375401d001808a0388acc004c00c00a2b3001301b375401d001808a0388acc004c01c00a2b3001301b375401d001808a0388acc004c01800a2b3001301b375401d001808a0388acc004c01400a2b3001301b375401d001808a038808a030406080c10182030406033001301a37540152301e301f001980c9baa00d911192cc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f132598009814001c0260108128dd7000a0503025001408c6eb4004c09000a0088128c088005020180f1baa0048acc004c03c006264b3001001801c4c966002003004802401226644b300100180344c96600200315980098138014566002601860446ea8006264b300100180444c966002003009804c02626644b3001001805c4c96600200300c80640320191332259800800c03a264b3001001807c03e01f00f8992cc004c0c000e02301040b46eb80050301816800a056375c00260580048168c0a80050281bad0013029002804a0543027001409460466ea800600e810200e812200f007803c01d0281812800a046375a0026048005004409460440028100c078dd50024566002600c00313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01500a80544c966002605600700c805a050375c0028158c0a00050261bae001302700240a0604a0028118dd6800981200140110251811000a040301e3754009002406c80d901b180e1baa003911919800800801911980180098010014888c966002600e00313259800800c00e264b300100180240120090048992cc004c09400e00d00540886eb80050251811000a040301e37540091598009807800c4c9660020030038992cc0040060090048024012264b3001302500380340150221bae001409460440028100c078dd5002400901b2036301c37540072301e301f301f301f301f301f301f301f301f301f301f0019ba54800a6e9520004888888888cc8a60026052605260526052605200522232598009809000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009819001c66002009008803a014803a05e375c0028190c0bc00502d181780140120090048022060302d00140ac60526ea80122b3001301a0018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130320038cc004012011007402900740bc6eb80050321817800a05a302f002802401200900440c0605a0028158c0a4dd50024566002602200313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606400719800802402200e805200e8178dd7000a064302f00140b4605e00500480240120088180c0b400502b18149baa004801204c40988130c09cdd5001c889660026022604e6ea800e264b300100180144c96600200313259800800c012264b3001001802c4c96600260620071332259800980c000c4c9660020030098992cc0040062b300130350028994c004006005005400444464b3001301e0018992cc00400601f13259800800c04202101080844cc89660020030128992cc00400602713259800981f801c4cc074004896600200500a899192cc00400603101880c44cc89660020031980080840062600a608a00c808203501a80d40690461bad001303f00280c2088303d001304000240f901440f06eac006027013809a07e303c00140e86eb8004c0ec00903c181c800a06e303537540071598009813000c4c96600200300f8992cc004006021010808404226644b300100180944c966002003013809c04e0271332259800800c056264b300100180b405a02d0168992cc004c10800e01701740fc6eb8005042181f800a07a375c002607c00481f8c0f000503a1bae001303b00240f0607200281b8c0d4dd5001c03903220643033375400500a40c900a805402a01481b0c0cc00503118179baa0068acc004c080006264b3001001804c4c96600200300a80544c966002606c0071330140012259800801401e264b3001001899912cc004c080006264b3001001808c4c96600200301280944c966002607c00713301c0012259800801401e264b30010018cc004006260046082007016408101680b405a02c8210c0fc00903d404d03b1bac001809404903e181d800a072303737540071598009814000c4c9660020030118992cc004006025012809404a26644b300100180a44c96600200301580ac05602b1332259800800c05e264b300100180c4062264b30013044003899811000912cc00400a01b13259800800c6600200313002304700380e204c80e407203901c4120608a004821a0328208dd6000c0620308220c10400503f1bae00130400024104607c00281e0dd7000981e801207c303b00140e4606e6ea800e2b3001301f0018992cc00400602313259800800c04a02513259800981f001c4cc07000489660020050078992cc00400633001001898011820801c059020405a02d01680b2084303f00240f501340ec6eb000602501240f8607600281c8c0dcdd5001c041034206840d026004607200660686ea800601d00e807403903a181b801206a805a066375800300a805206c303300140c4605e6ea801a010816102c099807800912cc00400a0131323259800800c02a01500a80544cc896600200300c80644c96600200300d8992cc00400601d00e807403a26644b300100180844c966002003011808c04602313259800981e801c4c02cc0f403202481d0dd7000a07a303a00140e06eb8004c0e400903a181b800a06a375800300c8062070375c002606200481b0c0bc004c0c800903018161baa004803205c3756003005802c0150311817000a058302e002801c00e00700340bc60580028150c0a0dd5001c00502524446530013758605800337566058605a0033758605800d2223259800980b000c4c9660020030038992cc0040062b300130330028cc00400600b004402500440c1004802401200881a0c0c400502f18169baa0048acc004c0780062b3001302d3754009003801205c8acc004c054006264b3001001801c4c966002003004802401200913259800981a001c01a00a8188dd7000a068303100140bc605a6ea80122b300130190018992cc00400600713259800800c566002606600519800800c016008804a008818200900480240110341818800a05e302d3754009159800980c000c4c9660020030038992cc0040062b300130330028cc00400600b004402100440c1004802401200881a0c0c400502f18169baa0048acc004c05c006264b3001001801c4c966002003159800981980146600200300580220108022060802401200900440d060620028178c0b4dd5002400902a205440a8815102a2054302b375400691112cc004c0580462b30013016302c375403513259800980b98169baa0018992cc004006330010018acc004c064c0b8dd5000c528c5282058814200681440a205102840d06062605c6ea800604c8158c8c8cc004004014896600200314c0103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a9159800980f008c566002602c60586ea806a264b30013017302d375400313259800800c66002003159800980d18171baa0018a518a5040b1028400d02881440a205081a0c0c4c0b8dd5000c09902b191919800800802912cc004006298103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a919800911919800800801912cc0040062980103d87a8000899192cc004cdc8802800c56600266e3c014006260226606a606600497ae08a60103d87a800040c1133004004303700340c06eb8c0c4004c0d00050324889660026032605e6ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0e000a330010038992cc004c078006264b3001001803c4c966002003159800981d80144c966002604200313259800800c02a264b30010018acc004c0f800a33001001806402d01b402d03b402e01700b805a07e303c00140e860706ea800a2b300130290018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c11400e02701241086eb40060228228c1080050401bad00130410028072084303f00140f46eb4004c0f800a01681f8c0f000503a181c1baa002804a06a40d4606c6ea800601081c2011008804402103c181c800a06e303537540051598009813000c566002606a6ea800a00f00640d900640c88190c0ccdd5000c0150154015035401600b005802a072303600140d0606c005003801c00e00681b8c0d000503218181baa003800a05a911919800800801912cc004006298103d87a80008992cc004c010006260206606800297ae0899801801981b001205e303400140c8911192cc004c064056264660020026eb0c0d4c0c8dd5181a981b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b18191baa3300200702e2259800800c528c56600264646600200201844b30010018a508acc004cdc79bae30390010038a51899801001181d000a06640dc6eb8c0d8006266004004606e00314a081810344566002603802b13232330010013756606c01c44b30010018a508acc004cdd78019819981b800c528c4cc008008c0e0005031206a3010330333034303530353035303137546068606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a60626ea8cc0040180b52f5c1159800980e80ac4c966002603660626ea80062b300159800acc004c966002604860646ea8006297adef6c6089bab3036303337540028180cc014dd5980b98191baa301730323754606a60646ea80040b6294629410334528c54cc0c12411b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0817a2b300132323300100100b2259800800c528456600266e3cdd7181c000801c528c4cc008008c0e4005032206c375c606a60646ea8cc00801c0ba29462a6606092011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0817a294102f454cc0c12413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640bc660046eb0c0d005c8cdd7981a98191baa0010208acc004c068c0c0dd500f456600264646600200201444b30010018a508acc004cdc79bae30370010038a51899801001181c000a06240d46eb8c058c0c4dd5181a18189baa01e8a518a99817a481356b65795f7369676e65642865787472615f7369676e61746f726965732c20646174756d2e73746f705f6b657929203f2046616c73650014a08172050817102e205c40b84464b3001301c3032375400313259800800c566002603a60666ea8006264b3001001817c4c96600200303081840c20611332259800800c0ca264b3001001819c0ce067033899912cc00400606b13259800800c0da06d1332259800800c0e2264b300100181cc0e6073039899912cc00400607713259800800c4c96600200303d8992cc00400607d03e81f40fa26644b300100182044c966002003041820c1060831332259800800c10e264b30010018992cc00400608b13259800800c11a08d04682344cc89660020030488992cc004006264b300100182544c96600200304b825c12e0971332259800800c136264b30010018992cc00400609f13259800800c1420a105082844cc89660020030528992cc004006264b300100182a44c96600200305582ac1560ab1332259800800c15e264b30010018992cc0040060b313259800800c4c96600200305b8992cc0040062b30013066002899822013112cc00400a330010238cc00406e330010168cc0040463300100c8cc00401e2b3001304d3063375400b13259800800c17e264b300100183041820c1060899912cc0040060c513259800800c18e0c7063831c4cc89660020030658992cc0040060cd066833419a26644b300100183444c966002003069834c1a60d313259800983a001c56600260b260de6ea803e264b3001001835c4c96600200306c83644c96600260ee00713305500122598008014410a264b300100183841c20e10708991801983d8021bae00141ec60f000483b20da83a0dd6000c1b20d883b8c1d000507218381baa00f83520da83520e2375c00283a0c1c400506f1bae001307000241c460dc0028360dd7000983680120dc306b00141a46eb8004c1a800906b1834000a0cc3064375400b05e418505e40d905e40d905e40d905e40d905e40d905e40d913259800800c17e0bf05f82fc4c8c00cc1a8010dd7000a0d43067002419505c418d05c82e41720b88338c1900050621832001416a0b505a82d20ca3062001418060c400505882c41620b08318c18000505e1bae001305f002418060ba00282d8c17400a0a7053829c14d05e182d800a0b2375c00260b400482d8c160005056182c001413a09d04e82720b2305600141506eb8004c1540090561829800a0a23053002824c126093049415060a20028278dd7000982800120a2304e0014130609c00504482241120888278c13000504a1bae001304b002413060920028238dd70009824001209230460014110608c00503c81e40f20788238c1100050421bae00130430024110608200281f8dd6000982000140da06c8208c0f800503c1bae001303d00240f8607600281c8dd7000981d0012076303800140d860686ea800605c818a05d02e81740b903919192cc004c0780062a660669201274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0980062a66066921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981c181a9baa00240c88190c0ccdd5000981b181b981b98199baa301830333754606c60666ea80062a660629201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640c0660060044604864b300130253033375400314800226eb4c0dcc0d0dd5000a0623259800981298199baa0018a6103d87a8000899198008009bab30383035375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980b1981d181c00125eb82298103d87a800040d5133004004303c00340d46eb8c0d8004c0e40050372062330063756603060666ea8c060c0ccdd5000801102a2054181618160018c09c02488966002601e604a6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002606200519800801c66002003009804201c804201c804205c804402201100840c8605e0028168c0bc00a00d00680340190301816800a056375c00260580048168c0a800502818131baa003800a046201500a8054029019180a800980a980b00098089baa0038b201c180800098059baa0118a4d153300949011856616c696461746f722072657475726e65642066616c7365001365640201", - "hash": "b68cda8afdebac748c8a855c4ceb0ef0be54dea86ec2f0dce2e65214" + "compiledCode": "5917bb0101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a4011370e90024dc3a40013013375400e9111192cc004c00c00a2b300130193754019001807a0348acc004c02800a2b300130193754019001807a0348acc004c01000a2b300130193754019001807a0348acc004cdc3a400c005159800980c9baa00c800c03d01a4566002600a005159800980c9baa00c800c03d01a403d016202c405880b10160cc004c060dd50044888c966002600c00313259800800c00e264b300100180240120090048992cc004c08c00e00d00540806eb80050231810000a03c301c37540091598009806800c4c9660020030038992cc0040060090048024012264b3001302300380340150201bae001408c604000280f0c070dd500240090192032301a3754007223233001001003223300300130020029ba54800246038603a0033017375401722232598009803000c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e264b30013026003804c0210231bae001409860460028108dd6800981100140110231810000a03c301c37540091598009806800c4c9660020030038992cc00400600900480244cc89660020030068992cc0040062b300130250028acc004c02cc080dd5000c4c9660020030088992cc004006013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f132598009817001c0460208158dd7000a05c302b00140a46eb8004c0a800902b1814000a04c375a002604e00500940a0604a0028118c084dd5000c01d01e401d022401e00f007803a04c302300140846eb4004c08800a0088118c08000501e180e1baa0048acc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f1332259800800c026264b3001001805402a01500a8992cc004c0a400e01900b40986eb80050291813000a048375c002604a0048130c08c0050211bad001302200280220463020001407860386ea801200480c90192032301a37540072301c301d301d301d301d301d301d301d301d301d301d0019ba54800922222222298009812804c88c8cc00400400c896600200314c0103d87a8000899192cc004cdc8802800c56600266e3c0140062601866052604e00497ae08a60103d87a80004091133004004302b00340906eb8c094004c0a0005026488966002601c60466ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0b000a330010038992cc004c04c006264b3001001803c4c966002003159800981780144c966002602c00313259800800c02a264b30010018acc004c0c800a33001001806402d015402d02f402e01700b805a066303000140b860586ea800a2b3001301d0018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c0e400e02701240d86eb400602281c8c0d80050341bad0013035002807206c303300140c46eb4004c0c800a0168198c0c000502e18161baa002804a05240a460546ea8006010816201100880440210301816800a05630293754005159800980d000c56600260526ea800a00f00640a900640988130c09cdd5000c01500f4015029401600b005802a05a302a00140a06054005003801c00e0068158c0a000502618121baa003800a042911919800800801912cc004006298103d87a80008992cc004c010006260166605000297ae0899801801981500120463028001409922259800980718119baa0038992cc00400600513259800800c00e007003801c4cc89660020030058992cc004006264b3001001803c4c966002003159800981780146600200719800800c02601080920108092010816201100880440210301816800a056302d002803401a00d00640b860560028148dd7000981500120563028001409860486ea800e002810a444b3001300e3023375400713259800800c00a264b30010018992cc00400600913259800800c016264b3001302d003899912cc004c054006264b3001001804c4c966002003159800981880144ca6002003002802a0022223259800980d800c4c96600200300f8992cc004006021010808404226644b300100180944c9660020030138992cc004c0ec00e26603a00244b300100280544c8c96600200301880c406226644b30010018cc004042003130053041006404101a80d406a0348210dd6800981d8014061040181c800981e001207480a20703756003013809c04d03b181c000a06c375c002606e00481c0c0d400503318189baa0038acc004c088006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c04e027013899912cc00400602b13259800800c05a02d01680b44c966002607c00700b80ba076375c00281f0c0ec0050391bae001303a00240ec607000281b0dd7000981b8012070303500140cc60626ea800e01c817102e18179baa002805205c805402a01500a40c8605e0028168c0acdd50034566002603800313259800800c026264b3001001805402a264b3001303200389980a000912cc00400a00f13259800800c4cc8966002603a00313259800800c046264b3001001809404a264b3001303a00389980e000912cc00400a00f13259800800c6600200313002303d00380b203680b405a02d01640f8607600481ca02681b8dd6000c04a02481d0c0dc00503518199baa0038acc004c090006264b3001001808c4c966002003012809404a0251332259800800c052264b300100180ac05602b015899912cc00400602f13259800800c062031132598009820001c4cc088004896600200500d8992cc00400633001001898011821801c071021407203901c80e2088304100240fd01940f46eb00060310184100607a00281d8dd7000981e001207a303a00140e06eb8004c0e400903a181b800a06a30333754007159800980f000c4c9660020030118992cc0040060250128992cc004c0e800e26603800244b3001002803c4c96600200319800800c4c008c0f400e02c80da02d01680b405903e181d8012072809a06e37580030128092074303700140d460666ea800e020818103020601300230350033030375400300e807403a01c81b0c0cc009031402d02f1bac00180540290321817800a05a302b375400d00840a081404cc03c0048966002005009899192cc00400601500a805402a26644b30010018064032264b3001001806c4c96600200300e807403a01d1332259800800c042264b3001001808c0460230118992cc004c0e400e26016607201901240d86eb8005039181b000a068375c002606a00481b0c0cc0050311bac00180640310341bae001302d00240c86056002605c0048160c0a0dd5002401902a1bab001802c01600a8168c0a80050281815001400e007003801a0563028001409860486ea800e00281092222229800981598159815981598158034dd61815003488c966002602860526ea8006264b30010018acc004c054c0a8dd5000c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b3001001816c0b626644b3001001817c4c96600200303081840c20611332259800800c0ca264b30010018992cc00400606913259800800c0d606b03581ac4cc89660020030378992cc00400607103881c40e226644b300100181d44c96600200313259800800c0f2264b300100181ec0f607b03d899912cc00400607f13259800800c4c9660020030418992cc004006085042821410a26644b300100182244c96600200313259800800c11a264b3001001823c11e08f047899912cc00400609313259800800c4c96600200304b8992cc00400609904c826413226644b300100182744c96600200313259800800c142264b30010018992cc0040060a513259800800c56600260ba00513303f02622598008014660020471980080dc6600202d19800808c6600201919800803c566002608a60b46ea8016264b300100182b44c96600200305782bc15e0af1332259800800c166264b300100182d416a0b505a899912cc0040060b913259800800c1760bb05d82ec4cc896600200305f8992cc0040060c10608304182264b3001306b0038acc004c144c198dd5007c4c9660020030628992cc0040060c70638992cc004c1b800e2660a000244b3001002882144c966002003067833c19e0cf13230033072004375c0028390c1bc00906d419106b1bac001831c18d06e1835800a0d23067375401f061419106141a06eb800506b1834000a0cc375c00260ce0048340c1940050631bae0013064002419460c40028300dd7000983080120c4305f001417460b66ea80160aa82c20aa81c20aa81c20aa81c20aa81c20aa81c20aa81c2264b300100182b415a0ad056899180198308021bae001418460bc00482e20a682d20a7053829c14d05e182d800a0b2305b002828c1460a3051417060b200282b8c16400a09f04f827c13d05a182b800a0aa375c00260ac00482b8c150005052182a001412a09504a82520aa305200141406eb8004c1440090521827800a09a304f002822c11608b0454140609a0028258dd70009826001209a304a0014120609400504082041020808258c1200050461bae00130470024120608a0028218c11400a07703b81dc0ed0461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0f400a067033819c0cd03e181d800a072375c002607400481d8c0e00050361bac0013037002816c0b5038181a800a066375c002606800481a8c0c80050301bae001303100240c8605e0028168c0acdd5000c095028409604b025812a060323259800980b000c54cc0a9241274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0740062a66054921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981798161baa00240a48148c0a8dd500098169817181718151baa300e302a3754605a60546ea80062a660509201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a2020202020202020290016409c6600a0044603664b3001301c302a375400314800226eb4c0b8c0acdd5000a0503259800980e18151baa0018a6103d87a8000899198008009bab302f302c375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980a19818981780125eb82298103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e2050330083756601c60546ea8c038c0a8dd50008014888c966002602a00313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606800719800802402200e805a00e8188dd7000a068303100140bc606200500480240120088190c0bc00502d18159baa0048acc004c070006264b3001001801c4c96600200313259800800c016264b3001001803401a00d0068992cc004c0d000e33001004804401d00b401d0311bae00140d060620028178c0c400a00900480240110321817800a05a302b3754009159800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d13259800981a001c66002009008803a016803a062375c00281a0c0c400502f181880140120090048022064302f00140b460566ea801200481410282050302937540069111194c004dd61817800cdd598179818000c888c966002603400313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b300130210018acc004c0c0dd5002400e004818a2b3001301b0018992cc00400600713259800800c01200900480244c966002606e007006802a068375c00281b8c0d000503218181baa0048acc004cdc3a400c00313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b3001301c0018992cc00400600713259800800c566002606c00519800800c0160088062008819a0090048024011037181a000a0643030375400915980099b8748028006264b3001001801c4c966002003159800981b00146600200300580220188022066802401200900440dc60680028190c0c0dd5002400902d205a40b4816902d205a302e37540069112cc004c06404a2b30013019302e375403913259800980d18179baa0018992cc004006330010018acc004cdc3a401460606ea80062946294102e40a900340aa05502a815206c30333030375400302840b464646600200200844b30010018a6103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800981000945660026032605c6ea8072264b3001301a302f375400313259800800c66002003159800980e98181baa0018a518a5040b902a400d02a81540aa05481b0c0ccc0c0dd5000c0a102d191919800800802112cc004006298103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800980d00944c8cc004004dd6181998181baa303330343034303430343034303430343034303430343034303430343034303430343034303037546600e01005844b30010018a518acc004c8c8cc00400401c896600200314a115980099b8f375c606e00200714a3133002002303800140c481a8dd7181a000c4cc008008c0d4006294102e20648acc004c06c04a26464660020026eacc0d0028896600200314a115980099baf003303130350018a51899801001181b000a05e40cc601e660626064606660666066605e6ea8c0c8c0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0bcdd519803003815a5eb82264b3001301a302f3754003159800acc0056600264b300130223030375400314bd6f7b63044dd5981a18189baa00140b86601c6eacc050c0c0dd5180a18181baa30333030375400205714a314a0818a29462a6605c92011b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0816a2b30013232330010010062259800800c528456600266e3cdd7181b000801c528c4cc008008c0dc0050302068375c606660606ea8cc01c0200b229462a6605c92011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0816a294102d454cc0b92413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640b4660166eb0c0c805c8cdd7981998181baa00101e40b0816102c2058181798178020402a01500a8052032301500130153016001301137540071640383010001300b3754023149a2a660129211856616c696461746f722072657475726e65642066616c7365001365640201", + "hash": "60c6788a6d21574f92338b5908be8b763dad113d795127ee493f3bac" }, { "title": "emergency_request/cancel_order_mint.emergency_cancel_order_request.mint", @@ -1711,12 +1711,6 @@ "dataType": "constructor", "index": 4, "fields": [] - }, - { - "title": "DexOrderBookMigration", - "dataType": "constructor", - "index": 5, - "fields": [] } ] }, diff --git a/validators/dex_order_book/spend.ak b/validators/dex_order_book/spend.ak index db22061..257b4e6 100644 --- a/validators/dex_order_book/spend.ak +++ b/validators/dex_order_book/spend.ak @@ -6,9 +6,8 @@ use hydra_dex/hydra_commit_utils.{validate_hydra_commit} use hydra_dex/types.{ AppOracleDatum, CombineOrderMerkle, DexOrderBookCombineMerkleTree, DexOrderBookDatum, DexOrderBookEmergencyCancelOrder, DexOrderBookHydraCommit, - DexOrderBookMigration, DexOrderBookRedeemer, - DexOrderBookSpamPreventionWithdraw, DexOrderBookSplitMerkleTree, - HydraOrderBookRedeemer, SplitOrderMerkle, + DexOrderBookRedeemer, DexOrderBookSpamPreventionWithdraw, + DexOrderBookSplitMerkleTree, HydraOrderBookRedeemer, SplitOrderMerkle, } use hydra_dex/utils.{get_app_oracle_datum} @@ -78,10 +77,6 @@ validator dex_order_book(oracle_nft: PolicyId, dex_order_book_nft: PolicyId) { no_auth_token_check? && is_operation_key_signed? } - DexOrderBookMigration -> { - expect Some(datum) = datum_opt - key_signed(extra_signatories, datum.stop_key)? - } } } From ad46facf95b9ff45b160f23e35f9eac823207cb0 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 2 Apr 2026 01:49:53 +0800 Subject: [PATCH 27/30] fix: redeemer type --- lib/hydra_dex/types.ak | 8 ++++---- validators/hydra_account/core.ak | 11 +++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index 9dd6b33..2430204 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -249,6 +249,10 @@ pub type HydraAccountOperation { ProcessSplitUtxosAtOpen { tree_or_proofs_with_token_map: TreeOrProofsWithTokenMap, } +} + +pub type ProcessHydraAccountOtherRedeemer { + ProcessMigration { account: UserAccount } ProcessVaultDeposit(ByteArray, List, TokenMap, SharesMPFAction) ProcessVaultWithdrawal( ByteArray, @@ -259,10 +263,6 @@ pub type HydraAccountOperation { ) } -pub type ProcessMigrationRedeemer { - ProcessMigration { account: UserAccount } -} - // 9 - HydraOrderBook pub type HydraOrderBookIntent { diff --git a/validators/hydra_account/core.ak b/validators/hydra_account/core.ak index f408c4d..6ce8439 100644 --- a/validators/hydra_account/core.ak +++ b/validators/hydra_account/core.ak @@ -16,7 +16,7 @@ use hydra_dex/types.{ DexOrderBookDatum, HydraAccountMigrate, HydraAccountOperate, HydraAccountOperation, HydraAccountRedeemer, HydraAccountSpamPreventionWithdraw, HydraAccountTrade, ProcessCancelWithdrawal, - ProcessCombineUtxosAtClose, ProcessMigration, ProcessMigrationRedeemer, + ProcessCombineUtxosAtClose, ProcessHydraAccountOtherRedeemer, ProcessMigration, ProcessSameAccountTransferal, ProcessSplitUtxosAtOpen, ProcessTransferal, ProcessVaultDeposit, ProcessVaultWithdrawal, ProcessWithdrawal, TreeOrProofsWithTokenMap, UserAccount, @@ -103,6 +103,12 @@ validator hydra_account(dex_oracle_nft: PolicyId) { tree_or_proofs_with_token_map combine_utxos_at_close(dex_oracle_nft, proof, token_map, tx) } + } + } else { + expect operation: ProcessHydraAccountOtherRedeemer = redeemer + when operation is { + ProcessMigration { account } -> + migration(dex_oracle_nft, account, credential, tx) ProcessVaultDeposit(prices_message, signatures, token_map, mpf_action) -> vault_deposit( dex_oracle_nft, @@ -129,9 +135,6 @@ validator hydra_account(dex_oracle_nft: PolicyId) { tx, ) } - } else { - expect ProcessMigration { account }: ProcessMigrationRedeemer = redeemer - migration(dex_oracle_nft, account, credential, tx) } } From d8dfa82a59fdcf6dd294bfec99368f8f4c47ecf6 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 2 Apr 2026 01:59:48 +0800 Subject: [PATCH 28/30] fix: revert intent change --- validators/hydra_user_intent.ak | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/validators/hydra_user_intent.ak b/validators/hydra_user_intent.ak index aa19c23..d3679d4 100644 --- a/validators/hydra_user_intent.ak +++ b/validators/hydra_user_intent.ak @@ -3,8 +3,8 @@ use cardano/address.{from_script} use cardano/assets.{PolicyId, flatten} use cardano/transaction.{OutputReference, Transaction} use cocktail.{ - key_signed, output_inline_datum, outputs_at_with_policy, outputs_with_policy, - policy_only_minted_token, + key_signed, only_minted_token, output_inline_datum, outputs_at_with_policy, + outputs_with_policy, } use hydra_dex/account_utils.{master_auth_by_account, trade_auth_by_account} use hydra_dex/types.{ @@ -61,7 +61,7 @@ validator hydra_user_intent(dex_oracle_nft: PolicyId) { from_script(oracle.hydra_user_intent_script_hash) when redeemer is { MintTradeIntent { account, intent } -> { - let token_check = policy_only_minted_token(mint, policy_id, "", 1) + let token_check = only_minted_token(mint, policy_id, "", 1) let only_output_check = when outputs_at_with_policy( @@ -85,7 +85,7 @@ validator hydra_user_intent(dex_oracle_nft: PolicyId) { token_check? && only_output_check? && is_account_auth? } MintMasterIntent { account, intent } -> { - let token_check = policy_only_minted_token(mint, policy_id, "", 1) + let token_check = only_minted_token(mint, policy_id, "", 1) let only_output_check = when outputs_at_with_policy( From dfa87762235b6415fbe4c8a093b2a15a5b94e95e Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 2 Apr 2026 02:13:31 +0800 Subject: [PATCH 29/30] feat: dexOrderBook migration --- lib/hydra_dex/types.ak | 1 + plutus.json | 14 ++++++++++---- validators/dex_order_book/spend.ak | 9 +++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/hydra_dex/types.ak b/lib/hydra_dex/types.ak index 2430204..454237b 100644 --- a/lib/hydra_dex/types.ak +++ b/lib/hydra_dex/types.ak @@ -188,6 +188,7 @@ pub type DexOrderBookRedeemer { DexOrderBookHydraCommit DexOrderBookSpamPreventionWithdraw DexOrderBookEmergencyCancelOrder + DexOrderBookMigration } pub type DexOrderBookDatum { diff --git a/plutus.json b/plutus.json index 50d1823..b373204 100644 --- a/plutus.json +++ b/plutus.json @@ -542,8 +542,8 @@ } } ], - "compiledCode": "5917bb0101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a4011370e90024dc3a40013013375400e9111192cc004c00c00a2b300130193754019001807a0348acc004c02800a2b300130193754019001807a0348acc004c01000a2b300130193754019001807a0348acc004cdc3a400c005159800980c9baa00c800c03d01a4566002600a005159800980c9baa00c800c03d01a403d016202c405880b10160cc004c060dd50044888c966002600c00313259800800c00e264b300100180240120090048992cc004c08c00e00d00540806eb80050231810000a03c301c37540091598009806800c4c9660020030038992cc0040060090048024012264b3001302300380340150201bae001408c604000280f0c070dd500240090192032301a3754007223233001001003223300300130020029ba54800246038603a0033017375401722232598009803000c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e264b30013026003804c0210231bae001409860460028108dd6800981100140110231810000a03c301c37540091598009806800c4c9660020030038992cc00400600900480244cc89660020030068992cc0040062b300130250028acc004c02cc080dd5000c4c9660020030088992cc004006013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f132598009817001c0460208158dd7000a05c302b00140a46eb8004c0a800902b1814000a04c375a002604e00500940a0604a0028118c084dd5000c01d01e401d022401e00f007803a04c302300140846eb4004c08800a0088118c08000501e180e1baa0048acc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f1332259800800c026264b3001001805402a01500a8992cc004c0a400e01900b40986eb80050291813000a048375c002604a0048130c08c0050211bad001302200280220463020001407860386ea801200480c90192032301a37540072301c301d301d301d301d301d301d301d301d301d301d0019ba54800922222222298009812804c88c8cc00400400c896600200314c0103d87a8000899192cc004cdc8802800c56600266e3c0140062601866052604e00497ae08a60103d87a80004091133004004302b00340906eb8c094004c0a0005026488966002601c60466ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0b000a330010038992cc004c04c006264b3001001803c4c966002003159800981780144c966002602c00313259800800c02a264b30010018acc004c0c800a33001001806402d015402d02f402e01700b805a066303000140b860586ea800a2b3001301d0018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c0e400e02701240d86eb400602281c8c0d80050341bad0013035002807206c303300140c46eb4004c0c800a0168198c0c000502e18161baa002804a05240a460546ea8006010816201100880440210301816800a05630293754005159800980d000c56600260526ea800a00f00640a900640988130c09cdd5000c01500f4015029401600b005802a05a302a00140a06054005003801c00e0068158c0a000502618121baa003800a042911919800800801912cc004006298103d87a80008992cc004c010006260166605000297ae0899801801981500120463028001409922259800980718119baa0038992cc00400600513259800800c00e007003801c4cc89660020030058992cc004006264b3001001803c4c966002003159800981780146600200719800800c02601080920108092010816201100880440210301816800a056302d002803401a00d00640b860560028148dd7000981500120563028001409860486ea800e002810a444b3001300e3023375400713259800800c00a264b30010018992cc00400600913259800800c016264b3001302d003899912cc004c054006264b3001001804c4c966002003159800981880144ca6002003002802a0022223259800980d800c4c96600200300f8992cc004006021010808404226644b300100180944c9660020030138992cc004c0ec00e26603a00244b300100280544c8c96600200301880c406226644b30010018cc004042003130053041006404101a80d406a0348210dd6800981d8014061040181c800981e001207480a20703756003013809c04d03b181c000a06c375c002606e00481c0c0d400503318189baa0038acc004c088006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c04e027013899912cc00400602b13259800800c05a02d01680b44c966002607c00700b80ba076375c00281f0c0ec0050391bae001303a00240ec607000281b0dd7000981b8012070303500140cc60626ea800e01c817102e18179baa002805205c805402a01500a40c8605e0028168c0acdd50034566002603800313259800800c026264b3001001805402a264b3001303200389980a000912cc00400a00f13259800800c4cc8966002603a00313259800800c046264b3001001809404a264b3001303a00389980e000912cc00400a00f13259800800c6600200313002303d00380b203680b405a02d01640f8607600481ca02681b8dd6000c04a02481d0c0dc00503518199baa0038acc004c090006264b3001001808c4c966002003012809404a0251332259800800c052264b300100180ac05602b015899912cc00400602f13259800800c062031132598009820001c4cc088004896600200500d8992cc00400633001001898011821801c071021407203901c80e2088304100240fd01940f46eb00060310184100607a00281d8dd7000981e001207a303a00140e06eb8004c0e400903a181b800a06a30333754007159800980f000c4c9660020030118992cc0040060250128992cc004c0e800e26603800244b3001002803c4c96600200319800800c4c008c0f400e02c80da02d01680b405903e181d8012072809a06e37580030128092074303700140d460666ea800e020818103020601300230350033030375400300e807403a01c81b0c0cc009031402d02f1bac00180540290321817800a05a302b375400d00840a081404cc03c0048966002005009899192cc00400601500a805402a26644b30010018064032264b3001001806c4c96600200300e807403a01d1332259800800c042264b3001001808c0460230118992cc004c0e400e26016607201901240d86eb8005039181b000a068375c002606a00481b0c0cc0050311bac00180640310341bae001302d00240c86056002605c0048160c0a0dd5002401902a1bab001802c01600a8168c0a80050281815001400e007003801a0563028001409860486ea800e00281092222229800981598159815981598158034dd61815003488c966002602860526ea8006264b30010018acc004c054c0a8dd5000c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b3001001816c0b626644b3001001817c4c96600200303081840c20611332259800800c0ca264b30010018992cc00400606913259800800c0d606b03581ac4cc89660020030378992cc00400607103881c40e226644b300100181d44c96600200313259800800c0f2264b300100181ec0f607b03d899912cc00400607f13259800800c4c9660020030418992cc004006085042821410a26644b300100182244c96600200313259800800c11a264b3001001823c11e08f047899912cc00400609313259800800c4c96600200304b8992cc00400609904c826413226644b300100182744c96600200313259800800c142264b30010018992cc0040060a513259800800c56600260ba00513303f02622598008014660020471980080dc6600202d19800808c6600201919800803c566002608a60b46ea8016264b300100182b44c96600200305782bc15e0af1332259800800c166264b300100182d416a0b505a899912cc0040060b913259800800c1760bb05d82ec4cc896600200305f8992cc0040060c10608304182264b3001306b0038acc004c144c198dd5007c4c9660020030628992cc0040060c70638992cc004c1b800e2660a000244b3001002882144c966002003067833c19e0cf13230033072004375c0028390c1bc00906d419106b1bac001831c18d06e1835800a0d23067375401f061419106141a06eb800506b1834000a0cc375c00260ce0048340c1940050631bae0013064002419460c40028300dd7000983080120c4305f001417460b66ea80160aa82c20aa81c20aa81c20aa81c20aa81c20aa81c20aa81c2264b300100182b415a0ad056899180198308021bae001418460bc00482e20a682d20a7053829c14d05e182d800a0b2305b002828c1460a3051417060b200282b8c16400a09f04f827c13d05a182b800a0aa375c00260ac00482b8c150005052182a001412a09504a82520aa305200141406eb8004c1440090521827800a09a304f002822c11608b0454140609a0028258dd70009826001209a304a0014120609400504082041020808258c1200050461bae00130470024120608a0028218c11400a07703b81dc0ed0461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0f400a067033819c0cd03e181d800a072375c002607400481d8c0e00050361bac0013037002816c0b5038181a800a066375c002606800481a8c0c80050301bae001303100240c8605e0028168c0acdd5000c095028409604b025812a060323259800980b000c54cc0a9241274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0740062a66054921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981798161baa00240a48148c0a8dd500098169817181718151baa300e302a3754605a60546ea80062a660509201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a2020202020202020290016409c6600a0044603664b3001301c302a375400314800226eb4c0b8c0acdd5000a0503259800980e18151baa0018a6103d87a8000899198008009bab302f302c375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980a19818981780125eb82298103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e2050330083756601c60546ea8c038c0a8dd50008014888c966002602a00313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606800719800802402200e805a00e8188dd7000a068303100140bc606200500480240120088190c0bc00502d18159baa0048acc004c070006264b3001001801c4c96600200313259800800c016264b3001001803401a00d0068992cc004c0d000e33001004804401d00b401d0311bae00140d060620028178c0c400a00900480240110321817800a05a302b3754009159800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d13259800981a001c66002009008803a016803a062375c00281a0c0c400502f181880140120090048022064302f00140b460566ea801200481410282050302937540069111194c004dd61817800cdd598179818000c888c966002603400313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b300130210018acc004c0c0dd5002400e004818a2b3001301b0018992cc00400600713259800800c01200900480244c966002606e007006802a068375c00281b8c0d000503218181baa0048acc004cdc3a400c00313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b3001301c0018992cc00400600713259800800c566002606c00519800800c0160088062008819a0090048024011037181a000a0643030375400915980099b8748028006264b3001001801c4c966002003159800981b00146600200300580220188022066802401200900440dc60680028190c0c0dd5002400902d205a40b4816902d205a302e37540069112cc004c06404a2b30013019302e375403913259800980d18179baa0018992cc004006330010018acc004cdc3a401460606ea80062946294102e40a900340aa05502a815206c30333030375400302840b464646600200200844b30010018a6103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800981000945660026032605c6ea8072264b3001301a302f375400313259800800c66002003159800980e98181baa0018a518a5040b902a400d02a81540aa05481b0c0ccc0c0dd5000c0a102d191919800800802112cc004006298103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800980d00944c8cc004004dd6181998181baa303330343034303430343034303430343034303430343034303430343034303430343034303037546600e01005844b30010018a518acc004c8c8cc00400401c896600200314a115980099b8f375c606e00200714a3133002002303800140c481a8dd7181a000c4cc008008c0d4006294102e20648acc004c06c04a26464660020026eacc0d0028896600200314a115980099baf003303130350018a51899801001181b000a05e40cc601e660626064606660666066605e6ea8c0c8c0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0bcdd519803003815a5eb82264b3001301a302f3754003159800acc0056600264b300130223030375400314bd6f7b63044dd5981a18189baa00140b86601c6eacc050c0c0dd5180a18181baa30333030375400205714a314a0818a29462a6605c92011b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0816a2b30013232330010010062259800800c528456600266e3cdd7181b000801c528c4cc008008c0dc0050302068375c606660606ea8cc01c0200b229462a6605c92011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0816a294102d454cc0b92413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640b4660166eb0c0c805c8cdd7981998181baa00101e40b0816102c2058181798178020402a01500a8052032301500130153016001301137540071640383010001300b3754023149a2a660129211856616c696461746f722072657475726e65642066616c7365001365640201", - "hash": "60c6788a6d21574f92338b5908be8b763dad113d795127ee493f3bac" + "compiledCode": "5918670101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a400d370e90044dc3a4015370e90004dc3a40093013375400e911111192cc004c01000a2b3001301b375401d001808a0388acc004c03000a2b3001301b375401d001808a0388acc004c00c00a2b3001301b375401d001808a0388acc004c01c00a2b3001301b375401d001808a0388acc004c01800a2b3001301b375401d001808a0388acc004c01400a2b3001301b375401d001808a038808a030406080c10182030406033001301a37540152301e301f001980c9baa00d911192cc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f132598009814001c0260108128dd7000a0503025001408c6eb4004c09000a0088128c088005020180f1baa0048acc004c03c006264b3001001801c4c966002003004802401226644b300100180344c96600200315980098138014566002601860446ea8006264b300100180444c966002003009804c02626644b3001001805c4c96600200300c80640320191332259800800c03a264b3001001807c03e01f00f8992cc004c0c000e02301040b46eb80050301816800a056375c00260580048168c0a80050281bad0013029002804a0543027001409460466ea800600e810200e812200f007803c01d0281812800a046375a0026048005004409460440028100c078dd50024566002600c00313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01500a80544c966002605600700c805a050375c0028158c0a00050261bae001302700240a0604a0028118dd6800981200140110251811000a040301e3754009002406c80d901b180e1baa003911919800800801911980180098010014888c966002600e00313259800800c00e264b300100180240120090048992cc004c09400e00d00540886eb80050251811000a040301e37540091598009807800c4c9660020030038992cc0040060090048024012264b3001302500380340150221bae001409460440028100c078dd5002400901b2036301c37540072301e301f301f301f301f301f301f301f301f301f301f0019ba54800a6e9520004888888888cc8a60026052605260526052605200522232598009809000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009819001c66002009008803a014803a05e375c0028190c0bc00502d181780140120090048022060302d00140ac60526ea80122b3001301a0018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130320038cc004012011007402900740bc6eb80050321817800a05a302f002802401200900440c0605a0028158c0a4dd50024566002602200313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606400719800802402200e805200e8178dd7000a064302f00140b4605e00500480240120088180c0b400502b18149baa004801204c40988130c09cdd5001c889660026022604e6ea800e264b300100180144c96600200313259800800c012264b3001001802c4c96600260620071332259800980c000c4c9660020030098992cc0040062b300130350028994c004006005005400444464b3001301e0018992cc00400601f13259800800c04202101080844cc89660020030128992cc00400602713259800981f801c4cc074004896600200500a899192cc00400603101880c44cc89660020031980080840062600a608a00c808203501a80d40690461bad001303f00280c2088303d001304000240f901440f06eac006027013809a07e303c00140e86eb8004c0ec00903c181c800a06e303537540071598009813000c4c96600200300f8992cc004006021010808404226644b300100180944c966002003013809c04e0271332259800800c056264b300100180b405a02d0168992cc004c10800e01701740fc6eb8005042181f800a07a375c002607c00481f8c0f000503a1bae001303b00240f0607200281b8c0d4dd5001c03903220643033375400500a40c900a805402a01481b0c0cc00503118179baa0068acc004c080006264b3001001804c4c96600200300a80544c966002606c0071330140012259800801401e264b3001001899912cc004c080006264b3001001808c4c96600200301280944c966002607c00713301c0012259800801401e264b30010018cc004006260046082007016408101680b405a02c8210c0fc00903d404d03b1bac001809404903e181d800a072303737540071598009814000c4c9660020030118992cc004006025012809404a26644b300100180a44c96600200301580ac05602b1332259800800c05e264b300100180c4062264b30013044003899811000912cc00400a01b13259800800c6600200313002304700380e204c80e407203901c4120608a004821a0328208dd6000c0620308220c10400503f1bae00130400024104607c00281e0dd7000981e801207c303b00140e4606e6ea800e2b3001301f0018992cc00400602313259800800c04a02513259800981f001c4cc07000489660020050078992cc00400633001001898011820801c059020405a02d01680b2084303f00240f501340ec6eb000602501240f8607600281c8c0dcdd5001c041034206840d026004607200660686ea800601d00e807403903a181b801206a805a066375800300a805206c303300140c4605e6ea801a010816102c099807800912cc00400a0131323259800800c02a01500a80544cc896600200300c80644c96600200300d8992cc00400601d00e807403a26644b300100180844c966002003011808c04602313259800981e801c4c02cc0f403202481d0dd7000a07a303a00140e06eb8004c0e400903a181b800a06a375800300c8062070375c002606200481b0c0bc004c0c800903018161baa004803205c3756003005802c0150311817000a058302e002801c00e00700340bc60580028150c0a0dd5001c00502524446530013758605800337566058605a0033758605800d2223259800980b000c4c9660020030038992cc0040062b300130330028cc00400600b004402500440c1004802401200881a0c0c400502f18169baa0048acc004c0780062b3001302d3754009003801205c8acc004c054006264b3001001801c4c966002003004802401200913259800981a001c01a00a8188dd7000a068303100140bc605a6ea80122b300130190018992cc00400600713259800800c566002606600519800800c016008804a008818200900480240110341818800a05e302d3754009159800980c000c4c9660020030038992cc0040062b300130330028cc00400600b004402100440c1004802401200881a0c0c400502f18169baa0048acc004c05c006264b3001001801c4c966002003159800981980146600200300580220108022060802401200900440d060620028178c0b4dd5002400902a205440a8815102a2054302b375400691112cc004c0580462b30013016302c375403513259800980b98169baa0018992cc004006330010018acc004c064c0b8dd5000c528c5282058814200681440a205102840d06062605c6ea800604c8158c8c8cc004004014896600200314c0103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a9159800980f008c566002602c60586ea806a264b30013017302d375400313259800800c66002003159800980d18171baa0018a518a5040b1028400d02881440a205081a0c0c4c0b8dd5000c09902b191919800800802912cc004006298103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a919800911919800800801912cc0040062980103d87a8000899192cc004cdc8802800c56600266e3c014006260226606a606600497ae08a60103d87a800040c1133004004303700340c06eb8c0c4004c0d00050324889660026032605e6ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0e000a330010038992cc004c078006264b3001001803c4c966002003159800981d80144c966002604200313259800800c02a264b30010018acc004c0f800a33001001806402d01b402d03b402e01700b805a07e303c00140e860706ea800a2b300130290018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c11400e02701241086eb40060228228c1080050401bad00130410028072084303f00140f46eb4004c0f800a01681f8c0f000503a181c1baa002804a06a40d4606c6ea800601081c2011008804402103c181c800a06e303537540051598009813000c566002606a6ea800a00f00640d900640c88190c0ccdd5000c0150154015035401600b005802a072303600140d0606c005003801c00e00681b8c0d000503218181baa003800a05a911919800800801912cc004006298103d87a80008992cc004c010006260206606800297ae0899801801981b001205e303400140c8911192cc004c064056264660020026eb0c0d4c0c8dd5181a981b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b18191baa3300200702e2259800800c528c56600264646600200201844b30010018a508acc004cdc79bae30390010038a51899801001181d000a06640dc6eb8c0d8006266004004606e00314a081810344566002603802b13232330010013756606c01c44b30010018a508acc004cdd78019819981b800c528c4cc008008c0e0005031206a3010330333034303530353035303137546068606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a60626ea8cc0040180b52f5c1159800980e80ac4c966002603660626ea80062b300159800acc004c966002604860646ea8006297adef6c6089bab3036303337540028180cc014dd5980b98191baa301730323754606a60646ea80040b6294629410334528c54cc0c12411b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0817a2b300132323300100100b2259800800c528456600266e3cdd7181c000801c528c4cc008008c0e4005032206c375c606a60646ea8cc00801c0ba29462a6606092011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0817a294102f454cc0c12413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640bc660046eb0c0d005c8cdd7981a98191baa0010208acc004c068c0c0dd500f456600264646600200201444b30010018a508acc004cdc79bae30370010038a51899801001181c000a06240d46eb8c058c0c4dd5181a18189baa01e8a518a99817a481356b65795f7369676e65642865787472615f7369676e61746f726965732c20646174756d2e73746f705f6b657929203f2046616c73650014a08172050817102e205c40b84464b3001301c3032375400313259800800c566002603a60666ea8006264b3001001817c4c96600200303081840c20611332259800800c0ca264b3001001819c0ce067033899912cc00400606b13259800800c0da06d1332259800800c0e2264b300100181cc0e6073039899912cc00400607713259800800c4c96600200303d8992cc00400607d03e81f40fa26644b300100182044c966002003041820c1060831332259800800c10e264b30010018992cc00400608b13259800800c11a08d04682344cc89660020030488992cc004006264b300100182544c96600200304b825c12e0971332259800800c136264b30010018992cc00400609f13259800800c1420a105082844cc89660020030528992cc004006264b300100182a44c96600200305582ac1560ab1332259800800c15e264b30010018992cc0040060b313259800800c4c96600200305b8992cc0040062b30013066002899822013112cc00400a330010238cc00406e330010168cc0040463300100c8cc00401e2b3001304d3063375400b13259800800c17e264b300100183041820c1060899912cc0040060c513259800800c18e0c7063831c4cc89660020030658992cc0040060cd066833419a26644b300100183444c966002003069834c1a60d313259800983a001c56600260b260de6ea803e264b3001001835c4c96600200306c83644c96600260ee00713305500122598008014410a264b300100183841c20e10708991801983d8021bae00141ec60f000483b20da83a0dd6000c1b20d883b8c1d000507218381baa00f83520da83520e2375c00283a0c1c400506f1bae001307000241c460dc0028360dd7000983680120dc306b00141a46eb8004c1a800906b1834000a0cc3064375400b05e418505e40d905e40d905e40d905e40d905e40d905e40d913259800800c17e0bf05f82fc4c8c00cc1a8010dd7000a0d43067002419505c418d05c82e41720b88338c1900050621832001416a0b505a82d20ca3062001418060c400505882c41620b08318c18000505e1bae001305f002418060ba00282d8c17400a0a7053829c14d05e182d800a0b2375c00260b400482d8c160005056182c001413a09d04e82720b2305600141506eb8004c1540090561829800a0a23053002824c126093049415060a20028278dd7000982800120a2304e0014130609c00504482241120888278c13000504a1bae001304b002413060920028238dd70009824001209230460014110608c00503c81e40f20788238c1100050421bae00130430024110608200281f8dd6000982000140da06c8208c0f800503c1bae001303d00240f8607600281c8dd7000981d0012076303800140d860686ea800605c818a05d02e81740b903919192cc004c0780062a660669201274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0980062a66066921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981c181a9baa00240c88190c0ccdd5000981b181b981b98199baa301830333754606c60666ea80062a660629201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640c0660060044604864b300130253033375400314800226eb4c0dcc0d0dd5000a0623259800981298199baa0018a6103d87a8000899198008009bab30383035375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980b1981d181c00125eb82298103d87a800040d5133004004303c00340d46eb8c0d8004c0e40050372062330063756603060666ea8c060c0ccdd5000801102a2054181618160018c09c02488966002601e604a6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002606200519800801c66002003009804201c804201c804205c804402201100840c8605e0028168c0bc00a00d00680340190301816800a056375c00260580048168c0a800502818131baa003800a046201500a8054029019180a800980a980b00098089baa0038b201c180800098059baa0118a4d153300949011856616c696461746f722072657475726e65642066616c7365001365640201", + "hash": "b68cda8afdebac748c8a855c4ceb0ef0be54dea86ec2f0dce2e65214" }, { "title": "dex_order_book/spend.dex_order_book.else", @@ -564,8 +564,8 @@ } } ], - "compiledCode": "5917bb0101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a4011370e90024dc3a40013013375400e9111192cc004c00c00a2b300130193754019001807a0348acc004c02800a2b300130193754019001807a0348acc004c01000a2b300130193754019001807a0348acc004cdc3a400c005159800980c9baa00c800c03d01a4566002600a005159800980c9baa00c800c03d01a403d016202c405880b10160cc004c060dd50044888c966002600c00313259800800c00e264b300100180240120090048992cc004c08c00e00d00540806eb80050231810000a03c301c37540091598009806800c4c9660020030038992cc0040060090048024012264b3001302300380340150201bae001408c604000280f0c070dd500240090192032301a3754007223233001001003223300300130020029ba54800246038603a0033017375401722232598009803000c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e264b30013026003804c0210231bae001409860460028108dd6800981100140110231810000a03c301c37540091598009806800c4c9660020030038992cc00400600900480244cc89660020030068992cc0040062b300130250028acc004c02cc080dd5000c4c9660020030088992cc004006013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f132598009817001c0460208158dd7000a05c302b00140a46eb8004c0a800902b1814000a04c375a002604e00500940a0604a0028118c084dd5000c01d01e401d022401e00f007803a04c302300140846eb4004c08800a0088118c08000501e180e1baa0048acc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f1332259800800c026264b3001001805402a01500a8992cc004c0a400e01900b40986eb80050291813000a048375c002604a0048130c08c0050211bad001302200280220463020001407860386ea801200480c90192032301a37540072301c301d301d301d301d301d301d301d301d301d301d0019ba54800922222222298009812804c88c8cc00400400c896600200314c0103d87a8000899192cc004cdc8802800c56600266e3c0140062601866052604e00497ae08a60103d87a80004091133004004302b00340906eb8c094004c0a0005026488966002601c60466ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0b000a330010038992cc004c04c006264b3001001803c4c966002003159800981780144c966002602c00313259800800c02a264b30010018acc004c0c800a33001001806402d015402d02f402e01700b805a066303000140b860586ea800a2b3001301d0018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c0e400e02701240d86eb400602281c8c0d80050341bad0013035002807206c303300140c46eb4004c0c800a0168198c0c000502e18161baa002804a05240a460546ea8006010816201100880440210301816800a05630293754005159800980d000c56600260526ea800a00f00640a900640988130c09cdd5000c01500f4015029401600b005802a05a302a00140a06054005003801c00e0068158c0a000502618121baa003800a042911919800800801912cc004006298103d87a80008992cc004c010006260166605000297ae0899801801981500120463028001409922259800980718119baa0038992cc00400600513259800800c00e007003801c4cc89660020030058992cc004006264b3001001803c4c966002003159800981780146600200719800800c02601080920108092010816201100880440210301816800a056302d002803401a00d00640b860560028148dd7000981500120563028001409860486ea800e002810a444b3001300e3023375400713259800800c00a264b30010018992cc00400600913259800800c016264b3001302d003899912cc004c054006264b3001001804c4c966002003159800981880144ca6002003002802a0022223259800980d800c4c96600200300f8992cc004006021010808404226644b300100180944c9660020030138992cc004c0ec00e26603a00244b300100280544c8c96600200301880c406226644b30010018cc004042003130053041006404101a80d406a0348210dd6800981d8014061040181c800981e001207480a20703756003013809c04d03b181c000a06c375c002606e00481c0c0d400503318189baa0038acc004c088006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c04e027013899912cc00400602b13259800800c05a02d01680b44c966002607c00700b80ba076375c00281f0c0ec0050391bae001303a00240ec607000281b0dd7000981b8012070303500140cc60626ea800e01c817102e18179baa002805205c805402a01500a40c8605e0028168c0acdd50034566002603800313259800800c026264b3001001805402a264b3001303200389980a000912cc00400a00f13259800800c4cc8966002603a00313259800800c046264b3001001809404a264b3001303a00389980e000912cc00400a00f13259800800c6600200313002303d00380b203680b405a02d01640f8607600481ca02681b8dd6000c04a02481d0c0dc00503518199baa0038acc004c090006264b3001001808c4c966002003012809404a0251332259800800c052264b300100180ac05602b015899912cc00400602f13259800800c062031132598009820001c4cc088004896600200500d8992cc00400633001001898011821801c071021407203901c80e2088304100240fd01940f46eb00060310184100607a00281d8dd7000981e001207a303a00140e06eb8004c0e400903a181b800a06a30333754007159800980f000c4c9660020030118992cc0040060250128992cc004c0e800e26603800244b3001002803c4c96600200319800800c4c008c0f400e02c80da02d01680b405903e181d8012072809a06e37580030128092074303700140d460666ea800e020818103020601300230350033030375400300e807403a01c81b0c0cc009031402d02f1bac00180540290321817800a05a302b375400d00840a081404cc03c0048966002005009899192cc00400601500a805402a26644b30010018064032264b3001001806c4c96600200300e807403a01d1332259800800c042264b3001001808c0460230118992cc004c0e400e26016607201901240d86eb8005039181b000a068375c002606a00481b0c0cc0050311bac00180640310341bae001302d00240c86056002605c0048160c0a0dd5002401902a1bab001802c01600a8168c0a80050281815001400e007003801a0563028001409860486ea800e00281092222229800981598159815981598158034dd61815003488c966002602860526ea8006264b30010018acc004c054c0a8dd5000c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b3001001816c0b626644b3001001817c4c96600200303081840c20611332259800800c0ca264b30010018992cc00400606913259800800c0d606b03581ac4cc89660020030378992cc00400607103881c40e226644b300100181d44c96600200313259800800c0f2264b300100181ec0f607b03d899912cc00400607f13259800800c4c9660020030418992cc004006085042821410a26644b300100182244c96600200313259800800c11a264b3001001823c11e08f047899912cc00400609313259800800c4c96600200304b8992cc00400609904c826413226644b300100182744c96600200313259800800c142264b30010018992cc0040060a513259800800c56600260ba00513303f02622598008014660020471980080dc6600202d19800808c6600201919800803c566002608a60b46ea8016264b300100182b44c96600200305782bc15e0af1332259800800c166264b300100182d416a0b505a899912cc0040060b913259800800c1760bb05d82ec4cc896600200305f8992cc0040060c10608304182264b3001306b0038acc004c144c198dd5007c4c9660020030628992cc0040060c70638992cc004c1b800e2660a000244b3001002882144c966002003067833c19e0cf13230033072004375c0028390c1bc00906d419106b1bac001831c18d06e1835800a0d23067375401f061419106141a06eb800506b1834000a0cc375c00260ce0048340c1940050631bae0013064002419460c40028300dd7000983080120c4305f001417460b66ea80160aa82c20aa81c20aa81c20aa81c20aa81c20aa81c20aa81c2264b300100182b415a0ad056899180198308021bae001418460bc00482e20a682d20a7053829c14d05e182d800a0b2305b002828c1460a3051417060b200282b8c16400a09f04f827c13d05a182b800a0aa375c00260ac00482b8c150005052182a001412a09504a82520aa305200141406eb8004c1440090521827800a09a304f002822c11608b0454140609a0028258dd70009826001209a304a0014120609400504082041020808258c1200050461bae00130470024120608a0028218c11400a07703b81dc0ed0461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0f400a067033819c0cd03e181d800a072375c002607400481d8c0e00050361bac0013037002816c0b5038181a800a066375c002606800481a8c0c80050301bae001303100240c8605e0028168c0acdd5000c095028409604b025812a060323259800980b000c54cc0a9241274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0740062a66054921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981798161baa00240a48148c0a8dd500098169817181718151baa300e302a3754605a60546ea80062a660509201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a2020202020202020290016409c6600a0044603664b3001301c302a375400314800226eb4c0b8c0acdd5000a0503259800980e18151baa0018a6103d87a8000899198008009bab302f302c375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980a19818981780125eb82298103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e2050330083756601c60546ea8c038c0a8dd50008014888c966002602a00313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606800719800802402200e805a00e8188dd7000a068303100140bc606200500480240120088190c0bc00502d18159baa0048acc004c070006264b3001001801c4c96600200313259800800c016264b3001001803401a00d0068992cc004c0d000e33001004804401d00b401d0311bae00140d060620028178c0c400a00900480240110321817800a05a302b3754009159800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d13259800981a001c66002009008803a016803a062375c00281a0c0c400502f181880140120090048022064302f00140b460566ea801200481410282050302937540069111194c004dd61817800cdd598179818000c888c966002603400313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b300130210018acc004c0c0dd5002400e004818a2b3001301b0018992cc00400600713259800800c01200900480244c966002606e007006802a068375c00281b8c0d000503218181baa0048acc004cdc3a400c00313259800800c00e264b30010018acc004c0d800a33001001802c01100840110334012009004802206e303400140c860606ea80122b3001301c0018992cc00400600713259800800c566002606c00519800800c0160088062008819a0090048024011037181a000a0643030375400915980099b8748028006264b3001001801c4c966002003159800981b00146600200300580220188022066802401200900440dc60680028190c0c0dd5002400902d205a40b4816902d205a302e37540069112cc004c06404a2b30013019302e375403913259800980d18179baa0018992cc004006330010018acc004cdc3a401460606ea80062946294102e40a900340aa05502a815206c30333030375400302840b464646600200200844b30010018a6103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800981000945660026032605c6ea8072264b3001301a302f375400313259800800c66002003159800980e98181baa0018a518a5040b902a400d02a81540aa05481b0c0ccc0c0dd5000c0a102d191919800800802112cc004006298103d87a80008992cc004cdd78021819000c4c060cc0d4c0cc0052f5c1133003003303700240c0606a0028198cdd2a400866062601e660626020605e6ea8c0c8c0bcdd500e25eb812f5c102640b1159800980d00944c8cc004004dd6181998181baa303330343034303430343034303430343034303430343034303430343034303430343034303037546600e01005844b30010018a518acc004c8c8cc00400401c896600200314a115980099b8f375c606e00200714a3133002002303800140c481a8dd7181a000c4cc008008c0d4006294102e20648acc004c06c04a26464660020026eacc0d0028896600200314a115980099baf003303130350018a51899801001181b000a05e40cc601e660626064606660666066605e6ea8c0c8c0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0ccc0bcdd519803003815a5eb82264b3001301a302f3754003159800acc0056600264b300130223030375400314bd6f7b63044dd5981a18189baa00140b86601c6eacc050c0c0dd5180a18181baa30333030375400205714a314a0818a29462a6605c92011b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0816a2b30013232330010010062259800800c528456600266e3cdd7181b000801c528c4cc008008c0dc0050302068375c606660606ea8cc01c0200b229462a6605c92011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0816a294102d454cc0b92413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640b4660166eb0c0c805c8cdd7981998181baa00101e40b0816102c2058181798178020402a01500a8052032301500130153016001301137540071640383010001300b3754023149a2a660129211856616c696461746f722072657475726e65642066616c7365001365640201", - "hash": "60c6788a6d21574f92338b5908be8b763dad113d795127ee493f3bac" + "compiledCode": "5918670101002229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0039bae00248888888888a60022a660089213d657870656374206f7261636c655f696e7075745f646174756d3a204170704f7261636c65446174756d203d206f7261636c655f696e7075745f6461746100168a998022493665787065637420775f72656465656d65723a2048796472614f72646572426f6f6b52656465656d6572203d20775f72656465656d657200168a998022496665787065637420536f6d6528775f72656465656d657229203d0a202020202020202020207769746864726177616c5f72656465656d65722872656465656d6572732c20646174756d2e68796472615f6f726465725f626f6f6b5f7363726970745f686173682900168a998022491e65787065637420536f6d6528646174756d29203d20646174756d5f6f707400168a998022491e72656465656d65723a204465784f72646572426f6f6b52656465656d657200164888896600264653001301000198081808800cdc3a400530100024888966002600460206ea800e2646644b30010078cc004dc3a400d370e90044dc3a4015370e90004dc3a40093013375400e911111192cc004c01000a2b3001301b375401d001808a0388acc004c03000a2b3001301b375401d001808a0388acc004c00c00a2b3001301b375401d001808a0388acc004c01c00a2b3001301b375401d001808a0388acc004c01800a2b3001301b375401d001808a0388acc004c01400a2b3001301b375401d001808a038808a030406080c10182030406033001301a37540152301e301f001980c9baa00d911192cc004c01c006264b3001001801c4c966002003004802401226644b300100180344c966002003007803c01e00f132598009814001c0260108128dd7000a0503025001408c6eb4004c09000a0088128c088005020180f1baa0048acc004c03c006264b3001001801c4c966002003004802401226644b300100180344c96600200315980098138014566002601860446ea8006264b300100180444c966002003009804c02626644b3001001805c4c96600200300c80640320191332259800800c03a264b3001001807c03e01f00f8992cc004c0c000e02301040b46eb80050301816800a056375c00260580048168c0a80050281bad0013029002804a0543027001409460466ea800600e810200e812200f007803c01d0281812800a046375a0026048005004409460440028100c078dd50024566002600c00313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01500a80544c966002605600700c805a050375c0028158c0a00050261bae001302700240a0604a0028118dd6800981200140110251811000a040301e3754009002406c80d901b180e1baa003911919800800801911980180098010014888c966002600e00313259800800c00e264b300100180240120090048992cc004c09400e00d00540886eb80050251811000a040301e37540091598009807800c4c9660020030038992cc0040060090048024012264b3001302500380340150221bae001409460440028100c078dd5002400901b2036301c37540072301e301f301f301f301f301f301f301f301f301f301f0019ba54800a6e9520004888888888cc8a60026052605260526052605200522232598009809000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009819001c66002009008803a014803a05e375c0028190c0bc00502d181780140120090048022060302d00140ac60526ea80122b3001301a0018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130320038cc004012011007402900740bc6eb80050321817800a05a302f002802401200900440c0605a0028158c0a4dd50024566002602200313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002606400719800802402200e805200e8178dd7000a064302f00140b4605e00500480240120088180c0b400502b18149baa004801204c40988130c09cdd5001c889660026022604e6ea800e264b300100180144c96600200313259800800c012264b3001001802c4c96600260620071332259800980c000c4c9660020030098992cc0040062b300130350028994c004006005005400444464b3001301e0018992cc00400601f13259800800c04202101080844cc89660020030128992cc00400602713259800981f801c4cc074004896600200500a899192cc00400603101880c44cc89660020031980080840062600a608a00c808203501a80d40690461bad001303f00280c2088303d001304000240f901440f06eac006027013809a07e303c00140e86eb8004c0ec00903c181c800a06e303537540071598009813000c4c96600200300f8992cc004006021010808404226644b300100180944c966002003013809c04e0271332259800800c056264b300100180b405a02d0168992cc004c10800e01701740fc6eb8005042181f800a07a375c002607c00481f8c0f000503a1bae001303b00240f0607200281b8c0d4dd5001c03903220643033375400500a40c900a805402a01481b0c0cc00503118179baa0068acc004c080006264b3001001804c4c96600200300a80544c966002606c0071330140012259800801401e264b3001001899912cc004c080006264b3001001808c4c96600200301280944c966002607c00713301c0012259800801401e264b30010018cc004006260046082007016408101680b405a02c8210c0fc00903d404d03b1bac001809404903e181d800a072303737540071598009814000c4c9660020030118992cc004006025012809404a26644b300100180a44c96600200301580ac05602b1332259800800c05e264b300100180c4062264b30013044003899811000912cc00400a01b13259800800c6600200313002304700380e204c80e407203901c4120608a004821a0328208dd6000c0620308220c10400503f1bae00130400024104607c00281e0dd7000981e801207c303b00140e4606e6ea800e2b3001301f0018992cc00400602313259800800c04a02513259800981f001c4cc07000489660020050078992cc00400633001001898011820801c059020405a02d01680b2084303f00240f501340ec6eb000602501240f8607600281c8c0dcdd5001c041034206840d026004607200660686ea800601d00e807403903a181b801206a805a066375800300a805206c303300140c4605e6ea801a010816102c099807800912cc00400a0131323259800800c02a01500a80544cc896600200300c80644c96600200300d8992cc00400601d00e807403a26644b300100180844c966002003011808c04602313259800981e801c4c02cc0f403202481d0dd7000a07a303a00140e06eb8004c0e400903a181b800a06a375800300c8062070375c002606200481b0c0bc004c0c800903018161baa004803205c3756003005802c0150311817000a058302e002801c00e00700340bc60580028150c0a0dd5001c00502524446530013758605800337566058605a0033758605800d2223259800980b000c4c9660020030038992cc0040062b300130330028cc00400600b004402500440c1004802401200881a0c0c400502f18169baa0048acc004c0780062b3001302d3754009003801205c8acc004c054006264b3001001801c4c966002003004802401200913259800981a001c01a00a8188dd7000a068303100140bc605a6ea80122b300130190018992cc00400600713259800800c566002606600519800800c016008804a008818200900480240110341818800a05e302d3754009159800980c000c4c9660020030038992cc0040062b300130330028cc00400600b004402100440c1004802401200881a0c0c400502f18169baa0048acc004c05c006264b3001001801c4c966002003159800981980146600200300580220108022060802401200900440d060620028178c0b4dd5002400902a205440a8815102a2054302b375400691112cc004c0580462b30013016302c375403513259800980b98169baa0018992cc004006330010018acc004c064c0b8dd5000c528c5282058814200681440a205102840d06062605c6ea800604c8158c8c8cc004004014896600200314c0103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a9159800980f008c566002602c60586ea806a264b30013017302d375400313259800800c66002003159800980d18171baa0018a518a5040b1028400d02881440a205081a0c0c4c0b8dd5000c09902b191919800800802912cc004006298103d87a80008992cc004cdd78021818000c4c03ccc0ccc0c40052f5c1133003003303500240b860660028188cdd2a40086605e60186605e601a605a6ea8c0c0c0b4dd500d25eb812f5c102440a919800911919800800801912cc0040062980103d87a8000899192cc004cdc8802800c56600266e3c014006260226606a606600497ae08a60103d87a800040c1133004004303700340c06eb8c0c4004c0d00050324889660026032605e6ea800e264b300100180144c96600200313259800800c012264b30010018acc004c0e000a330010038992cc004c078006264b3001001803c4c966002003159800981d80144c966002604200313259800800c02a264b30010018acc004c0f800a33001001806402d01b402d03b402e01700b805a07e303c00140e860706ea800a2b300130290018992cc00400601513259800800c02e01700b899912cc00400601b13259800800c03a01d00e899912cc00400602113259800800c0460230118992cc004c11400e02701241086eb40060228228c1080050401bad00130410028072084303f00140f46eb4004c0f800a01681f8c0f000503a181c1baa002804a06a40d4606c6ea800601081c2011008804402103c181c800a06e303537540051598009813000c566002606a6ea800a00f00640d900640c88190c0ccdd5000c0150154015035401600b005802a072303600140d0606c005003801c00e00681b8c0d000503218181baa003800a05a911919800800801912cc004006298103d87a80008992cc004c010006260206606800297ae0899801801981b001205e303400140c8911192cc004c064056264660020026eb0c0d4c0c8dd5181a981b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b181b18191baa3300200702e2259800800c528c56600264646600200201844b30010018a508acc004cdc79bae30390010038a51899801001181d000a06640dc6eb8c0d8006266004004606e00314a081810344566002603802b13232330010013756606c01c44b30010018a508acc004cdd78019819981b800c528c4cc008008c0e0005031206a3010330333034303530353035303137546068606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a606a60626ea8cc0040180b52f5c1159800980e80ac4c966002603660626ea80062b300159800acc004c966002604860646ea8006297adef6c6089bab3036303337540028180cc014dd5980b98191baa301730323754606a60646ea80040b6294629410334528c54cc0c12411b6e6f5f617574685f746f6b656e5f636865636b203f2046616c73650014a0817a2b300132323300100100b2259800800c528456600266e3cdd7181c000801c528c4cc008008c0e4005032206c375c606a60646ea8cc00801c0ba29462a6606092011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0817a294102f454cc0c12413165787065637420536f6d65286f776e5f696e70757429203d2066696e645f696e70757428696e707574732c207574786f29001640bc660046eb0c0d005c8cdd7981a98191baa0010208acc004c068c0c0dd500f456600264646600200201444b30010018a508acc004cdc79bae30370010038a51899801001181c000a06240d46eb8c058c0c4dd5181a18189baa01e8a518a99817a481356b65795f7369676e65642865787472615f7369676e61746f726965732c20646174756d2e73746f705f6b657929203f2046616c73650014a08172050817102e205c40b84464b3001301c3032375400313259800800c566002603a60666ea8006264b3001001817c4c96600200303081840c20611332259800800c0ca264b3001001819c0ce067033899912cc00400606b13259800800c0da06d1332259800800c0e2264b300100181cc0e6073039899912cc00400607713259800800c4c96600200303d8992cc00400607d03e81f40fa26644b300100182044c966002003041820c1060831332259800800c10e264b30010018992cc00400608b13259800800c11a08d04682344cc89660020030488992cc004006264b300100182544c96600200304b825c12e0971332259800800c136264b30010018992cc00400609f13259800800c1420a105082844cc89660020030528992cc004006264b300100182a44c96600200305582ac1560ab1332259800800c15e264b30010018992cc0040060b313259800800c4c96600200305b8992cc0040062b30013066002899822013112cc00400a330010238cc00406e330010168cc0040463300100c8cc00401e2b3001304d3063375400b13259800800c17e264b300100183041820c1060899912cc0040060c513259800800c18e0c7063831c4cc89660020030658992cc0040060cd066833419a26644b300100183444c966002003069834c1a60d313259800983a001c56600260b260de6ea803e264b3001001835c4c96600200306c83644c96600260ee00713305500122598008014410a264b300100183841c20e10708991801983d8021bae00141ec60f000483b20da83a0dd6000c1b20d883b8c1d000507218381baa00f83520da83520e2375c00283a0c1c400506f1bae001307000241c460dc0028360dd7000983680120dc306b00141a46eb8004c1a800906b1834000a0cc3064375400b05e418505e40d905e40d905e40d905e40d905e40d905e40d913259800800c17e0bf05f82fc4c8c00cc1a8010dd7000a0d43067002419505c418d05c82e41720b88338c1900050621832001416a0b505a82d20ca3062001418060c400505882c41620b08318c18000505e1bae001305f002418060ba00282d8c17400a0a7053829c14d05e182d800a0b2375c00260b400482d8c160005056182c001413a09d04e82720b2305600141506eb8004c1540090561829800a0a23053002824c126093049415060a20028278dd7000982800120a2304e0014130609c00504482241120888278c13000504a1bae001304b002413060920028238dd70009824001209230460014110608c00503c81e40f20788238c1100050421bae00130430024110608200281f8dd6000982000140da06c8208c0f800503c1bae001303d00240f8607600281c8dd7000981d0012076303800140d860686ea800605c818a05d02e81740b903919192cc004c0780062a660669201274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0980062a66066921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981c181a9baa00240c88190c0ccdd5000981b181b981b98199baa301830333754606c60666ea80062a660629201c165787065637420536f6d65286f7261636c655f696e70757429203d0a202020207265666572656e63655f696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206f7261636c655f6e66742c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640c0660060044604864b300130253033375400314800226eb4c0dcc0d0dd5000a0623259800981298199baa0018a6103d87a8000899198008009bab30383035375400444b30010018a6103d87a8000899192cc004cdc8a45000018acc004cdc7a441000018980b1981d181c00125eb82298103d87a800040d5133004004303c00340d46eb8c0d8004c0e40050372062330063756603060666ea8c060c0ccdd5000801102a2054181618160018c09c02488966002601e604a6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002606200519800801c66002003009804201c804201c804205c804402201100840c8605e0028168c0bc00a00d00680340190301816800a056375c00260580048168c0a800502818131baa003800a046201500a8054029019180a800980a980b00098089baa0038b201c180800098059baa0118a4d153300949011856616c696461746f722072657475726e65642066616c7365001365640201", + "hash": "b68cda8afdebac748c8a855c4ceb0ef0be54dea86ec2f0dce2e65214" }, { "title": "emergency_request/cancel_order_mint.emergency_cancel_order_request.mint", @@ -1711,6 +1711,12 @@ "dataType": "constructor", "index": 4, "fields": [] + }, + { + "title": "DexOrderBookMigration", + "dataType": "constructor", + "index": 5, + "fields": [] } ] }, diff --git a/validators/dex_order_book/spend.ak b/validators/dex_order_book/spend.ak index 257b4e6..db22061 100644 --- a/validators/dex_order_book/spend.ak +++ b/validators/dex_order_book/spend.ak @@ -6,8 +6,9 @@ use hydra_dex/hydra_commit_utils.{validate_hydra_commit} use hydra_dex/types.{ AppOracleDatum, CombineOrderMerkle, DexOrderBookCombineMerkleTree, DexOrderBookDatum, DexOrderBookEmergencyCancelOrder, DexOrderBookHydraCommit, - DexOrderBookRedeemer, DexOrderBookSpamPreventionWithdraw, - DexOrderBookSplitMerkleTree, HydraOrderBookRedeemer, SplitOrderMerkle, + DexOrderBookMigration, DexOrderBookRedeemer, + DexOrderBookSpamPreventionWithdraw, DexOrderBookSplitMerkleTree, + HydraOrderBookRedeemer, SplitOrderMerkle, } use hydra_dex/utils.{get_app_oracle_datum} @@ -77,6 +78,10 @@ validator dex_order_book(oracle_nft: PolicyId, dex_order_book_nft: PolicyId) { no_auth_token_check? && is_operation_key_signed? } + DexOrderBookMigration -> { + expect Some(datum) = datum_opt + key_signed(extra_signatories, datum.stop_key)? + } } } From 795b27eabfc1d1319af8a6186d2871b7eb1f2796 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 8 Apr 2026 11:13:06 +0800 Subject: [PATCH 30/30] chore: update plutus json --- plutus.json | 86 +++++--------------------------- validators/hydra_account/core.ak | 1 - 2 files changed, 13 insertions(+), 74 deletions(-) diff --git a/plutus.json b/plutus.json index b373204..4cdb1c8 100644 --- a/plutus.json +++ b/plutus.json @@ -741,15 +741,15 @@ } } ], - "compiledCode": "59801f010100229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0024888888888a60022a6600692012e6578706563742061737365745f6c6973743a204d56616c7565203d20646573657269616c697365645f76616c756500168a99801a4949657870656374206f75747075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a494665787065637420696e7075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a493e657870656374206f75747075745f646174756d3a20557365724163636f756e74203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a493b65787065637420696e7075745f646174756d3a20557365724163636f756e74203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492a657870656374206163636f756e743a20557365724163636f756e74203d206f75747075745f646174756d00168a99801a494a657870656374206f75747075745f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a497b657870656374204465784163636f756e7442616c616e6365446174756d207b0a202020206163636f756e745f62616c616e63655f6d65726b6c655f726f6f743a20696e7075745f6d65726b6c655f726f6f742c0a20207d3a204465784163636f756e7442616c616e6365446174756d203d20747265655f726f6f7400168a99801a495b657870656374205472616e73666572496e74656e74207b20746f2c20616d6f756e745f6c323a207472616e73666572616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a496a657870656374204d6173746572496e74656e74207b206163636f756e743a2066726f6d2c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495f6578706563742043616e63656c5769746864726177616c496e74656e74207b20616d6f756e745f6c313a207769746864726177616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a4941657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d206465785f6163636f756e745f62616c616e63655f6f75747075747300168a99801a493f657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d206465785f6163636f756e745f62616c616e63655f696e7075747300168a99801a49e7657870656374205b6665655f6f75747075745d203d0a202020202020202020206f746865725f6f7574707574730a2020202020202020202020207c3e206c6973742e66696c746572280a202020202020202020202020202020206372656174655f6163636f756e745f6f7574707574735f66696c746572280a2020202020202020202020202020202020206665655f6163636f756e742c0a20202020202020202020202020202020202068796472615f6163636f756e745f7363726970745f686173682c0a20202020202020202020202020202020292c0a20202020202020202020202020202900168a99801a498b657870656374205769746864726177616c496e74656e74207b0a20202020616d6f756e745f6c313a207769746864726177616c5f616d6f756e745f7261772c0a202020207769746864726177616c5f6665655f6c313a207769746864726177616c5f6665655f7261772c0a20207d3a2048796472614163636f756e74496e74656e74203d20696e74656e7400168a99801a4964657870656374204d6173746572496e74656e74207b206163636f756e742c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a498c657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c696379280a202020202020696e707574732c0a20202020202068796472615f757365725f696e74656e745f616464726573732c0a20202020202068796472615f757365725f696e74656e745f7363726970745f686173682c0a202020202900168a99801a494e657870656374206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a494365787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f6f75747075742e646174756d00168a99801a499d657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d0a202020206f7574707574735f61745f77697468280a2020202020206f7574707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a494c65787065637420696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f646174756d00168a99801a499a657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d0a20202020696e707574735f61745f77697468280a202020202020696e707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a4929657870656374206163636f756e743a20557365724163636f756e74203d20696e7075745f646174756d00168a99801a4958657870656374206465785f6f726465725f626f6f6b5f696e7075745f646174756d3a204465784f72646572426f6f6b446174756d203d0a202020206465785f6f726465725f626f6f6b5f7265665f696e7075745f6461746100168a99801a491e72656465656d65723a2048796472614163636f756e7452656465656d657200168a99801a491f72656465656d65723a2048796472614163636f756e744f7065726174696f6e0016488888888888888888888888889660033001301f375404b3722911009b8f4881009b87480026e1d20029ba5480026e1d2004918119812000c8c08cc090c0900066e9520024888888888a6002605a015302c00a91919800800801112cc004006297adef6c608994c004dd71816000cdd59816800cc0c4009222598009808001c566002601e00710018802a05a89981919bb037520066e98008cc01801800502d0c0bc00502d4888c966002601600313259800800c00e264b300100180240120090048992cc004c0d000e00d00540c46eb80050341818800a05e302d37540091598009805000c4c9660020030038992cc0040060090048024012264b3001303400380340150311bae00140d060620028178c0b4dd5002400902a2054302b37540072232330010010032259800800c5300103d87a8000899192cc004cdc8802800c56600266e3c0140062601666062605e00497ae08a60103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e488c8cc00400400c896600200314c0103d87a80008992cc004c010006260146606000297ae089980180198190012056303000140b922259800801452844ca600264b3001300c302d37540031375a605c60626eacc0c4c0b8dd5000c5200040ac6060003375e6060606200337560069112cc0040062b30013002006899802801a400114a0816a264b30013375e60600029810140008acc004cc018010dd69818981a1bab3031001898019ba630350028a5040b91598009980300224001130030078a5040b88170c0cc0050310ca60020030049119818801198189ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0bc0066eacc0c000660680069112cc004c04c00e2b3001301200389980298079981a9ba60024bd70000c4cc01530103d87a800000640c119800803c006446600e0046606e66ec0dd48029ba6004001401c81806064004818229422942294103124444445300130330079819981a003c88966002602260646ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002607c00519800801c66002003009804201c804201c8042076804402201100840fc607800281d0c0f000a00d006803401903d181d000a070375c002607200481d0c0dc00503518199baa003800a0609112cc004c044c0c8dd5001c4c9660020030028992cc004006264b300100180244c966002003159800981d80146600200713259800980b000c4c9660020030078992cc0040062b3001303e0028992cc004c064006264b300100180544c966002003159800982080146600200300c805a022805a07c805c02e01700b4108607e00281e8c0ecdd50014566002603000313259800800c02a264b3001001805c02e0171332259800800c036264b3001001807403a01d1332259800800c042264b3001001808c046023132598009824001c04e0248228dd6800c0450481822800a086375a002608800500e411460840028200dd68009820801402d042181f800a07a303b375400500940e081c0c0e4dd5000c02103b4022011008804207e303c00140e860706ea800a2b300130150018acc004c0e0dd5001401e00c81ca00c81a9035181b1baa001802a016802a070802c01600b00540f0607200281b8c0e400a007003801c00d03a181b800a06a3033375400700140c091111919912cc004c0500062646644b300100a899912cc004c068006264b300100181044c9660026084005004810a07e304000140f860786ea80322b300130190018acc004c0f0dd5006400a03e81ea2b300130170018acc004c0f0dd5006400a03e81ea03e81c9039207213232332298009bab3041002982118211821182118211821182118211821000cdd71820800cc0f4dd500724444b300130200018acc004c8c8cc004004018896600200314a115980099baf003304430480018a518998010011824800a0844118603466088608a608c00697ae08a518a998202494e7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6f726465725f626f6f6b5f7363726970745f6861736829203f2046616c73650014a081fa2b3001301f0018acc004c8c8cc004004018896600200314a115980099baf003304430480018a518998010011824800a0844118603466088608a00697ae08a518a9982024814b7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6163636f756e745f7363726970745f6861736829203f2046616c73650014a081fa264b300130213042375400313259800acc00566003300130193756603c60886ea8c078c110dd5182398221baa002a60101a0009119b87002001405514a3153304249011369735f6e6f5f76616c7565203f2046616c73650014a0820a29462b300159800981118219baa00b8a508a51410514a315330424911369735f6e6f5f646174756d203f2046616c73650014a08209041454cc1092410f746f646f3a2072656d6f766520697400159800800c528c54cc1092411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0820a294104119198008009bac3047304830480082259800800c528456600266e3cdd71824000802c528c4cc008008c124005042208c8a99820a4813465787065637420536f6d65286f776e5f696e70757429203d20696e70757473207c3e2066696e645f696e70757428696e7075742900164100660286eb0c1140208cdd7982318219baa00100b40fc81f86080608060806080608000260786ea8cc01cdd6181f80081c181f800981d1baa0103039375401501d80ec07603a81f8c0ec004c0ecc0f0004c0dcdd5003456600260240031325980080446600244646600200200644660060026004005370e90054888c966002603400313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f0078992cc004c11800e013008410c6eb80050461821800a082375a0026084005004410c608000281f0c0f0dd50024566002603200313259800800c00e264b300100180240120091332259800800c01a264b30010018acc004c11400a2b3001301f3040375400313259800800c022264b3001001804c0260131332259800800c02e264b3001001806403201900c899912cc00400601d13259800800c03e01f00f807c4c966002609c0070118082096375c0028270c12c0050491bae001304a002412c60900028230dd6800982380140250481822800a0863041375400300740f90074109007803c01e00e8230c10c0050411bad00130420028022086304000140f860786ea80122b300130170018992cc00400600713259800800c012009004899912cc00400600d13259800800c01e00f007803c4cc89660020030098992cc00400601500a805402a264b30013049003806402d0461bae0014124608c0028220dd70009822801208c304300141046eb4004c10800a0088218c10000503e181e1baa004801207240e481c8c0e8dd5001cc0dcdd500424444646644b3001301d0048992cc00400604513259800800c566002608a00519800800c00e046802a0468212047023811c08d0461821800a082303f375401f159800980e00244c9660020030228992cc0040062b300130450028cc00400600702340150234109023811c08e0468230c10c005041181f9baa00f8acc004c068012264b300100181144c9660020031598009822801466002003003811a01a811a084811c08e047023411860860028208c0fcdd5007c56600266e1d20060048acc004c0fcdd5007c00604282022b30013370e900400244c9660020030228992cc0040062b300130450028cc00400600702340110234109023811c08e0468230c10c005041181f9baa00f8acc004c018012264b300100181144c9660020031598009822801466002003003811a008811a084811c08e047023411860860028208c0fcdd5007c08503c207840f081e103c207822259800980f181f9baa0038992cc00400600513259800800c4c9660020030048992cc00400600b132598009824801c4cc8966002604a00313259800800c026264b30010018acc004c13400a26530010018014015001111192cc004c0ac006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c4c96600260ae00713301b0012259800801402a26464b300100180c40620311332259800800c6600202100189802982e803202080d406a03501a41786eb4004c15c00a03082e0c154004c16000905640510541bab001809c04e02682b8c1500050521bae0013053002415060a20028278c134dd5001c566002605400313259800800c03e264b30010018084042021010899912cc00400602513259800800c04e027013809c4cc89660020030158992cc00400602d01680b405a264b3001305a003805c05d0571bae001416860ae00282a8dd7000982b00120ae305400141486eb8004c14c0090541828800a09e304d375400700e41288250c12cdd5001402904a402a01500a805209c304b0014124608e6ea801a2b300130240018992cc00400601313259800800c02a015132598009827001c4cc04800489660020050078992cc00400633001001898011828801c039011403a01d00e80720a4304f002413500b412c6eb000601500a413860960028248c11cdd50034021044208813300d0012259800801402626464b3001001805402a01500a899912cc00400601900c8992cc00400601b13259800800c03a01d00e80744cc89660020030108992cc004006023011808c046264b3001305500389805982a80640490521bae001415460a40028280dd7000982880120a4304f00141346eb000601900c41406eb8004c12400904e1823800982500120903044375400900641186eac00600b005802a09230460014110608c005003801c00e0068238c11000504218201baa003800a07a19800912cc00400629344c966002003149a264b3001337206eb8c100c11000cdd71820000c4cc010010cc10c004c11400a2a6607e921326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f72646572001640f860860028208c10c00504048888c8cc0040040148966002003133045337606ea4014dd300225eb7bdb1822653001375c608600337566088003304800248896600266e4002400e26609266ec0dd48049ba60080058acc004cdc7804801c4c966002604c608e6ea800626609466ec0dd4805182598241baa0010028801208a9800804c022004803a26609266ec0dd48019ba60023300600600141108220608c00282224444646600200200a44b300100189982299bb0375200a6ea00112f5bded8c113298009bae30430019bad304400198240012444b300133720012007133049337606ea4024dd4004002c56600266e3c02400e264b300130263047375400313304a337606ea4028c12cc120dd5000801440090454c004026011002401d133049337606ea400cdd400119803003000a088411030460014111259800800c528c528207e91192cc004c074c0fcdd5000c52f5bded8c113756608660806ea800503d19809001000c888c8cc004004010896600200310048994c004dd71821000cdd69821800ccc00c00cc11c0090041822800a086912cc004006297ae0899820981f1821000998010011821800a080912cc004c070c0f8dd5000c4c8cc108cdd8182180098219822000a5eb7bdb180c10cc0fcdd5000c4c8cc004004c8cc004004dd59822182298209baa0032259800800c52f5c113304430423045001330020023046001410c44b30010018a5eb7bdb1822646644660040046600e00e00244b30010018801c4cc118c11c004cc008008c1200050451822801198010011822800a08440f12329800800c00a97ae04004444b30010028800c660020073045002998219822001000a0064109223304137520020052259800980e99b8600148012266e0ccdc700119b83001480112020899b863371c00466e0c00520044808103c48a6002003337026e34008006004b8c48896600266e2400920008800c6600200733708004900a4cdc599b803370a004900a240c0002801903d488dca19b8a0020019b804800a6e05200091111919800800802912cc004006200b13259800800c4cc010c11c00801a26600a608e004660060060028228c11c0050444dc0240032301a33040301633040375200297ae0330404c0103d87a80004bd704888c8cc004004010896600200310048998019822800998010011823000a0869112cc004c078c0fcdd5001c4c9660020030028992cc004006007003801c00e264b30013047003802c0110441bae001411c60880028210c100dd5001c00503d4dc02400737009003cdc02401f25980099b87371a0029020440062a6607892138657870656374206279746561727261792e6c656e67746828726f6f7429203d3d20626c616b6532625f3235365f6469676573745f73697a65001640ed303c375401b22225980099b88002480c22600200515980099b87002480c2266008900111801000c56600266e20009203889980199b8e488103020408003370000490189180119bca4a2003124bded8c10140000101200040f881f103e4dc3a41fc0722337600046ea0005222222222222222222222222222229800980e80ec888a6002009003801488a6002007001801200840813017017980b00b4c044046444b30010028cc00400e60300034bd7020068992cc004006264b30010038800c6600200b33019301a003001a5eb8100520c0375c60c2007198008024c18800666030004660286eb8c18400cdd71830800a008417c60c200482f244b3001303a3370c002900244cdc5a41fc066602800466e0c0052004899b8b48000cdc59980a8010009980a00119b833011001480110594888c8cc00400400c896600266e2400c0062910100899b8b3301800500133002002301400141712225980099b8900348002266026004003133013001002416922329800800c00e00480088896600200510018994c00401260c800798008014dd7182f800cdd59830000c888c966002604800314c0103d87a800089820198331ba60014bd7020c2329800800c00e00480088896600200510018994c00401260d600798008014dd71833000cdd69833800c888c966002609200314c103d87a800089823998369ba80014bd7020d0337000040028141004183480120ce40888020c18800906048c8cc004004008896600200314bd6f7b63044c8cc180cdd8182e8009ba63233001001375660be00444b30010018a5eb7bdb182264660c666ec0c180004dd4180a9bad3061001330030033065002306300141846600600660c400460c000282f2444b30013375e60c060ba6ea8c0dcc174dd5000980700144c96600200319800800c4cdd7800802415502a41560ab05582aa0c63259800981c982e9baa00189830982f1baa0018a9982e2493265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016416c60c060c260c260ba6ea8c180c184c174dd5000c52820b49112cc004cdd79830182e9baa001300e0028992cc00400633001001899baf00100482b205482b415a0ad056418c64b30013039305d375400313061305e3754003153305c49012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016416c60c060c260c260ba6ea8006294105a48966002003148002260226600400460c000282ea44444653001001801c0090011112cc004cdc480124001130014bd70448c8ca600200d30170059180299834001000cdd69832801200c30630019800804c022002803905f48888c8cc00400400888cc01920022598009804800c4c0092f5c1123232980080348c018cc19c0080066eb4c1900090061831000cc00402200f3017001401882f244453001004801c00a46600800246006002803922222222222222222980091112cc004c134006200919800802400e6464004602c002660e266ec0dd48011ba80014bd6f7b6304888c966002606600314c103d87a8000898279983a9ba60014bd7020e0980080140160092223259800982a000c530103d87a8000898291983c1ba80014bd7020e633700002004819901420d89806006488c8cc00400400c8966002609a0031337149110130000038acc004cdc4000a40011337149101012d0033002002302300189980899b8400148050cdc599b803370a002900a240c0006836106c488896600266e240112002899812cc00401200700140340051330250029800980e802400e002806906c488896600266e2001120048acc004cdc4001240091330259800802400e00280692201200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100899812cc0040120074892000000000000000000000000000000000000000000000000000000000000000000040353001301d002800d22120000000000000000000000000000000000000000000000000000000000000000000403483622b300133712900200144cc095221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f9761009800980e802400e002806a26604b3001002800d2212000000000000000000000000000000000000000000000000000000000000000000040353001301d004801d221200000000000000000000000000000000000000000000000000000000000000000004034836106c4c0100124466002444646466ec0c8dd39983a98390009983a9839800a5eb80cdd8183880118388009839000cc00401a44003004801cdd69838800a00c9800802c88006007002800a00a2233002480088c96600266e2400520048acc004c13c00633001004801c00a460326ea000501a4566002609c00319800802400e66e00009203f9180c9ba830243026001406915980099b87002482f80626466002002460346ea400488cc0192002259800980e000c4c0092201008cc00401e00d33700002903fc8cc0100108c010cdc5001000a01441c519800802400e66e00009207f9180c9ba9001401c837106e20dc8acc004cdc3800a401919800802400e66e0000920ff02919802a40044b30013370e004906600c492f7b63001014000010120008992cc004cdc38012417c0519800803c01a66012012440032301c3374a004002805a330010078034cdc0001241fe0329800804401e66014014440030019180e99ba5003001403480e90712cc004cdc4a41002800513370066e0000920ff134803a266e0000920f10141c0838101a456600266e1c00520088acc004cdc38012417c0519800802400e6600c00c4400323019374e002804233001004801ccdc0001241fe0329800802c0126600e00e440030019180d1ba7001402880d106e4566002607000315980099b87002483f80a2646466002002460366e9800488cc01d2002259800980e800c4c0092f5bded8c1123232980080348c018cc1ec0080066eb4c1e00090061919bb0307b001307b307c001375860ec00330010098044c0ac00500520e433006006220028cc00401200733700004905f8148c8ca60020030039180e1ba60014004444b300133712004900044c0052f5bded8c112323298008034c0ac0164600a660f8004003375a60f20048030c8cdd8183e000983e183e8009bac30770019800805402600280290731980380391001203441b9124bded8c010140000101200041b8837106e20dc33706002902048c8cc004004008896600200314bd6f7b63044ca60026eb8c1b80066eacc1bc0066600600660e60049112cc00400a2a660e092124657870656374205061697228702c205b5f2c202e2e5d206173207829203d20696e6e657200168cc004006007323200432330010010042259800800c5268992cc0040062b30013004375a60ec60f2005149a2a660e892011f76616c756520646f65736e2774207361746973667920707265646963617465001641cd133225980099b90375c60ee0046eb8c1dc0062b30013006375a60f00051330050053307a001307c0038a9983b2491f76616c756520646f65736e2774207361746973667920707265646963617465001641d51533076491276b65797320696e207061697273206172656e277420696e20617363656e64696e67206f72646572001641d460f200460f200283b8c1e400507614c004c14400694294507048894cc1cd2401234475706c696361746520706f6c69637920696e20746865206173736574206c6973742e0016405c839860e200283792222222298009114c004cc0d400c00a97adef6c60911192cc004c160c1e4dd5000c4ca6002007375c60fc003375c60fc60fe00300440406eb0c1f4c1e8dd5000c54cc1e124121546f6b656e2068617368206e6f7420666f756e6420696e20746f6b656e206d6170001641dc646600200200a44b30010018a60103d87a80008992cc004cdc78031bae307b0018982c1983f183e000a5eb8226600600661000200483c8c1f800507c2068911919800800980d001912cc004006297adef6c60899912cc004c8cc004004018896600200314a115980099b8f375c60fc00200914a3133002002307f00141e083e23300133038006002800c88a6002003005801c009011206e8800a0ec375c60f40026600400460f600283c244464b30010038991919911980700119b8a488101280059800800c4cdc52441035b5d2900006899b8a489035b5f20009800800ccdc52441025d2900006914c00402a00530070014029229800805400a002805102e20f85980099b880014803a266e0120f2010018acc004cdc4000a41000513370066e01208014001480362c83b10761bac3079002375a60ee0026466ec0dd4183b8009ba73078001375400713259800800c4cdc52441027b7d00003899b8a489037b5f20003232330010010032259800800c400e264b30010018994c00402a60f8003337149101023a200098008054c1f400600a805100a183f80144ca6002015307c00199b8a489023a200098008054c1f4006600e66008008004805100a183f80120fa307f00141f066e29220102207d0000341e46eac00e264b3001001899b8a489025b5d00003899b8a489035b5f20009800800ccdc52441015d00003914c00401e0053004001401d229800803c00a002803902b20f2375800713300a375a0060051323371491102682700329800800cc0acdc68014cdc52450127000044004444b300133710004900044006264664530010069818002ccdc599b800025980099b88002480522903045206e41ec66e2ccdc0000acc004cdc4000a40291481822903720f6004401866e0c00520203370c002901019b8e00400241e06eb800d07c1b8a4881022c2000911112cc004cdc4802a400d13302e9800802c012005001402800713302e00398009812802c012005001402883aa4444b3001337100089004456600266e200092008899816cc004012007002800a01048812085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100899816cc004012007489200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402530013024002800d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483a22b300133712900400144cc0b52212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b10098009812002400e6048005001402113302d980080140069101200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402530013024004801d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483a1074488c8cc00400400c896600200314bd6f7b63044c8ca60026eacc1e400a6600800860fa0072229800800c022b300159800982d80244c16c00e2941079452210089b943371400800683ca00480890371bae3077001307a00141e130020024888888a6002600a00b22222330359800802c012606200680f260026607000a60620079800a400148102002b8c66002902052040800ae319800a41000348102002b8c66002906000d2040800ae30911112cc004cdc4802a401d13303a9800802c01e007002800a01c00489981d0024c004c0c001600f003801400500e210202488888c96600330013370e0026eb4c20c04c20004dd5001528528a0fa89981b4c00401a00b3032004407c6644b3001337100069008456600266e20009201089981c4c00400e00b002800a016488120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0089981c4c00400e00b4892085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302e002800d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403083fa2b300133712900800144cc0e122120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0098009817001c016605c005001402d1330389800801400691012085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302e003802d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403083f907f1bad30830130800137540046606c6eb8c168c20004dd50011bae30593080013754005153307e49120657870656374206272616e636820213d206e65696768626f722e6e6962626c65001641f46607000a606200723259800982d183d9baa0018992cc0040060f113233046001225980080144c96600266e3cdd99ba60010078800c54cc1fd241306578706563742063626f722e73657269616c6973652876616c756529203d3d2073657269616c697365645f76616c7565001641f8601c0071323259800800c1f60fb07d83ec4cc896600200307f8998261bab001225980080144c01cc2280402226464b300100184180c20c061060308301899912cc00400610a030850184280c4c8c018c23c0401cdd6800c2140508f011bae001308801002423404610c0200261120200484380a0ff07f83fa11202375c002610402004843808c20004004c20c04009081011bab00183c41e20f0841008c1fcc1f0dd5000c54cc1e924014465787065637420536f6d6528646573657269616c697365645f76616c756529203d2063626f722e646573657269616c6973652873657269616c697365645f76616c756529001641e464b3001305a0018a6103d87a80008992cc006600260b66eb4c1f400694294507a4530103d87a80008982c9983f983e000a5eb8107a4c00488006444b3001337120029000452f7b63010140000101200089980119b8e0053370200800266e0400400d07c48896600266e2400520008a5ef6c601014000010120008998014c004cdc0802000c00e00ab8c19b8100100341f1001400c83c8dc6800a44453001223300122225980099b870024808220091325980098311842009baa0018cc00401e440053303f0054881200000000000000000000000000000000000000000000000000000000000000000008024c0e800e004803a26464b30013371000200b15330850149012e696e76616c696420747265652c206368696c6472656e206d75737420626520736f7274656420627920696e64657800168992cc004c198c21c04dd5000c56600266e1c01800a3300100a910014cc108022600201522001984400801ccdc5002cc00528d20028032f2480526eacc22c04c22004dd5000cc0f401a00a80523300100a910014cc108021220120000000000000000000000000000000000000000000000000000000000000000000803cc0f401a00a805108501454cc218052412a65787065637420536f6d65287461696c5f6e6f64657329203d206c6973742e7461696c286e6f646573290016421404b30010068a6103d87a80008983199844809ba6308b010064bd702110024210046eb4c21404004c8cdd81844808009844809845008009bac30880130850137540028410096600200714c103d87a8000898301984300991ba7330870130840100133087013085010014bd70184380801a5eb8108501210202225980098301840809baa002899191981d000992cc0040062a661060292012e696e76616c6964206368696c64206861736865732c206d7573742062652061206e6f6e2d656d707479206c69737400168acc004c2240400626eb8c2200400626603200297ae0421804843008c0fe600200d22002a5eb826eacc21c04c2200400a90004cdc5001800a00c375c610c020026104026ea800a264646644b3001980099b8f37280040034a14a284180a2a661080266e59241056b65793a20003732660186ea40092201001533084013372c920106706174683a20003732660186ea40052201001533084014912d696e76616c696420747265652c2070617468206973206e6f74207468652068617368206f6620746865206b65790016899192cc004cdc7800803c4cc0f8cc0a000c008dca1bae308b01308c010058a998430099b964910e706174685f6e6962626c65733a200037326601c6ea40052201001533086013372c9201107072656669785f6e6962626c65733a200037326601c6ea401d22010015330860149128696e76616c696420747265652c2070726566697820646f6573206e6f74206d61746368207061746800164214053001002a400100140986e34015083011bae308701001375c610e02004610e020026104026ea800907f488c8ca6002003480020068008888c8c96600200714881200000000000000000000000000000000000000000000000000000000000000000008992cc00400626464b300130670018994c0040126eb4c234040066eb8c23404c238040050051844809baa0028acc004c1980062646608066e2cdd69846809845009baa001375c60c86114026ea8004dd718319845009baa001308c01308d013089013754005132330403302a375c611a020020106eb8c23404c23804004c23404c22404dd5001210c02421804610e026ea8004c2280401226464b300130670018994c0040126eb4c234040066eb8c23404c238040050051844809baa0028acc004c19800626465300100b804c007300100a800c01500a4c23804c23c0400900f18031bad308d01001308901375400513233223322980080740320039800806c006010806a60d466120026ea0cc11c008030cc24004dd499817001000998480098488098490080225eb810121bae308f010023008001308e01001375a611a020026112026ea800908601210c023087013754002611402008844008c2280400d08701111194c00402600f001cc0040220030044021002403860080046e00c0e4008dca0014888cc88ca60020034800200880088896600200313303c3302600500200489919912cc004c19c00a26465300100a803c0073001008800cc23c040190084dd718470098478080120203002375a611a020026112026ea800e2b30013066002899194c00402a00f001cc004022003308f010064021308e01308f01002403c60046eb4c23404004c22404dd5001c4c8cc8a60026eb8c23c0400a6008003309001007488a600201d00b80166002019002800a018983599848809ba8330480033041002330910137526605e006004661220261240261260200a97ae0404c308e01001375a611a020026112026ea800d08601210c0230860137540026e00c0f000cc22404005087011b940033728004911194c004a600244003001a441004009222225980099b8f9800802400a006803801633001004800c00d007454cc2140524013465787065637420696e636c7564696e67286b65792c206f6c645f76616c75652c2070726f6f6629203d3d2073656c662e726f6f74001642100522225980099b8f330070030010048cc00400e0050014019153308401490129657870656374206578636c7564696e67286b65792c2070726f6f6629203d3d2073656c662e726f6f740016420c049112cc004c18c0be2646466453001308d01308d010029bac308c01002984680984680800cdd7184600800a444530013756612002009375861200261220261220261220261220200930910130910100298480080124444646530013097010019bae3096010019bac30960100e488a60026eb8c2640400e6eb8c26404c26804c2680400e64646600200200644b30010018a5eb8226644b30015980099baf309e01309b013754613c02613e026136026ea80080162646600200264660020026eacc28004c28404c27404dd5185000985080984e809baa0042259800800c52f5c113233223233001001375661440200844b30010018801c4c8cc29804dd399853009ba9005330a60130a301001330a60130a4010014bd7019801801985400801185300800a14802375c613c020026600600661460200461420200284f808896600200314a115980099b8f375c6140026eb0c28004004026294626600400461420200284d00909e01452821300289984e8080119802002000c4cc01001000509801184e00800984e80800a134023047002984c80984b009baa0669bae309901007984c80802a444444b300100484380c4c96600261420200b13259800800c56600260f6613a026ea8006264b300100184580c4c96600200313259800800c23406264b300130a6010028cc00400e2b30010018acc004c20004c28404dd5000c4c966002003090018992cc004006122031332259800800c24c06264b300100184a00c4c966002615802007133070004225980080144cc1c800c896600200519800981d002cc8c8cc004004064896600200314bd7081018000810180008101800044cc8966002600a0051330b301374e66166020046eb0c2d004004cc2cc04c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c1159800acc004cdd7985a009858809baa30b40130b50130b101375400402d1323300100132330010013756616c02616e026166026ea8c2d804c2dc04c2cc04dd5002112cc004006297ae0899199119198008009bab30b8010042259800800c400e26466178026e9ccc2f004dd48029985e00985c808009985e00985d00800a5eb80cc00c00cc2f804008c2f0040050ba011bae30b4010013300300330b90100230b70100142d40444b30010018a508acc004cdc79bae30b6013758616c0200203314a313300200230b70100142c00485a00a29410ae0144cc2cc04c2d004004cc2cc04dd399859808011bac30b40130b501001330b30130b40130b50130b5010014bd7044cc2cc04c2d004004cc2cc04c2d004c2d404004cc2cc04dd399859808011bac30b40130b50130b5010014bd70215c0242b80461640200266004004616602002858008cc11c03405a64646600200204844b30010018a5eb841018000810180008101800044cc8966002600a0051330b301374e66166020046eb0c2d004004cc2cc04c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c1159800acc004cdd7985a009858809baa0020168991980080099198008009bab30b60130b70130b301375400844b30010018a5eb82264664464660020026eacc2e004010896600200310038991985e009ba7330bc01375200a6617802617202002661780261740200297ae03300300330be0100230bc0100142e8046eb8c2d004004cc00c00cc2e404008c2dc040050b501112cc00400629422b30013371e6eb8c2d804dd6185b0080080cc528c4cc008008c2dc040050b0012168028a5042b8051330b30130b401001330b301374e66166020046eb0c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c11330b30130b401001330b30130b40130b501001330b301374e66166020046eb0c2d004c2d404c2d4040052f5c08570090ae0118590080099801001185980800a160023304600d016488a600266098607a016609600730b3010029bac30b201002985980800cdd6185900800a4444530013758616e020053758616e0261700200530910130443758616e026170020093758616e020089111192cc00400a1500313259800985f00801c56600200d0aa018992cc004c2fc0401e264b3001598008034528c54cc2e8052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085c80a2b3001598008024528c54cc2e80524011e69735f7769746864726177616c5f6665655f70616964203f2046616c73650014a085c80a2b300159800992cc004006330010018992cc004006330010018cc004dd7186080985f009baa0029bae30c10130be013754003376603f30bd01375404a9111192cc004c2840400a266e3e60020030039bb3374c0293758618c026186026ea80a903f002456600261400200513232332259800acc0066002660c86094002031374c6094005223370e00400284c00a29462a6618a0292011a69735f62616c616e63655f75706461746564203f2046616c73650014a086200a2b30013371f3001005803cdd6186500986580801c006004822002229462a6618a029211e69735f6e65775f62616c616e63655f636f7272656374203f2046616c73650014a086200a29410c4011bae30c801001375c6190020046190020026186026ea80aa29410c001218002306d00442e00506d42e006170030b80185c00a186023259800984c80985e809baa0018986080985f009baa0018a9985e00a4812c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642ec04618002618202618202617a026ea800e16c02836216c030b60185b00c2d8050c201192cc004c26004c2f004dd5000c4c30004c2f404dd5000c54cc2ec0524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642e804617e026180026180026178026ea8c2fc04c30004c2f004dd5001c528c54cc2e80524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a085c80a2b30015980099baf374c612202660b2660b265300100180652f5bded8c080088896600200510018cc00400e618602005329800800c00a6eacc30c04c31004c30004dd51861809862009860009baa30c3010034004444b30010028800c4c8cc8a600200d30c9010059919800800802912cc0040062661920266ec0dd48021ba60034bd6f7b63044ca60026eb8c31c040066eacc320040066198020049112cc004cdc8004001c4cc33404cdd81ba9008374c00e00b15980099b8f0080038992cc004c2a804c32c04dd5000c4cc33804cdd81ba900930cf0130cc013754002005100243240464b300159800800c528c528219a028a60103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c001182c194c0040060114bd6f7b63020022225980080144006330010039861808014ca60020030029bab30c30130c40130c0013754618602006800888966002005100189919914c00401a61920200b32330010010052259800800c4cc32404cdd81ba9004374c00697adef6c608994c004dd7186380800cdd5986400800cc330040092225980099b900080038998668099bb037520106e9801c0162b30013371e010007132598009855009865809baa0018998670099bb03752012619e026198026ea800400a2004864808c966002b30010018a518a5043340514c103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c001182c194c0040060154bd6f7b63020022225980080144006330010039861808014ca60020030029bab30c30130c40130c0013754618602006800888966002005100189919914c00401a61920200b32330010010052259800800c4cc32404cdd81ba9004374c00697adef6c608994c004dd7186380800cdd5986400800cc330040092225980099b900080038998668099bb037520106e9801c0162b30013371e010007132598009855009865809baa0018998670099bb03752012619e026198026ea800400a2004864808c966002b30010018a518a5043340514c103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c0011ba60018a518a9985d00a4812569735f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a085c80a2b300159800cc0040be6e98c160cc164c24404dd5984b00985e009baa30960130bc013754040003223370e00400284680a29462a66174029211769735f746f6b656e735f6275726e74203f2046616c73650014a085c80a2b3001323300100102f2259800800c528456600266e3cdd71860808008194528c4cc008008c308040050bb01217e028a518a9985d00a492669735f68796472615f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a085c80a29410b90145282172028a5042e40514a085c80a29410b9011848009982180601242ac050bc01185e8080321760285480a1760230bc0100242e804b30010038a518acc004c2f00400e264b300100185380c4c966002617c020051980098478099821007011cdd31847809bab30940130ba013754003223370e00400284580a1500285d808c2f0040050ba01191919800800802912cc004006297ae0899912cc004c01400a26617e020046600800800313300400400142e804617c02002617e0200285e008cc1480a008a2a6616c02920118756e6578706563746564206f74686572206f7574707574730014a085c8090b9010899192cc0040061360309b0184d80c26c0626644b300100184e80c4cc1e0dd5800912cc00400a2600e616c020111323259800800c28406142030a10185080c4cc89660020030a30185180c28c06264600c61760200e6eb40061460285d808dd7000985a0080121720230b20100130b50100242cc0509d0184e80c274050b5011bae00130ae0100242cc04615802002615e0200485680a26464b300100184c80c264061320309901899912cc00400613603133076375600244b300100289803985a0080444c8c96600200309f0184f80c27c0613e031332259800800c28406142030a1018991803185c808039bad00185080a17202375c00261640200485b808c2c004004c2cc040090b101426c061360309b0142cc046eb8004c2b0040090b10118550080098568080121560284a80a1520237560030940184a00c250050ac01185480800a14e0237560026150020050910184880c244050a901185300800a1480230a201375400308f01427c0508f0184780c23c0611e0285380a11c02837211c02851808c290040050a2011852008014230061180308c0184600a14a0230a201001428004613c026ea80061140284d80a1140308a0184500c228050a301192cc004c1e4c27404dd5000c4c28404c27804dd5000c54cc270052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016426c04614002614202614202613a026ea8c28004c28404c27404dd5000c2200509e01184f80802213a020c25804c25804c25804004c25404008308b010013087013754660a46eb0c2280400420c04c22804004c21404dd502dc4ca600253001001a5eb7bdb182446604c0046eacc18cc22404dd518319844809baa001400929800800d2f5bded8c12233026002375660c66112026ea8005002488896600266e3e6002007002800a014004899805801800c54cc220052413065787065637420696e636c7564696e67286b65792c2076616c75652c2070726f6f6629203d3d2073656c662e726f6f740016421c049112cc004c1980ce26464664530013091013091010029bac309001002984880984880984880984880800cdd7184800800a4445300137566128020093758612802612a02612a02612a02612a020093095010029bae30940100248888ca6002613402003375c613202003375861320201a9114c004dd7184e00801cdd7184e00984e80984e80801cc8c8cc00400400c896600200314bd7044cc8966002b30013375e614202613c026ea8c28404c28804c27804dd5001002c4c8cc004004c8cc004004dd59851809852009850009baa30a30130a40130a001375400844b30010018a5eb82264664464660020026eacc294040108966002003100389919854809ba7330a901375200a6615202614c020026615202614e0200297ae03300300330ab0100230a901001429c046eb8c28404004cc00c00cc29804008c290040050a201112cc00400629422b30013371e6eb8c28c04dd6185180800804c528c4cc008008c2900400509d012142028a50426c051330a00100233004004001899802002000a13602309f0100130a0010014274046094005309c0130990137540d3309c0100648888966002007089018992cc004c28c04012264b30010018acc004c1f4c27c04dd5000c4c96600200308d018992cc004006264b300100184780c4c96600261500200519800801c5660020031598009840809851809baa0018992cc00400612c0313259800800c25c06264b300130ab01003899837800912cc00400a26645300130af010029bac30ae01002985780800cdd6185700800a444530013758616402005308c01303f3758616402616602009308d01303f3758616402616602005375861640200891112cc0040061440313259800985c00801456600200b0a4018992cc004c2e40401a264b3001598008034528c54cc2d005241176e6f5f6f746865725f696e70757473203f2046616c73650014a085980a2b300159800802c528c54cc2d0052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085980a2b30015980099912cc004006330010018992cc004006330010018cc004dd7185e00985c809baa0029bae30bc0130b9013754003376603130b801375403a9111192cc004c2640400a266e3e60020030039bb3374c0113758618202617c026ea8089036002456600261360200513232332259800cc004cc17cc114004c1780326e98c11400a4466e1c0080050930144cdc7cc00401600f3758618a02618c02007001801207e0088a5042fc046eb8c30c04004dd7186180801186180800985f009baa0228a5042ec0485d808c1a00110b30141a10b30185980c2cc061660285f008c9660026128026170026ea800626178026172026ea80062a6616e029212c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642d8046176026178026178026170026ea801216202833a162030b10185880c2c4050bd011822008192cc004c24804c2d804dd5000c4c2e804c2dc04dd5000c54cc2d4052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642d004617202617402617402616c026ea8c2e404c2e804c2d804dd5001c528c54cc2d00524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a085980a2b30015980099baf374c611602660a6605e01060a460600146e9800629462a66168029212c69735f63616e63656c5f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a085980a2b300159800cc0040966e98cc14cc148c22c04dd5984800985b009baa30900130b6013754030003223370e00400284380a29462a66168029211d69735f6d696e745f76616c75655f636f7272656374203f2046616c73650014a085980a2b300132330010010252259800800c528456600266e3cdd7185d808008144528c4cc008008c2f0040050b5012172028a518a9985a00a492d69735f68796472615f63616e63656c5f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a085980a29410b30145282166028a5042cc0514a085980a29410b3011981e982180780dc294050b601185b80802a16a0285180a16a0230b60100142d004194c00404a97ae10101800081018000810180004896600260060051330ae01374e6615c020046eb0c2bc04004cc2b804c21804004cc2b804c214040052f5c1159800acc004cdd79857809856009baa30860130ac01375400401f1323300100132330010013756611002615c026ea8c22004c2b804dd5002112cc004006297ae08991991199119801001000912cc0040062007132330b701374e6616e026ea4014cc2dc04c2d004004cc2dc04c2d4040052f5c066006006617202004616e0200285a808dd59859008019bae30af010013300300330b40100230b20100142c00444b30010018a508acc004cdc79bae30b101375861620200203514a313300200230b20100142ac0485780a29410a90144cc2b804c2bc04004cc2b804dd399857008011bac308601001330ae013085010014bd7044cc2b804c2bc04004cc2b804c21804004cc2b804dd399857008011bac3085010014bd7021520242a40482d0cc110020040c8c8cc004004074896600200314bd7081018000810180008101800044cc8966002600a0051330b001374e66160020046eb0c2c404004cc2c004c2c404c2c804004cc2c004c2c404c2c804c2c8040052f5c1159800acc004cdd79858809857009baa0020118991980080099198008009bab30b30130b40130b001375400844b30010018a5eb82264664464660020026eacc2d404010896600200310038991985c809ba7330b901375200a6617202616c020026617202616e0200297ae03300300330bb0100230b90100142dc046eb8c2c404004cc00c00cc2d804008c2d0040050b201112cc00400629422b30013371e6eb8c2cc04dd618598080080e4528c4cc008008c2d0040050ad012162028a5042ac051330b00130b101001330b001374e66160020046eb0c2c404c2c804004cc2c004c2c404c2c804c2c8040052f5c11330b00130b101001330b00130b10130b201001330b001374e66160020046eb0c2c404c2c804c2c8040052f5c08558090ab0118578080099801001185800800a15a0233043008010899192cc0040061380309c0184e00c2700626644b300100184f00c4cc1d4dd5800912cc00400a2600e6166020111323259800800c28806144030a20185100c4cc89660020030a40185200c29006264600c61700200e6eb40061480285c008dd7000985880801216c0230af0100130b20100242c00509e0184f00c278050b2011bae00130ab0100242c00461520200261580200485500a13002854008dd5800c25c0612e030970142ac04615002002853008c29004dd5000c254050a10142540612a030950184a80a1520284800a0e084800a14a0230a601001429004614c0200508e0184700c2380611c02853808c290040050a2011850009baa00184600a13a0284600c230061180308c0142940464b3001307b309f013754003130a30130a0013754003153309e014913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016427404614402614602614602613e026ea8c28804c28c04c27c04dd5000c228050a001185080801a13e020c26404c26404c26404008308f01001308b013754660ac6eb0c2380400421c04c23804004c22404dd502fc4c96600260ca069132323298009bae3090013091013091013091013091013091013091013091013091013091010019848009846809baa05d98488080124446644b3001598009804984a80984b008014528c54cc240052401176e6f5f6f746865725f696e70757473203f2046616c73650014a084780a2b3001598009804984a80984b00800c528c54cc240052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a084780a2b30015980099baf374c60ce6530010019bac309601003a5eb7bdb1810011112cc00400a200319800801cc2640400a6530010018014dd5984c80984d00984b009baa309901309a013096013754613202006800888966002005100189919914c00401a613e0200b32330010010052259800800c4cc27c04cdd81ba9004374c00697adef6c608994c004dd7184e80800cdd5984f00800cc288040092225980099b900080038998518099bb037520106e9801c0162b30013371e010007132598009840009850809baa0018998520099bb03752012614a026144026ea800400a200484f808c966002b30010018a518a50428c0514c0103d87a80008983f19852009ba60014bd70213e02329800800c022006800888966002005100189919914c00401a61560200b32330010010052259800800c4cc2ac04cdd81ba9004375000697adef6c608994c004dd7185480800cdd6985500800cc2b8040092225980099b900080038998578099bb037520106ea001c0162b30013371e010007132598009846009856809baa0018998580099bb03752012616202615c026ea800400a2004855808c96600261180200314c0103d87a8000898450099858009ba80014bd702156023370000e0051330af01337606ea400cdd400119803003000a1540242a80430ac0100142a8048030dd71852008009bad30a50100130a7010024294051330a301337606ea400cdd300119803003000a13c0242780430a0010014278048030dd7184c008009bab309901001309b010024264048019096011ba63067329800800cdd6184b0080152f5bded8c080088896600200510018cc00400e613202005329800800c00a6eacc26404c26804c25804dd5184c80801a002222598008014400626466453001006984f80802cc8cc004004014896600200313309f01337606ea4010dd3001a5eb7bdb1822653001375c613a020033756613c0200330a20100248896600266e4002000e2661460266ec0dd48041ba60070058acc004cdc7804001c4c9660026100026142026ea80062661480266ec0dd48049852809851009baa0010028801213e023259800acc004006294629410a3014530103d87a80008983f19852009ba60014bd70213e02329800800c022006800888966002005100189919914c00401a61560200b32330010010052259800800c4cc2ac04cdd81ba9004375000697adef6c608994c004dd7185480800cdd6985500800cc2b8040092225980099b900080038998578099bb037520106ea001c0162b30013371e010007132598009846009856809baa0018998580099bb03752012616202615c026ea800400a2004855808c96600261180200314c0103d87a8000898450099858009ba80014bd702156023370000e0051330af01337606ea400cdd400119803003000a1540242a80430ac0100142a8048030dd71852008009bad30a50100130a7010024294051330a301337606ea400cdd300119803003000a13c0242780430a0010014278048030dd7184c008009bab309901001309b010024264048019096014528c54cc2400524011e69735f6163636f756e745f76616c75655f657175616c203f2046616c73650014a084780a2b30013232330010013758612e0261300261300261300261300261300261300200a44b30010018a508acc004cdc79bae3098010010038a51899801001184c80800a124024258046eb8c2540401a29462a661200292012d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a084780a294108f014528211e028a50423c046466446600400400244b30010018a5eb8410180008101800044cc8966002600a00513309701374e6612e020046eb0c26004004cc25c04c26004c264040052f5c1133097013098010013309701374e6612e020046eb0c26004c264040052f5c0849008c25804004cc008008c25c04005094011bac3094010073302b002003323322330020020012259800800c52f5c210180008101800044cc8966002600a00513309701374e6612e020046eb0c26004004cc25c04c26004c264040052f5c1133097013098010013309701374e6612e020046eb0c26004c264040052f5c0849008c25804004cc008008c25c04005094011bac3094010023302a0020031846009baa330573758611e0200211002611e020026114026ea81822b30013370e900301a44c8c8cc8a600261240261240200537586122020053092013092013092013092013092013092013092013092010019bae3091010014888a60026eacc254040126eb0c25404c25804c25804c25804c258040126eb8c2540400a6eb8c25404c2580400a6eb0c25404021222223259800800c20c06264b3001309d010028992cc0040062b30013077309901375400313259800800c23406264b30010018992cc00400611e0313259800985100801466002007159800800c56600260f2613a026ea8006264b300100184900c4c96600200313259800800c25006264b300100184a80c4c966002614e020071980080244cc1ac00489660020051332233223259800acc004c21c04c0e8dd6185680985700801c528c54cc2a0052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085380a2b30015980098109856809857008014528c54cc2a0052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085380a2b300159800acc004cdd79ba6307f3304730243758615a0200a608c60466eb0c2b404010dd3000c4cdd79ba6001374c607001114a085380a29462a66150029211a69735f76616c7565735f6d61746368696e67203f2046616c73650014a085380a2b300159800991980080080c112cc00400629422b30013371e6eb8c2bc0400406e29462660040046160020028548090ad014528c54cc2a0052412d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085380a2b3001980080c4dd31823183f9bab30840130aa0137546108026154026ea804a4466e1c00800507b4528c54cc2a00524011d69735f696e74656e745f746f6b656e5f6275726e74203f2046616c73650014a085380a29410a7014528214e028a50429c0514a0853808c1f8cc118c088dd6185600800982298119bac30ac0100230ab0100230ab01001332232330010010122259800800c52f5c21018000810180008101800044cc8966002600c0051330ad01374e6615a020046eb0c2b804004cc2b404c2b804c2bc04004cc2b404c2b804c2bc04c2bc040052f5c1159800980280144cc2b404c2b804004cc2b404dd399856808011bac30ae0130af01001330ad0130ae0130af0130af010014bd7044cc2b404c2b804004cc2b404c2b804c2bc04004cc2b404dd399856808011bac30ae0130af0130af010014bd7021500242a00461580200266004004615a02002855008cc100028040cc100018040cc88c8cc004004064896600200314bd7081018000810180008101800044cc8966002600c0051330ad01374e6615a020046eb0c2b804004cc2b404c2b804c2bc04004cc2b404c2b804c2bc04c2bc040052f5c1159800980280144cc2b404c2b804004cc2b404dd399856808011bac30ae0130af01001330ad0130ae0130af0130af010014bd7044cc2b404c2b804004cc2b404c2b804c2bc04004cc2b404dd399856808011bac30ae0130af0130af010014bd7021500242a00461580200266004004615a02002855008cc0fc028040cc0fc01804226464b300100184d00c268061340309a01899912cc00400613803133071375600244b30010028980398578080444c8c9660020030a00185000c28006140031332259800800c28806144030a2018991803185a008039bad00185100a16802375c002615a02004859008c2ac04004c2b8040090ac014270061380309c0142b8046eb8004c29c040090ac01185280800985400801214c0284b00a0de84b00a1480237560030950184a80c254050a701185200800a1440230a40100284980c24c061260309301429404614402002850008c27804dd5000c2440509b01424406122030910184880a1460284800a0d484800a13e0230a00100142780461400200508e0184700c2380611c02850808c2780400509c01184d009baa00184600a12e0284600c230061180308c01427c0464b3001307530990137540031309d01309a01375400315330980149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016425c04613802613a02613a026132026ea8c27004c27404c26404dd5000c2100509a01184d80800a132023232330010010032259800800c52f5c11332259800acc004cdd7984f80984e009baa309f0130a001309c01375400400b1323300100132330010013756614202614402613c026ea8c28404c28804c27804dd5002112cc004006297ae0899199119198008009bab30a3010042259800800c400e2646614e026e9ccc29c04dd480299853809852008009985380985280800a5eb80cc00c00cc2a404008c29c040050a5011bae309f010013300300330a40100230a20100142800444b30010018a508acc004cdc79bae30a101375861420200201514a313300200230a201001426c0484f80a29410990144cc27804008cc01001000626600800800284c808c27404004c2780400509b01182400186120020026118026ea8cc15cdd6184780800844009847808009845009baa0608acc004c1440d233001308a013754611a026114026ea816a4444b30010018801c4c966002007153308d0149012a6e6f7420656e6f756768206b65792d76616c756520706169727320746f206d617463682070726f6f667300168992cc004c1acc23c04dd500146600200d9800802cdd7184780800cdd7184800800cdd61849809848009baa0024021309401004984a00801a00c8a9984700a4930657870656374204d504644656c657465207b2070726f6f663a2064656c6574655f70726f6f66207d203d2070726f6f660016423404612402006848008c2440400508f014c22804dd5030244530013002002984800801cdd5984800984880801cc2440400522223232329800984c00984c00984c00984c00800cc25c040066eb8c25c0400922298009bae309a01309b01309b0100398241bae309a0100399198008009bac309b0100c2259800800c52f5c11332259800acc004cdd7984f00984d809baa309e01309f01309b01375400400d130783259800983c984d809baa0018a40011375a613e026138026ea800509901192cc004c1e4c26c04dd5000c5300103d87a8000899198008009bab30a001309d01375400444b30010018a6103d87a8000899192cc004c200040062b3001307f0018983e198510098500080125eb82298103d87a800042740513300400430a4010034274046eb8c27804004c2840400509f0121320232330010013756613e026140026138026ea8c27c04c28004c27004dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c024006260f66614202613e0200497ae08a60103d87a800042700513300400430a3010034270046eb8c27404004c2800400509e01452821300289984e8080119802002000c4cc01001000509801184e00800984e80800a134029bac309a01309b010079bae309a0100648888966002007082018992cc004c28404012264b30013079309d01375400313259800800c56600260fa613c026ea8006264b300100184a00c4c9660020030950184a80c2540612a0313259800985300801c4c96600200308b018992cc004c2a00400a264b300130800130a401375400313259800800c660020031323259800acc004cdd79ba63303437566156026158026158026158026158026150026ea81f8cc2a804dd4808a5eb80c2ac04c2b00400a29462a6614c029211769735f76616c75655f6d696e746564203f2046616c73650014a085280a2b30015980099198008009bac30ac0130ad0130ad0130ad0130ad0130ad0130ad0130ad0130ad0130a90137540fe44b30010018a508acc004cdc79bae30ad0100100f8a51899801001185700800a14e0242ac0514a315330a60149011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085280a2b3001598009843009853809baa01a8992cc0056600266e3cc09c00402229462a6614e02920134636f6d707574655f747265655f68617368287472656529203d3d20696e7075745f6d65726b6c655f726f6f74203f2046616c73650014a085300a2b30015980099baf374c60980026e9800a29462a6614e029212f6b65795f76616c756573203d3d206f75747075745f6d65726b6c655f7265636f72645f6c697374203f2046616c73650014a085300a2b30013371e6eb8c2b004c2a404dd5002245200000000000000000000000000000000000000000000000000000000000000000008a518a9985380a494d6f75747075745f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085300a29410a6014528214c0230ab0130a801375403513371e60a66eb8c2ac04c2a004dd5001cc004c14c01e00337586156026150026ea806901b214a028a518a9985300a4811769735f747265655f75706461746564203f2046616c73650014a085280a29410a5014528214a0237566154020033001323300100100d2259800800c52f5c1133225980099baf30ad0130aa0137540040251330ac0100233004004001899802002000a14e0230ab0100130ac0100142a4054bd708101a0008101a000488c9660026108026150026ea800626644b30010018cc00400626615a026e98cc2b404cdd81ba937660026ea4dd99ba60023756615c020086615a026e98cc120dd59842808021981b9bab30850130ab01375400a6615a026ea40512f5c097ae085080a0ee85080c28406142030a10142c005300137566106026152026ea800e02501a40d86158026152026ea80062a6614e029212f65787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206f75747075742e646174756d00164298046102026150026ea8009056426c05055426c061360309b0184d80a1560230a80130a501375400308e0142880460fa6148026ea800611802852808c298040050a4011919800800804912cc004006297ae0899912cc0056600266ebcc2a404c29804dd5001008c4c20c04c966002610802614c026ea80062900044dd69855009853809baa00142900464b300130840130a601375400314c0103d87a8000899198008009bab30ab0130a801375400444b30010018a6103d87a8000899192cc004c22c040062b3001308a010018984380998568098558080125eb82298103d87a800042a00513300400430af0100342a0046eb8c2a404004c2b0040050aa0121480232330010013756615402615602614e026ea800c896600200314c103d87a8000899192cc004cdc880a000c56600266e3c0500062610c02661580261540200497ae08a60103d87a8000429c0513300400430ae01003429c046eb8c2a004004c2ac040050a90145282146028998540080119802002000c4cc0100100050a301185380800985400800a14a0284b00a14602375c002853008c28c040050a101184f809baa00184980a1380284980c24c061260309301429004614202613c026ea80062a661380292014665787065637420496e6c696e65446174756d28747265655f726f6f7429203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d0016426c0460ec613a026ea8c1dcc27404dd5000c20c0509e01184f80801a13a020c25c04004c25804c25804c25804c25804004c24404dd51982e1bac30940100108d01233001308a013754611a026114026ea816a4444b30010018801c4c966002007153308d01491256e6f7420656e6f756768206b65792d76616c75657320746f206d617463682070726f6f667300168992cc004c1b8c23c04dd500146600200d9800802cdd7184780800cdd7184800800cdd61849809848009baa0024031309401004984a00801a00c8a9984700a4930657870656374204d5046496e73657274207b2070726f6f663a20696e736572745f70726f6f66207d203d2070726f6f660016423404612402006848008c2440400508f014c22804dd5030244530013002002984800801cdd5984800984880801cc244040066eb0c240040052222233229800984c00984c008014dd6184b808014c26004c26004c26004c260040066eb8c25c04005222298009bab309b010049bac309b01309c01309c01309c01309c01004984e008014dd7184d80801244446644646530013756614602003375661460261480200332330010010102259800800c52f5c11332259800acc004cdd79853809852009baa30a70130a80130a401375400400f130810132598009841009852009baa0018a40011375a615002614a026ea80050a201192cc004c20804c29004dd5000c530103d87a8000899198008009bab30a90130a601375400444b30010018a6103d87a8000899192cc004c224040062b30013088010018984280998558098548080125eb82298103d87a800042980513300400430ad010034298046eb8c29c04004c2a8040050a80121440232330010013756615002615202614a026ea8c2a004c2a404c29404dd5001912cc004006298103d87a8000899192cc004cdc8806800c56600266e3c0340062610802661540261500200497ae08a60103d87a800042940513300400430ac010034294046eb8c29804004c2a4040050a70145282142028998530080119802002000c4cc0100100050a101185280800985300800a14602488966002003089018992cc004c2a00400a264b300130800130a401375400313259800800c6600200313259800800c23c06264b300130ac010028992cc004c21004c2a004dd5000c4c96600200319800800c566002b30013375e6e98048dd3004c528c54cc2a00524011669735f76616c75655f6275726e74203f2046616c73650014a085380a2b3001598009919800800809112cc00400629422b30013371e6eb8c2bc0400405629462660040046160020028548090ad014528c54cc2a0052411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085380a2b3001598009844009854809baa01c8992cc0056600266e3cdd71857009855809baa006489200000000000000000000000000000000000000000000000000000000000000000008a518a9985480a4950696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085400a2b30015980099b8f3029001375c615c026156026ea800a29462a66152029215f636f6d707574655f747265655f68617368287472656529203d3d206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203f2046616c73650014a085400a2b30013375e6e98c138004dd31919800800806112cc004006297adef6c60899191980080099802002185980801912cc0040062661640200697adef6c608992cc004cdd799912cc004cdc8001000c530103d87980008acc004cdc7801000c530103d87a80008a6103d87b800042c004858008dca1bae30b00100437286eb8c2c00400530103d87980008998598080200144cc2cc04004cc00c00cc2d4040090ae01185980800a1620230b00100142b80514a315330a9014913c657874726163745f6b65795f76616c756573287472656529203d3d20736f727465645f73657269616c697365645f696e70757473203f2046616c73650014a085400a29410a801452821500230ad0130aa01375403913371e60aa6eb8c2b404c2a804dd5000cc004c154dd71856809855009baa0058054dd61856809855009baa01c407485380a29462a661500292011769735f747265655f75706461746564203f2046616c73650014a085380a29410a7014528214e0284a00a0b284a00c25006128030940142bc046158026152026ea800612402853008c20404c2a004dd5000c240050a901185500800a1500232330010010122259800800c52f5c11332259800acc004cdd79856809855009baa00200d8984380992cc004c22004c2a804dd5000c5200089bad30ae0130ab013754002854008c9660026110026154026ea8006298103d87a8000899198008009bab30af0130ac01375400444b30010018a6103d87a8000899192cc004c23c040062b3001308e010018984580998588098578080125eb82298103d87a800042b00513300400430b30100342b0046eb8c2b404004c2c0040050ae0121500232330010013756615c02615e026156026ea800c896600200314c103d87a8000899192cc004cdc8809800c56600266e3c04c00626114026616002615c0200497ae08a60103d87a800042ac0513300400430b20100342ac046eb8c2b004004c2bc040050ad014528214e028998560080119802002000c4cc0100100050a701185580800985600800a1520284680a0aa84680c2340611a0308d0142ac04615002614a026ea80062a66146029214865787065637420496e6c696e65446174756d28696e7075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642880460fa6148026ea8c1f8c29004dd5000c228050a501185300800a148024c004c8c8cc004004040896600200314bd7044cc8966002600a0051330a60100233004004001899802002000a1420230a50100130a601001428c0446466ebcc29004c28404dd51852009852809850809baa0020013051375c6146020094bd70901a0008101a000488c96600260fa6142026ea800626644b30010018cc00400626614c026e98cc29804cdd81ba937660026ea4dd99ba60023756614e020086614c026e98cc104dd5983f0021820198181bab307e30a401375460fc6148026ea8014cc29804dd480325eb812f5c10890141c10890184480c224061120285480a60026eacc1f0c28804dd5183e1851009baa003802404d02f1852809851009baa0018a9985000a4813465787065637420496e6c696e65446174756d28696e7075745f646174756d29203d20696e7075742e6f75747075742e646174756d0016427c0460f46142026ea8c1ecc28404dd5001209e375c614202614402614402004614002614002614002614002004613e02004184b008011849009baa3305d3758612a0200411c02210e02421c04843808dd7a601018000421804222329800800c01200680088896600200510018cc00400e611e0200533004001308e01002400c846009082010c00c00c02223259800980f000c4c9660020030038992cc0040060090048992cc004c11c00e26601600244b300100280444c96600200319800800c4c008c12800e0108062011008804402104b1824001208c802a0883758003004802208e3044001410860806ea80122b3001301d0018992cc00400600713259800800c01200900480244cc89660020030068992cc00400600f007803c01e26644b3001001804c4c96600200300a80544c966002609a0071330110012259800801403a264b30010018cc0040062600460a000700e404900e807403a01c8288c13800904c402d04a1bac001805402904d1825000a090375c00260920048250c11c0050451bae0013046002411c60880028210c100dd50024566002603600313259800800c00e264b30010018024012264b30013047003899805800912cc00400a01113259800800c6600200313002304a00380420188044022011008412c6090004823200a8220dd6000c0120088238c11000504218201baa004801207a40f481e8c0f8dd5001a03501a80d406903d181d181b9baa0068b206840d04464b300130163037375400313259800800c566002602e60706ea8006264b300100180f44c96600200301f80fc07e03f1332259800800c086264b3001001811408a045022899912cc00400604913259800800c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b30010018992cc00400605d13259800800c0be05f02f817c4cc89660020030318992cc004006264b3001001819c4c96600200303481a40d20691332259800800c0da264b300100181bc0de06f037899912cc00400607313259800800c0ea07503a81d44cc896600200303c8992cc00400607b03d81ec0f6264b3001305e0038cc00406a330010128cc004036204503e409d03e409d03e409903e416c6eb800505e182d800a0b2375c00260b400482d8c1600050561bae0013057002416060aa0028298dd7000982a00120aa3052001414060a400503281940ca0648298c14000504e1bae001304f0024140609a0028258c13400a05b02d816c0b504e1825800a092375c00260940048258c1200050461bae00130470024120608a0028218c11400a04b025812c0950461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0e4dd5000c075036407603b01d80ea07c323259800980c000c54cc0e12401274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c05c0062a66070921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981e981d1baa00240dc81b8c0e0dd50009808981c1baa301230383754607660706ea80062a6606c9201cd65787065637420536f6d65286465785f6f726465725f626f6f6b5f7265665f696e70757429203d0a20202020696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206465785f6f726465725f626f6f6b5f746f6b656e2c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640d4660120044602a64b300130163038375400314800226eb4c0f0c0e4dd5000a06c3259800980b181c1baa0018a6103d87a8000899198008009bab303d303a375400444b30010018a6103d87a8000899192cc004c0740062b3001301c0018980c9981f981e80125eb82298103d87a800040e9133004004304100340e86eb8c0ec004c0f800503c206c3300b3756602460706ea8c048c0e0dd5000801181a1baa0042223259800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009820801c66002009008803a016803a07c375c0028208c0f800503c181f0014012009004802207e303c00140e860706ea80122b300130150018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130410038cc004012011007402d00740f86eb8005041181f000a078303e002802401200900440fc607800281d0c0e0dd50024566002602600313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002608200719800802402200e805a00e81f0dd7000a082303e00140f0607c005004802401200881f8c0f000503a181c1baa004801206a40d481a8c0d8dd500188a4d153301d4911856616c696461746f722072657475726e65642066616c7365001365640701", - "hash": "598070a13f97093036bc75e11891e9931a98f2e2e4da8225bb6a1eaa" + "compiledCode": "59d54d010100229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0024888888888a60022a66006920148657870656374204d657373616765207b207661756c745f6571756974792c207072696365732c207574786f5f726566207d3a204d657373616765203d207369676e65645f6461746100168a99801a492e6578706563742061737365745f6c6973743a204d56616c7565203d20646573657269616c697365645f76616c756500168a99801a4949657870656374206f75747075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a494665787065637420696e7075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492a657870656374206163636f756e743a20557365724163636f756e74203d206f75747075745f646174756d00168a99801a494a657870656374206f75747075745f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a497b657870656374204465784163636f756e7442616c616e6365446174756d207b0a202020206163636f756e745f62616c616e63655f6d65726b6c655f726f6f743a20696e7075745f6d65726b6c655f726f6f742c0a20207d3a204465784163636f756e7442616c616e6365446174756d203d20747265655f726f6f7400168a99801a495b657870656374205472616e73666572496e74656e74207b20746f2c20616d6f756e745f6c323a207472616e73666572616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a496a657870656374204d6173746572496e74656e74207b206163636f756e743a2066726f6d2c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495f6578706563742043616e63656c5769746864726177616c496e74656e74207b20616d6f756e745f6c313a207769746864726177616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a4941657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d206465785f6163636f756e745f62616c616e63655f6f75747075747300168a99801a493f657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d206465785f6163636f756e745f62616c616e63655f696e7075747300168a99801a49e7657870656374205b6665655f6f75747075745d203d0a202020202020202020206f746865725f6f7574707574730a2020202020202020202020207c3e206c6973742e66696c746572280a202020202020202020202020202020206372656174655f6163636f756e745f6f7574707574735f66696c746572280a2020202020202020202020202020202020206665655f6163636f756e742c0a20202020202020202020202020202020202068796472615f6163636f756e745f7363726970745f686173682c0a20202020202020202020202020202020292c0a20202020202020202020202020202900168a99801a498b657870656374205769746864726177616c496e74656e74207b0a20202020616d6f756e745f6c313a207769746864726177616c5f616d6f756e745f7261772c0a202020207769746864726177616c5f6665655f6c313a207769746864726177616c5f6665655f7261772c0a20207d3a2048796472614163636f756e74496e74656e74203d20696e74656e7400168a99801a4964657870656374204d6173746572496e74656e74207b206163636f756e742c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a498c657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c696379280a202020202020696e707574732c0a20202020202068796472615f757365725f696e74656e745f616464726573732c0a20202020202068796472615f757365725f696e74656e745f7363726970745f686173682c0a202020202900168a99801a494e657870656374206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a494365787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f6f75747075742e646174756d00168a99801a499d657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d0a202020206f7574707574735f61745f77697468280a2020202020206f7574707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a494c65787065637420696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f646174756d00168a99801a499a657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d0a20202020696e707574735f61745f77697468280a202020202020696e707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a4929657870656374206163636f756e743a20557365724163636f756e74203d20696e7075745f646174756d00168a99801a499d657870656374205661756c744465706f736974496e74656e74446174756d4c32207b0a202020207661756c745f6f7261636c655f6e66742c0a202020206465706f7369746f722c0a202020206465706f7369745f616d6f756e742c0a20207d3a205661756c744465706f736974496e74656e74446174756d4c32203d20696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a493e657870656374206f75747075745f646174756d3a20557365724163636f756e74203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a493b65787065637420696e7075745f646174756d3a20557365724163636f756e74203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492e657870656374206f6c645f656e7472793a205368617265735265636f7264456e747279203d206f6c645f6461746100168a99801a492f657870656374206f6c645f656e7472793a205368617265735265636f7264456e747279203d2066726f6d5f6461746100168a99801a492f65787065637420536f6d652866726f6d5f6461746129203d2063626f722e646573657269616c6973652866726f6d2900168a99801a495b657870656374206f75747075745f6f7261636c655f646174756d3a205661756c744f7261636c65446174756d203d0a202020206f75747075745f696e6c696e655f646174756d287661756c745f6f7261636c655f6f75747075742900168a99801a495865787065637420696e7075745f6f7261636c655f646174756d3a205661756c744f7261636c65446174756d203d0a20202020696e7075745f696e6c696e655f646174756d287661756c745f6f7261636c655f696e7075742900168a99801a494d657870656374205b7661756c745f6f7261636c655f6f75747075745d203d206f7574707574735f776974685f706f6c696379286f7574707574732c207661756c745f6f7261636c655f6e66742900168a99801a494a657870656374205b7661756c745f6f7261636c655f696e7075745d203d20696e707574735f776974685f706f6c69637928696e707574732c207661756c745f6f7261636c655f6e66742900168a99801a49a6657870656374205661756c745769746864726177616c496e74656e74446174756d4c32207b0a202020207661756c745f6f7261636c655f6e66742c0a20202020776974686472617765722c0a202020207368617265735f746f5f72656465656d2c0a20207d3a205661756c745769746864726177616c496e74656e74446174756d4c32203d20696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495b657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c69637928696e707574732c20696e74656e745f616464726573732c20696e74656e745f706f6c6963795f69642900168a99801a4958657870656374206465785f6f726465725f626f6f6b5f696e7075745f646174756d3a204465784f72646572426f6f6b446174756d203d0a202020206465785f6f726465725f626f6f6b5f7265665f696e7075745f6461746100168a99801a493465787065637420536f6d65286f776e5f696e70757429203d20696e70757473207c3e2066696e645f696e70757428696e7075742900168a99801a491e72656465656d65723a2048796472614163636f756e7452656465656d657200168a99801a493d657870656374206f7065726174696f6e3a2050726f6365737348796472614163636f756e744f7468657252656465656d6572203d2072656465656d65720016488888888888888888888888888888888888889660033001302b37540633722911009b8f4881009b87480026e1d20029ba5480026e1d2004918179818000c8c0bcc0c0c0c00066e1d20069ba548009222222222229800981d005cc0e402e4646600200200444b30010018a5eb7bdb1822653001375c607200337566074003303e00248896600260220071598009808001c4006200a81d226607e66ec0dd48019ba60023300600600140e8303c00140e922232598009806000c4c9660020030038992cc0040060090048024012264b30013041003803401503e1bae0014104607c00281e0c0e8dd50024566002601600313259800800c00e264b300100180240120090048992cc004c10400e00d00540f86eb8005041181f000a078303a375400900240dc81b8c0e0dd5001c88c8cc00400400c896600200314c103d87a8000899192cc004cdc8802800c56600266e3c014006260186607c607800497ae08a60103d87a800040e5133004004304000340e46eb8c0e8004c0f400503b488c8cc00400400c896600200314c0103d87a80008992cc004c010006260166607a00297ae0899801801981f8012070303d00140ed22259800801452844ca600264b3001300d303a37540031375a6076607c6eacc0f8c0ecdd5000c5200040e0607a003375e607a607c00337560069112cc0040062b30013002006899802801a400114a081d2264b30013375e607a0029810140008acc004cc018010dd6981f18209bab303e001898019ba630420028a5040ed1598009980300224001130030078a5040ec81d8c10000503e0ca6002003004911981f0011981f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0f00066eacc0f400660820069112cc004c05000e2b300130130038998029808198211ba60024bd70000c4cc01530103d87a800000640f519800803c006446600e0046608866ec0dd48029ba6004001401c81e8607e00481ea29422942294103e244444453001304000798201820803c889660026024607e6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002609600519800801c66002003009804201c804201c80420908044022011008413060920028238c12400a00d006803401904a1823800a08a375c002608c0048238c11000504218201baa003800a07a9112cc004c048c0fcdd5001c4c9660020030028992cc004006264b300100180244c966002003159800982400146600200713259800980b800c4c9660020030078992cc0040062b3001304b0028992cc004c068006264b300100180544c966002003159800982700146600200300c805a022805a096805c02e01700b413c60980028250c120dd50014566002603200313259800800c02a264b3001001805c02e0171332259800800c036264b3001001807403a01d1332259800800c042264b3001001808c04602313259800982a801c04e0248290dd6800c0450551829000a0a0375a00260a200500e4148609e0028268dd68009827001402d04f1826000a0943048375400500941148228c118dd5000c021048402201100880420983049001411c608a6ea800a2b300130160018acc004c114dd5001401e00c823200c821104218219baa001802a016802a08a802c01600b0054124608c0028220c11800a007003801c00d0471822000a0843040375400700140f491111919912cc004c0540062646644b300100a899912cc004c06c006264b3001001810c4c966002609e0050048112098304d001412c60926ea80322b3001301a0018acc004c124dd5006400a04082522b300130180018acc004c124dd5006400a04082522b300130150018acc004c124dd5006400a04082520408231046208c411826464664530013756609c0053758609c609e609e005304f304f304f304f304f304f304f304f304f0019bae304e00198251baa00e9119809001119baf3051304e37540020053758609c00891111112cc004c09000e2b30013232330010010092259800800c528456600266ebc00cc150c160006294626600400460b20028291056180e9982a182a982b002a5eb8229462a660a09214e7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6f726465725f626f6f6b5f7363726970745f6861736829203f2046616c73650014a0827a2b300130230038acc004c8c8cc004004024896600200314a115980099baf003305430580018a51899801001182c800a0a44158603a660a860aa00a97ae08a518a9982824814b7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6163636f756e745f7363726970745f6861736829203f2046616c73650014a0827a2b3001301e0038992cc004c094c148dd5000c4c966002604a60a66ea80062b300132323300100100b2259800800c528456600266ebc00cc158c168006294626600400460b600282a1058180f9982b182b982a1baa0014bd704528c54cc149241417769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c206f776e5f7363726970745f6861736829203f2046616c73650014a0828a2a660a49215665787065637420536372697074286f776e5f7363726970745f6861736829203d0a202020202020202020206f776e5f696e7075742e6f75747075742e616464726573732e7061796d656e745f63726564656e7469616c0016414460ac60a66ea8c158c14cdd5181098299baa30563053375400302b41406600400201b13259800981298291baa0018acc00566002b30019800980d9bab302130533754604260a66ea8c158c14cdd5000d30101a0009119b87002001405d14a3153305149011369735f6e6f5f76616c7565203f2046616c73650014a0828229462b300159800981298291baa00d8a508a51414114a315330514911369735f6e6f5f646174756d203f2046616c73650014a082810504566002646600200201044b30010018a508acc004cdc79bae30580010078a51899801001182c800a0a4415914a315330514911f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a08282294105040ad05019801000806a09e413c8278609a609a609a609a609a00260926ea8cc01cdd61826000822982600098239baa0103046375401501e80f407a03c8260c120004c120c124004c110dd50034566002602600319800982398221baa006912cc00400629344c966002003149a264b3001337206eb8c11cc12c00cdd71823800c4cc010010cc128004c13000a2a6608c9201326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f726465720016411460940028240c12800504748888c8cc004004014896600200313304c337606ea4014dd300225eb7bdb1822653001375c609400337566096003304f00248896600266e4002400e2660a066ec0dd48049ba60080058acc004cdc7804801c4c9660026042609c6ea80062660a266ec0dd4805182918279baa001002880120989800804c022004803a2660a066ec0dd48019ba600233006006001412c8258609a002825a4444646600200200a44b300100189982619bb0375200a6ea00112f5bded8c113298009bae304a0019bad304b00198278012444b300133720012007133050337606ea4024dd4004002c56600266e3c02400e264b30013021304e3754003133051337606ea4028c148c13cdd50008014400904c4c004026011002401d133050337606ea400cdd400119803003000a096412c304d001412d259800800c528c528208c91192cc004c060c118dd5000c52f5bded8c1137566094608e6ea800504419806001000c888c8cc004004010896600200310048994c004dd71824800cdd69825000ccc00c00cc1380090041826000a094918241824982498249824800c8c120c124c124c124c124c124c124c124c1240064602a6608e60206608e6ea40052f5c06608e980103d87a80004bd704888ca6002003004801a00222259800801440063300100398270014cc010004c134009003209691919800800801112cc004006297ae08991991199119801001000912cc00400620071323304f374e6609e6ea4014cc13cc130004cc13cc1340052f5c06600600660a2004609e0028268dd598250019bae304700133003003304c002304a001412122372866e280080066e0120039b804801e44b300130183370c002900244cdc199b8e0023370600290022404113370c66e38008cdc1800a4008901020869b804800a45300100199b81371a0040030025c626e01200f9b80480064b30013370e6e3400520408800c54cc10d24138657870656374206279746561727261792e6c656e67746828726f6f7429203d3d20626c616b6532625f3235365f6469676573745f73697a650016410937029000488c8cc00400400c88cc00c004c00800a44464b3001301a0018992cc00400600713259800800c012009004899912cc00400600d13259800800c01e00f007803c4c96600260a4007009804209e375c0028290c13c00504d1bad001304e002802209e304c001412860906ea80122b300130190018992cc00400600713259800800c012009004899912cc00400600d13259800800c56600260a2005159800980f98261baa0018992cc00400601113259800800c026013009899912cc00400601713259800800c03201900c80644cc896600200300e8992cc00400601f00f807c03e264b3001305a003808c0410571bae001416860ae00282a8dd7000982b00120ae305400141486eb4004c14c00a01282a0c14400504f18269baa001803a094803a09c803c01e00f0074148609e0028268dd68009827001401104f1826000a09430483754009159800980b800c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e26644b3001001804c4c96600200300a805402a01513259800982a801c0320168290dd7000a0aa305200141406eb8004c1440090521827800a09a375a002609c005004413c60980028250c120dd50024009045208a4114608c6ea800e444b3001337120049000440063300100399b840024805266e2ccdc019b85002480512060001400c82224444646600200200a44b30010018802c4c966002003133004304e002006899802982700119801801800a098304e001412d22225980099b88002480c22600200515980099b87002480c2266008900111801000c56600266e20009203889980199b8e488103020408003370000490189180119bca4a2003124bded8c101400001012000411482290454dc3a41fc0722337600046ea00066e1d200a9baf4c10180004888888888888888888888888888888a6002603c03d22229800802400e0052229800801c006004802102148896600266ebcc1a4c198dd5181a18331baa00130190028992cc00400633001001899baf001004825204c825412a09504a41b064b30013036306637540031306a3067375400315330654913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016419060d260d460d460cc6ea8c1a4c1a8c198dd5000c52820c69112cc004cdd7983498331baa00130190028992cc00400633001001899baf001004825a04c825c12e09704b41b064b30013036306637540031306a30673754003153306549012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016419060d260d460d460cc6ea80062941063488ca60020030038012002222598008014400626530010049836801e6002005375c60d0003375660d200322232598009812800c5300103d87a80008981e998379ba60014bd7020d4329800800c00e00480088896600200510018994c00401260e800798008014dd71837800cdd69838000c888c966002608c00314c103d87a8000898221983b1ba80014bd7020e2337000040028149004183900120e0408c8020c1ac00906948896600266e2400d200089980b001000c4cc0580040090634888c8cc00400400c896600266e2400c0062910100899b8b3301500500133002002301400141952259800981b99b8600148012266e2d20fe033301000233706002900244cdc5a400066e2ccc048008004cc040008cdc19808800a400883124646600200200444b30010018a5eb7bdb182264660d266ec0c198004dd319198008009bab30680022259800800c52f5bded8c11323306c3376060d20026ea0c044dd698350009980180198370011836000a0d433003003306b0023069001419d300700791111194c0040060070024004444b300133712004900044c0052f5c112323298008034c05c0164600a660e2004003375a60dc0048030c1b00066002013008800a00e41a1222232330010010022233006480089660026016003130024bd70448c8ca600200d23006330700020019bad306d002401860d60033001008803cc05c00500620ce91114c00401200700291980200091801800a0124888888888888a60024444b300130460018802466002009003991900118090009983b19bb037520046ea00052f5bded8c122232598009818000c530103d87a8000898241983d1ba60014bd7020ea9800801401600922232598009826800c530103d87a8000898259983e9ba80014bd7020f033700002004818101020e294c00400697adef6c6091198060011bab304130733754608260e66ea80050234a60020034bd6f7b630488cc030008dd5982098399baa001408d22225980099b890044800a2660493001004801c00500c00144cc09000a60026046009003800a01841c522225980099b88004480122b300133710004900244cc0926002009003800a0184881200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f9761008998124c00401200748920000000000000000000000000000000000000000000000000000000000000000000403130013023002800d221200000000000000000000000000000000000000000000000000000000000000000004030838a2b300133712900200144cc091221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f97610098009811802400e00280622660493001002800d22120000000000000000000000000000000000000000000000000000000000000000000403130013023004801d2212000000000000000000000000000000000000000000000000000000000000000000040308389071488c8cc00400400c8966002608c0031337149110130000038acc004cdc4000a40011337149101012d0033002002301b00189980419b8400148050cdc599b803370a002900a240c00068389071488cc004888c8c8cdd8191ba73307a30770013307a30780014bd7019bb030760023076001307700198008034880060090039bad30760014019300100591000c00e0050014014446600490011192cc004cdc4800a40091598009824000c6600200900380148c05cdd4000a0308acc004c11c00633001004801ccdc00012407f2301737506040603c00280c22b30013370e004905f00c4c8cc0040048c060dd48009119803240044b3001301a00189801245008cc00401e00d33700002903fc8cc0100108c010cdc5001000a01441d919800802400e66e00009207f9180b9ba9001401c839907320e68acc004cdc3800a401919800802400e66e0000920ff02919802a40044b30013370e004906600c492f7b63001014000010120008992cc004cdc38012417c0519800803c01a66012012440032301a3374a004002805a330010078034cdc0001241fe0329800804401e66014014440030019180d99ba5003001403480d90762cc004cdc4a41002800513370066e0000920ff134803a266e0000920f10141d483a9018456600266e1c00520088acc004cdc38012417c0519800802400e6600c00c4400323017374e002804233001004801ccdc0001241fe0329800802c0126600e00e440030019180c1ba7001402880c10734566002602a00315980099b87002483f80a2646466002002460326e9800488cc01d2002259800980d800c4c0092f5bded8c1123232980080348c018cc200040080066eb4c1f40090061919bb0308001001308001308101001375860f600330010098044c09c00500520ee33006006220028cc00401200733700004905f8148c8ca60020030039180d1ba60014004444b300133712004900044c0052f5bded8c112323298008034c09c0164600a6610202004003375a60fc0048030c8cdd81840808009840809841008009bac307c0019800805402600280290781980380391001203041cd124bded8c010140000101200041cc839907320e633706002902048c8cc004004008896600200314bd6f7b63044ca60026eb8c1cc0066eacc1d00066600600660f00049112cc00400a2a660ea92124657870656374205061697228702c205b5f2c202e2e5d206173207829203d20696e6e657200168cc004006007323200432330010010042259800800c5268992cc0040062b30013004375a60f660fc005149a2a660f292011f76616c756520646f65736e2774207361746973667920707265646963617465001641e1133225980099b90375c60f80046eb8c1f00062b30013006375a60fa0051330050053307f0013081010038a9983da491f76616c756520646f65736e2774207361746973667920707265646963617465001641e9153307b491276b65797320696e207061697273206172656e277420696e20617363656e64696e67206f72646572001641e860fc00460fc00283e0c1f800507b14c004c12800694294507548894cc1e12401234475706c696361746520706f6c69637920696e20746865206173736574206c6973742e0016404c83c060ec00283a12222222298009114c004cc0c800c00a97adef6c60911192cc004c144c1f8dd5000c4ca6002007375c610602003375c61060261080200300440406eb0c20804c1fcdd5000c54cc1f524121546f6b656e2068617368206e6f7420666f756e6420696e20746f6b656e206d6170001641f0646600200200a44b30010018a60103d87a80008992cc004cdc78031bae308001001898289984180984080800a5eb82266006006610a0200483f0c20c04005081012062911112cc004cdc4802a400d13302d9800802c012005001402800713302d00398009815802c012005001402883d24444b3001337100089004456600266e2000920088998164c004012007002800a01048812085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b1008998164c004012007489200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040253001302a002800d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483ca2b300133712900400144cc0b12212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b10098009815002400e6054005001402113302c980080140069101200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040253001302a004801d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483c90794888c9660020071323233223300b0023371491101280059800800c4cdc52441035b5d2900006899b8a489035b5f20009800800ccdc52441025d2900006914c00402a00530070014029229800805400a00280510232102025980099b880014803a266e0120f2010018acc004cdc4000a41000513370066e01208014001480362c83d907b1bac307e002375a60f80026466ec0dd4183e0009ba7307d001375400713259800800c4cdc52441027b7d00003899b8a489037b5f20003232330010010032259800800c400e264b30010018994c00402a610202003337149101023a200098008054c2080400600a805100a18420080144ca600201530810100199b8a489023a200098008054c20804006600e66008008004805100a18420080121040230840100142040466e29220102207d0000341f86eac00e264b3001001899b8a489025b5d00003899b8a489035b5f20009800800ccdc52441015d00003914c00401e0053004001401d229800803c00a002803902020fc3758007133007375a0060051323371491102682700329800800cc09cdc68014cdc52450127000044004444b300133710004900044006264664530010069816002ccdc599b800025980099b88002480522903045206e42000466e2ccdc0000acc004cdc4000a402914818229037210002004401866e0c00520203370c002901019b8e00400241f46eb800d081011b8a4881022c20009801001244445300122222330329800802c012605600680ca60026605e00a60560079800a400148102002b8c66002902052040800ae319800a41000348102002b8c66002906000d2040800ae30911112cc004cdc4802a401d1330379800802c01e007002800a01c00489981b8024c004c0c401600f003801400500e210802488888c96600330013370e0026eb4c21804c20c04dd5001528528a10002899819cc00401a00b302c00440686644b3001337100069008456600266e20009201089981acc00400e00b002800a01648920b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0089981acc00400e00b4892085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302f002800d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403084100a2b300133712900800144cc0d522120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0098009817801c016605e005001402d1330359800801400691012085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302f003802d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a441200000000000000000000000000000000000000000000000000000000000000000004030841009082011bad3086013083013754004660666eb8c144c20c04dd50011bae3050308301375400515330810149120657870656374206272616e636820213d206e65696768626f722e6e6962626c6500164200046605e00a605600730020029192cc004c144006298103d87a80008992cc006600260a46eb4c2000400694294507d4530103d87a8000898281984100983f800a5eb8107d4c00488006444b3001337120029000452f7b63010140000101200089980119b8e0053370200800266e0400400d07f48896600266e2400520008a5ef6c601014000010120008998014c004cdc0802000c00e00ab8c19b8100100341fd001400c83e0dc6800a44446645300122225980099b8f330060030010048cc00400e0050014015153308501490129657870656374206578636c7564696e67286b65792c2070726f6f6629203d3d2073656c662e726f6f740016421005222225980099b8f9800802400a006803001633001004800c00d006454cc2180524013465787065637420696e636c7564696e67286b65792c206f6c645f76616c75652c2070726f6f6629203d3d2073656c662e726f6f74001642140522225980099b8f9800801c00a002802801226600c00600315330850149013065787065637420696e636c7564696e67286b65792c2076616c75652c2070726f6f6629203d3d2073656c662e726f6f740016421004911192cc00412a265300122259800982e9845009baa0038992cc00400600513259800800c4c9660020030048992cc00400600b13259800984a00801c4cc896600260c800313259800800c026264b30010018acc004c2600400a26530010018014015001111192cc004c1a8006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c4c9660026144020071330440012259800801402a26464b300100180c40620311332259800800c6600202100189802985400803202080d406a03501a42a4046eb4004c2880400a030853808c28004004c28c040090a101405109f011bab001809c04e026851008c27c0400509d011bae001309e01002427c0461380200284d008c26004dd5001c56600260d200313259800800c03e264b30010018084042021010899912cc00400602513259800800c04e027013809c4cc89660020030158992cc00400602d01680b405a264b300130a501003805c05d0a2011bae001429404614402002850008dd7000985080801214402309f010014274046eb8004c2780400909f01184e00800a13402309801375400700e42540484a808c25804dd5001402909501402a01500a8052132023096010014250046124026ea801a2b300130630018992cc00400601313259800800c02a01513259800984c80801c4cc0ec00489660020050078992cc0040063300100189801184e00801c039011403a01d00e807213a02309a0100242600500b4258046eb000601500a426404612c0200284a008c24804dd5003402108f01211e021330360012259800801402626464b3001001805402a01500a899912cc00400601900c8992cc00400601b13259800800c03a01d00e80744cc89660020030108992cc004006023011808c046264b300130a00100389805985000806404909d011bae001428004613a0200284d808dd7000984e00801213a02309a010014260046eb000601900c426c046eb8004c2500400909901184900800984a80801212602308f0137540090064244046eac00600b005802a12802309101001423c04612202005003801c00e006849008c23c0400508d011845809baa003800a110029843809baa04b8cc004896600200314bd7044cc23004c22404c23404004cc008008c2380400508b014896600260b66112026ea80062646611a0266ec0c23804004c23804c23c040052f5bded8c0611c026114026ea80062646600200264660020026eacc23c04c24004c23004dd5001912cc004006297ae08998478098468098480080099801001184880800a11c022259800800c52f5bded8c1132332233002002330070070012259800800c400e2661220261240200266004004612602002848008c24004008cc008008c2400400508d01210e029194c0040060054bd7020022225980080144006330010039848008014cc23804c23c04008005003211a029119846009ba90010029111919800800802112cc00400620091330033090010013300200230910100142380522259800982e9845009baa0038992cc00400600513259800800c00e007003801c4c966002612402007005802211e02375c002849008c23c0400508d011845809baa003800a110029843809baa04b912cc0040062900044c0d8cc008008c2380400508b01488c8cc00400400c896600200314bd6f7b63044c8ca60026eacc2380400a660080086124020072229800800c022b300159800983200244c19000e294108e014522010089b943371400800684700a00481090441bae308c01001308f0100142340523259800982e1844809baa0018992cc00400610a0313233032001225980080144c96600266e3cdd99ba60010078800c54cc234052401306578706563742063626f722e73657269616c6973652876616c756529203d3d2073657269616c697365645f76616c75650016423004602e0071323259800800c228061140308a0184500c4cc896600200308c0189981c1bab001225980080144c01cc2600402226464b300100184800c240061200309001899912cc004006124030920184900c4c8c018c2740401cdd6800c2480509d011bae001309601002426c04612802002612e0200484a80a1180308c0184600a12e02375c00261200200484a808c23804004c2440400908f011bab00184280c2140610a02848008c23404c22804dd5000c54cc2200524014465787065637420536f6d6528646573657269616c697365645f76616c756529203d2063626f722e646573657269616c6973652873657269616c697365645f76616c7565290016421c04601200291111111114c004c02802a601201322259800801466002007300b001a5eb8100344c96600200313259800801c400633001005998061806801800d2f5c08029098011bae3099010038cc0040126134020033300b00233046375c6132020066eb8c26404005004212e02309901002425805300300348888c8c8c8cc896600260da01b13232332298009851809851808014dd61851008014c28c04c28c040066eb8c28804005222298009bab30a6010049bac30a60130a70130a70130a70130a7010049853809853808014c29804009222232329800985680800cdd7185600800cdd618560080724453001375c615e02007375c615e026160026160020073232330010010032259800800c52f5c11332259800acc004cdd7985a009858809baa30b40130b50130b101375400400b1323300100132330010013756616c02616e026166026ea8c2d804c2dc04c2cc04dd5002112cc004006297ae0899199119198008009bab30b8010042259800800c400e26466178026e9ccc2f004dd48029985e00985c808009985e00985d00800a5eb80cc00c00cc2f804008c2f0040050ba011bae30b4010013300300330b90100230b70100142d40444b30010018a508acc004cdc79bae30b6013758616c0200201314a313300200230b70100142c00485a00a29410ae0144cc2cc04008cc010010006266008008002857008c2c804004c2cc040050b001182f8014c2bc04c2b004dd5037cdd7185780803cc2bc0401522222259800802427806264b300130b7010058992cc0040062b300130850130b301375400313259800800c28806264b30010018992cc0040061480313259800985e00801466002007159800800c566002611402616e026ea8006264b300100185380c4c9660020030a801899912cc0040061540313259800800c2ac06264b300130c201003899832002112cc00400a2660cc00644b30010028cc004c12c01664646600200203244b30010018a5eb841018000810180008101800044cc8966002600a0051330c901374e66192020046eb0c32804004cc32404c32804c32c04004cc32404c32804c32c04c32c040052f5c1159800acc004cdd79865009863809baa30ca0130cb0130c701375400402d1323300100132330010013756619802619a026192026ea8c33004c33404c32404dd5002112cc004006297ae0899199119198008009bab30ce010042259800800c400e264661a4026e9ccc34804dd480299869009867808009986900986800800a5eb80cc00c00cc35004008c348040050d0011bae30ca010013300300330cf0100230cd01001432c0444b30010018a508acc004cdc79bae30cc01375861980200203314a313300200230cd0100143180486500a29410c40144cc32404c32804004cc32404dd399864808011bac30ca0130cb01001330c90130ca0130cb0130cb010014bd7044cc32404c32804004cc32404c32804c32c04004cc32404dd399864808011bac30ca0130cb0130cb010014bd7021880243100461900200266004004619202002863008cc17403405a64646600200204844b30010018a5eb841018000810180008101800044cc8966002600a0051330c901374e66192020046eb0c32804004cc32404c32804c32c04004cc32404c32804c32c04c32c040052f5c1159800acc004cdd79865009863809baa0020168991980080099198008009bab30cc0130cd0130c901375400844b30010018a5eb82264664464660020026eacc338040108966002003100389919869009ba7330d201375200a661a402619e02002661a40261a00200297ae03300300330d40100230d2010014340046eb8c32804004cc00c00cc33c04008c334040050cb01112cc00400629422b30013371e6eb8c33004dd618660080080cc528c4cc008008c334040050c6012194028a504310051330c90130ca01001330c901374e66192020046eb0c32804c32c04004cc32404c32804c32c04c32c040052f5c11330c90130ca01001330c90130ca0130cb01001330c901374e66192020046eb0c32804c32c04c32c040052f5c08620090c40118640080099801001186480800a18c023305c00d016488a6002660bc609c01660b400730c9010029bac30c801002986480800cdd6186400800a4444530013758619a020053758619a02619c02005309b0130353758619a02619c020093758619a020089111192cc00400a17e0313259800986a00801c56600200d0c1018992cc004c3540401e264b3001598008034528c54cc340052401176e6f5f6f746865725f696e70757473203f2046616c73650014a086780a2b3001598008024528c54cc3400524011e69735f7769746864726177616c5f6665655f70616964203f2046616c73650014a086780a2b300159800992cc004006330010018992cc004006330010018cc004dd7186b80986a009baa0029bae30d70130d4013754003376603f30d301375404a9111192cc004c2ac0400a266e3e60020030039bb3374c029375861b80261b2026ea80a9056002456600261540200513232332259800acc0066002660ec6098002031374c6098005223370e00400285080a29462a661b60292011a69735f62616c616e63655f75706461746564203f2046616c73650014a086d00a2b30013371f3001005803cdd6187000987080801c00600482c802229462a661b6029211e69735f6e65775f62616c616e63655f636f7272656374203f2046616c73650014a086d00a29410da011bae30de01001375c61bc0200461bc0200261b2026ea80aa29410d60121ac0230800100443340504743340619a030cd0186680a1b20232598009851809869809baa0018986b80986a009baa0018a9986900a4812c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001643440461ac0261ae0261ae0261a6026ea800e196028232196030cb0186580c32c050d801192cc004c28804c34804dd5000c4c35804c34c04dd5000c54cc3440524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001643400461aa0261ac0261ac0261a4026ea8c35404c35804c34804dd5001c528c54cc3400524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a086780a2b30015980099baf374c613402660d6660d665300100180652f5bded8c080088896600200510018cc00400e61b202005329800800c00a6eacc36404c36804c35804dd5186c80986d00986b009baa30d9010034004444b30010028800c4c8cc8a600200d30df010059919800800802912cc0040062661be0266ec0dd48021ba60034bd6f7b63044ca60026eb8c374040066eacc3780400661c4020049112cc004cdc8004001c4cc38c04cdd81ba9008374c00e00b15980099b8f0080038992cc004c2d004c38404dd5000c4cc39004cdd81ba900930e50130e20137540020051002437c0464b300159800800c528c52821c6028a60103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011833994c0040060114bd6f7b6302002222598008014400633001003986c808014ca60020030029bab30d90130da0130d601375461b202006800888966002005100189919914c00401a61be0200b32330010010052259800800c4cc37c04cdd81ba9004374c00697adef6c608994c004dd7186e80800cdd5986f00800cc388040092225980099b900080038998718099bb037520106e9801c0162b30013371e01000713259800985a009870809baa0018998720099bb0375201261ca0261c4026ea800400a200486f808c966002b30010018a518a50438c0514c103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011833994c0040060154bd6f7b6302002222598008014400633001003986c808014ca60020030029bab30d90130da0130d601375461b202006800888966002005100189919914c00401a61be0200b32330010010052259800800c4cc37c04cdd81ba9004374c00697adef6c608994c004dd7186e80800cdd5986f00800cc388040092225980099b900080038998718099bb037520106e9801c0162b30013371e01000713259800985a009870809baa0018998720099bb0375201261ca0261c4026ea800400a200486f808c966002b30010018a518a50438c0514c103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011ba60018a518a9986800a4812569735f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a086780a2b300159800cc0040be6e98c19ccc1acc26804dd59850009869009baa30a00130d2013754040003223370e00400284b00a29462a661a0029211769735f746f6b656e735f6275726e74203f2046616c73650014a086780a2b3001323300100102f2259800800c528456600266e3cdd7186b808008194528c4cc008008c360040050d10121aa028a518a9986800a492669735f68796472615f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a086780a29410cf014528219e028a50433c0514a086780a29410cf01184c80998208060124308050d20118698080321a20286000a1a20230d201002434004b30010038a518acc004c3480400e264b300100185f00c4c96600261a80200519800984c0099820007011cdd3184c009bab309e0130d0013754003223370e00400284a00a17e02868808c348040050d001191919800800802912cc004006297ae0899912cc004c01400a2661aa020046600800800313300400400143400461a80200261aa02002869008cc1a00a008a2a6619802920118756e6578706563746564206f74686572206f7574707574730014a08678090cf010899192cc004006164030b20185900c2c80626644b300100185a00c4cc1b0dd5800912cc00400a2600e6198020111323259800800c2e006170030b80185c00c4cc89660020030ba0185d00c2e806264600c61a20200e6eb400617402868808dd7000986500801219e0230c80100130cb010024324050b40185a00c2d0050cb011bae00130c401002432404618402002618a0200486180a26464b300100185800c2c006160030b001899912cc0040061640313306a375600244b30010028980398650080444c8c9660020030b60185b00c2d80616c031332259800800c2e006170030b80189918031867808039bad00185c00a19e02375c002619002004866808c31804004c324040090c70142c806164030b2014324046eb8004c308040090c70118600080098618080121820285600a17e0237560030ab0185580c2ac050c201185f80800a17a023756002617c020050a80185400c2a0050bf01185e00800a1740230b80137540030a60142d4050a60185300c2980614c0285e80a14a0283ba14a0285c808c2e8040050b801185d00801428c06146030a30185180a1760230b80100142d8046168026ea80061420285880a142030a10185080c284050b901192cc004c20c04c2cc04dd5000c4c2dc04c2d004dd5000c54cc2c8052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642c404616c02616e02616e026166026ea8c2d804c2dc04c2cc04dd5000c27c050b401185a808022166020c2b004c2b004c2b004004c2ac0400830a101001309d013754660b66eb0c2800400426404c28004004c26c04dd5032456600260d801b13232332298009851809851808014dd61851008014c28c04c28c04c28c04c28c040066eb8c28804005222298009bab30a6010049bac30a60130a70130a70130a70130a7010049853808014dd71853008012444465300130ac010019bae30ab010019bac30ab0100d488a60026eb8c2b80400e6eb8c2b804c2bc04c2bc0400e64646600200200644b30010018a5eb8226644b30015980099baf30b30130b00137546166026168026160026ea80080162646600200264660020026eacc2d404c2d804c2c804dd5185a80985b009859009baa0042259800800c52f5c1132332232330010013756616e0200844b30010018801c4c8cc2ec04dd39985d809ba9005330bb0130b801001330bb0130b9010014bd7019801801985e80801185d80800a17202375c61660200266006006617002004616c0200285a008896600200314a115980099b8f375c616a026eb0c2d4040040262946266004004616c020028578090b3014528215a028998590080119802002000c4cc0100100050ad01185880800985900800a15e02305e0029857009855809baa06e985700803244444b300100384e00c4c966002616a0200913259800800c5660026106026162026ea8006264b300100185000c4c96600200313259800800c28806264b300130ba010028cc00400e2b30010018acc004c21c04c2d404dd5000c4c9660020030a9018992cc0040061540313259800985e80801c4cc17c00489660020051332298009860808014dd61860008014c304040066eb0c30004005222298009bac30c40100298490098161bac30c40130c50100498498098161bac30c40130c5010029bac30c40100448889660020030b5018992cc004c3280400a2b300100585b80c4c96600261960200d13259800acc00401a29462a6618c02921176e6f5f6f746865725f696e70757473203f2046616c73650014a086280a2b300159800802c528c54cc318052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a086280a2b30015980099912cc004006330010018992cc004006330010018cc004dd71867009865809baa0029bae30ce0130cb013754003376603130ca01375403a9111192cc004c27c0400a266e3e60020030039bb3374c011375861a60261a0026ea808904b002456600261420200513232332259800cc004cc1b4c10c004c1a40326e98c10c00a4466e1c0080050980144cdc7cc00401600f375861ae0261b00200700180120a00088a504344046eb8c35404004dd7186a80801186a808009868009baa0228a50433404866808c1dc0110c40140f90c40186200c3100618802868008c9660026134026194026ea80062619c026196026ea80062a66192029212c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016432004619a02619c02619c026194026ea80121840281ea184030c20186100c308050cf011828808192cc004c26004c32004dd5000c4c33004c32404dd5000c54cc31c052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d00164318046196026198026198026190026ea8c32c04c33004c32004dd5001c528c54cc3180524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a086280a2b30015980099baf374c612002660c260ac01060ba60ae0146e9800629462a6618c029212c69735f63616e63656c5f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a086280a2b300159800cc0040966e98cc184c174c24004dd5984b009864009baa30960130c8013754030003223370e00400284600a29462a6618c029211d69735f6d696e745f76616c75655f636f7272656374203f2046616c73650014a086280a2b300132330010010252259800800c528456600266e3cdd71866808008144528c4cc008008c338040050c7012196028a518a9986300a492d69735f68796472615f63616e63656c5f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a086280a29410c5014528218a028a5043140514a086280a29410c5011981b982800780dc2e0050c801186480802a18e0285b00a18e0230c801001431804194c00404a97ae10101800081018000810180004896600260060051330c001374e66180020046eb0c30404004cc30004c23004004cc30004c22c040052f5c1159800acc004cdd7986080985f009baa308c0130be01375400401f1323300100130703756611a02617e026ea8c23404c2fc04dd5001912cc00400629422b30013371e6eb8c30c04dd618618080080d4528c4cc008008c310040050bd012182028a5042ec051330c00130c101001330c001374e66180020046eb0c23004004cc30004c22c040052f5c11330c00130c101001330c001308c01001330c001374e66180020046eb0c22c040052f5c085d8090bb0120603305600801032323300100101d2259800800c52f5c21018000810180008101800044cc8966002600a0051330c201374e66184020046eb0c30c04004cc30804c30c04c31004004cc30804c30c04c31004c310040052f5c1159800acc004cdd79861809860009baa0020118991980080099198008009bab30c50130c60130c201375400844b30010018a5eb82264664464660020026eacc31c040108966002003100389919865809ba7330cb01375200a6619602619002002661960261920200297ae03300300330cd0100230cb010014324046eb8c30c04004cc00c00cc32004008c318040050c401112cc00400629422b30013371e6eb8c31404dd618628080080e4528c4cc008008c318040050bf012186028a5042f4051330c20130c301001330c201374e66184020046eb0c30c04c31004004cc30804c30c04c31004c310040052f5c11330c20130c301001330c20130c30130c401001330c201374e66184020046eb0c30c04c31004c310040052f5c085e8090bd0118608080099801001186100800a17e0233055008010899192cc00400615e030af0185780c2bc0626644b300100185880c4cc194dd5800912cc00400a2600e618a020111323259800800c2d40616a030b50185a80c4cc89660020030b70185b80c2dc06264600c61940200e6eb400616e02865008dd700098618080121900230c10100130c4010024308050b10185880c2c4050c4011bae00130bd01002430804617602002617c0200485e00a1560285d008dd5800c2a806154030aa0142f40461740200285c008c2d804dd5000c2a0050b30142a006150030a80185400a1760285180a0ea85180a16e0230b80100142d8046170020050a10185080c284061420285c808c2d8040050b4011859009baa00184f80a15e0284f80c27c0613e0309f0142dc0464b300130810130b1013754003130b50130b201375400315330b0014913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642bc04616802616a02616a026162026ea8c2d004c2d404c2c404dd5000c274050b201185980801a162020c2ac04c2ac04c2ac0400830a101001309d013754660b66eb0c2800400426404c28004004c26c04dd5032456600260d401b132323298009bae30a10130a20130a20130a20130a20130a20130a20130a20130a20130a201001985080984f009baa06198510080124446644b30015980098209853009853808014528c54cc284052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085000a2b3001598009820985300985380800c528c54cc284052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085000a2b30015980099baf374c60d66530010019bac30a701003a5eb7bdb1810011112cc00400a200319800801cc2a80400a6530010018014dd59855009855809853809baa30aa0130ab0130a7013754615402006800888966002005100189919914c00401a61600200b32330010010052259800800c4cc2c004cdd81ba9004374c00697adef6c608994c004dd7185700800cdd5985780800cc2cc040092225980099b9000800389985a0099bb037520106e9801c0162b30013371e010007132598009842809859009baa00189985a8099bb03752012616c026166026ea800400a2004858008c966002b30010018a518a5042d00514c0103d87a800089841809985a809ba60014bd70216002329800800c022006800888966002005100189919914c00401a61780200b32330010010052259800800c4cc2f004cdd81ba9004375000697adef6c608994c004dd7185d00800cdd6985d80800cc2fc040092225980099b900080038998600099bb037520106ea001c0162b30013371e01000713259800984880985f009baa0018998608099bb03752012618402617e026ea800400a200485e008c96600261220200314c0103d87a8000898478099860809ba80014bd702178023370000e0051330c001337606ea400cdd400119803003000a1760242ec0430bd0100142ec048030dd7185a808009bad30b60100130b80100242d8051330b401337606ea400cdd300119803003000a15e0242bc0430b10100142bc048030dd71854808009bab30aa0100130ac0100242a80480190a7011ba6306b329800800cdd618538080152f5bded8c080088896600200510018cc00400e615402005329800800c00a6eacc2a804c2ac04c29c04dd5185500801a002222598008014400626466453001006985800802cc8cc00400401489660020031330b001337606ea4010dd3001a5eb7bdb1822653001375c615c020033756615e0200330b30100248896600266e4002000e2661680266ec0dd48041ba60070058acc004cdc7804001c4c966002610a026164026ea800626616a0266ec0dd4804985b009859809baa00100288012160023259800acc004006294629410b4014530103d87a800089841809985a809ba60014bd70216002329800800c022006800888966002005100189919914c00401a61780200b32330010010052259800800c4cc2f004cdd81ba9004375000697adef6c608994c004dd7185d00800cdd6985d80800cc2fc040092225980099b900080038998600099bb037520106ea001c0162b30013371e01000713259800984880985f009baa0018998608099bb03752012618402617e026ea800400a200485e008c96600261220200314c0103d87a8000898478099860809ba80014bd702178023370000e0051330c001337606ea400cdd400119803003000a1760242ec0430bd0100142ec048030dd7185a808009bad30b60100130b80100242d8051330b401337606ea400cdd300119803003000a15e0242bc0430b10100142bc048030dd71854808009bab30aa0100130ac0100242a80480190a7014528c54cc2840524011e69735f6163636f756e745f76616c75655f657175616c203f2046616c73650014a085000a2b3001323233001001375861500261520261520261520261520261520261520200a44b30010018a508acc004cdc79bae30a9010010038a51899801001185500800a14602429c046eb8c2980401a29462a661420292012d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085000a29410a00145282140028a504280046466446600400400244b30010018a5eb8410180008101800044cc8966002600a0051330a801374e66150020046eb0c2a404004cc2a004c2a404c2a8040052f5c11330a80130a901001330a801374e66150020046eb0c2a404c2a8040052f5c0851808c29c04004cc008008c2a0040050a5011bac30a5010073303c002003323322330020020012259800800c52f5c210180008101800044cc8966002600a0051330a801374e66150020046eb0c2a404004cc2a004c2a404c2a8040052f5c11330a80130a901001330a801374e66150020046eb0c2a404c2a8040052f5c0851808c29c04004cc008008c2a0040050a5011bac30a5010023303b002003184e809baa3305b3758614002002132026140020026136026ea81922b3001306700d8991919914c004c28c04c28c0400a6eb0c2880400a614602614602614602614602614602614602614602614602003375c61440200291114c004dd59853008024dd61853009853809853809853809853808024dd71853008014dd71853009853808014dd618530080424444464b300100184a80c4c966002615c0200513259800800c56600260f86154026ea8006264b300100184f80c4c96600200313259800800c28406264b300130b3010028cc00400e2b30010018acc004c1f8c2b804dd5000c4c9660020030a4018992cc004006264b300100185300c4c9660020030a7018992cc004c2e00400e3300100489982d000912cc00400a2664466446644b300159800982d1ba73233001001375861800261820200a44b30010018a5eb8226644b30013375e6186026180026ea8c30c04c31004c30004dd5001002c4cc30804008cc01001000626600800800285e808c30404004c308040050bf014528c54cc2e80524011f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a085c80a2b300159800982d1ba73233001001375861800261820200844b30010018a5eb8226644b30013375e6186026180026ea8008016266184020046600800800313300400400142f40461820200261840200285f80a29462a6617402921206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a085c80a2b300159800acc004cdd79ba630840133055304b3758617e0200c60a260946eb0c2fc04014dd300144cdd79ba6002374c608a01314a085c80a29462a66174029211a69735f76616c7565735f6d61746368696e67203f2046616c73650014a085c80a2b300159800991980080080c912cc00400629422b30013371e6eb8c30404004072294626600400461840200285d8090bf014528c54cc2e8052412d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085c80a2b3001980080ccdd318289842009bab308a0130bc0137546114026178026ea804e4466e1c008005080014528c54cc2e80524011d69735f696e74656e745f746f6b656e5f6275726e74203f2046616c73650014a085c80a29410b90145282172028a5042e40514a085c808c20804cc14cc120dd6185e80800982798249bac30bd01002306d01430bc0100230bc01001332232330010010122259800800c52f5c3018000810180008101800044cc8966002600c0051330be01374e6617c020046eb0c2fc04004cc2f804c2fc04c30004004cc2f804c2fc04c30004c300040052f5c1159800980280144cc2f804c2fc04004cc2f804dd39985f008011bac30bf0130c001001330be0130bf0130c00130c0010014bd7044cc2f804c2fc04004cc2f804c2fc04c30004004cc2f804dd39985f008011bac30bf0130c00130c0010014bd7021720242e404617a0200266004004617c0200285d808cc144028040cc144018040cc88c8cc004004064896600200314bd7081018000810180008101800044cc8966002600c0051330be01374e6617c020046eb0c2fc04004cc2f804c2fc04c30004004cc2f804c2fc04c30004c300040052f5c1159800980280144cc2f804c2fc04004cc2f804dd39985f008011bac30bf0130c001001330be0130bf0130c00130c0010014bd7044cc2f804c2fc04004cc2f804c2fc04c30004004cc2f804dd39985f008011bac30bf0130c00130c0010014bd7021720242e404617a0200266004004617c0200285d808cc140028040cc14001804226464b300100185600c2b006158030ac01899912cc00400615c03133060375600244b30010028980398600080444c8c9660020030b20185900c2c806164031332259800800c2d006168030b40189918031862808039bad00185a00a18a02375c002617c02004861808c2f004004c2fc040090bd0142b80615c030ae0142fc046eb8004c2e0040090bd01185b00800985c80801216e0285400a0e685400a16a0237560030a70185380c29c050b801185a80800a1660230b50100285280c2940614a030a50142d804616602002858808c2bc04dd5000c28c050ac01428c06146030a30185180a1680285100a0dc85100a1600230b10100142bc046162020050a00185000c2800614002859008c2bc040050ad011855809baa00184f00a1500284f00c2780613c0309e0142c00464b3001307a30aa013754003130ae0130ab01375400315330a90149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642a004615a02615c02615c026154026ea8c2b404c2b804c2a804dd5000c258050ab01185600800a154023232330010010032259800800c52f5c11332259800acc004cdd79858009856809baa30b00130b10130ad01375400400b1323300100132330010013756616402616602615e026ea8c2c804c2cc04c2bc04dd5002112cc004006297ae0899199119198008009bab30b4010042259800800c400e26466170026e9ccc2e004dd48029985c00985a808009985c00985b00800a5eb80cc00c00cc2e804008c2e0040050b6011bae30b0010013300300330b50100230b30100142c40444b30010018a508acc004cdc79bae30b201375861640200201514a313300200230b30100142b00485800a29410aa0144cc2bc04008cc010010006266008008002855008c2b804004c2bc040050ac01182d8018614202002613a026ea8cc16cdd618500080084c80985000800984d809baa0648acc004c0e803633001309b013754613c026136026ea817a4444b30010018801c4c966002007153309e0149012a6e6f7420656e6f756768206b65792d76616c756520706169727320746f206d617463682070726f6f667300168992cc004c1c0c28004dd500146600200d9800802cdd7185000800cdd7185080800cdd61852009850809baa002407130a501004985280801a00c8a9984f80a4930657870656374204d504644656c657465207b2070726f6f663a2064656c6574655f70726f6f66207d203d2070726f6f660016427804614602006850808c288040050a0014c26c04dd5032244530013002002985080801cdd5985080985100801cc2880400522223232329800985480985480985480985480800cc2a0040066eb8c2a00400922298009bae30ab0130ac0130ac01003982d9bae30ab0100399198008009bac30ac0100c2259800800c52f5c11332259800acc004cdd79857809856009baa30af0130b00130ac01375400400d1307d3259800983f1856009baa0018a40011375a616002615a026ea80050aa01192cc004c1f8c2b004dd5000c5300103d87a8000899198008009bab30b10130ae01375400444b30010018a6103d87a8000899192cc004c214040062b30013084010018984080998598098588080125eb82298103d87a800042b80513300400430b50100342b8046eb8c2bc04004c2c8040050b00121540232330010013756616002616202615a026ea8c2c004c2c404c2b404dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062610002661640261600200497ae08a60103d87a800042b40513300400430b40100342b4046eb8c2b804004c2c4040050af0145282152028998570080119802002000c4cc0100100050a901185680800985700800a156029bac30ab0130ac010079bae30ab0100648888966002007094018992cc004c2c804012264b3001307e30ae01375400313259800800c566002610402615e026ea8006264b300100185300c4c9660020030a70185380c29c0614e0313259800985b80801c4c96600200309d018992cc004c2e40400a264b300130850130b501375400313259800800c660020031323259800acc004cdd79ba63301f375660dc6172026ea820804cc2ec04dd4808a5eb80c2f004c2f40400a29462a6616e029211769735f76616c75655f6d696e746564203f2046616c73650014a085b00a2b30015980099198008009bac306e30ba0137541060244b30010018a508acc004cdc79bae30be0100100f8a51899801001185f80800a1700242f00514a315330b70149011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085b00a2b300159800984580985c009baa01a8992cc0056600266e3cc08400402229462a6617002920134636f6d707574655f747265655f68617368287472656529203d3d20696e7075745f6d65726b6c655f726f6f74203f2046616c73650014a085b80a2b30015980099baf374c604e0026e9800a29462a66170029212f6b65795f76616c756573203d3d206f75747075745f6d65726b6c655f7265636f72645f6c697374203f2046616c73650014a085b80a2b30013371e6eb8c2f404c2e804dd5002245200000000000000000000000000000000000000000000000000000000000000000008a518a9985c00a494d6f75747075745f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085b80a29410b7014528216e0230bc0130b901375403513371e60c26eb8c2f004c2e404dd5001cc004c18401e00337586178026172026ea806901b216c028a518a9985b80a4811769735f747265655f75706461746564203f2046616c73650014a085b00a29410b6014528216c0237566176020033001323300100100d2259800800c52f5c1133225980099baf30be0130bb0137540040251330bd0100233004004001899802002000a1700230bc0100130bd0100142e8054bd708101a0008101a000488c9660026112026172026ea800626644b30010018cc00400626617c026e98cc2f804cdd81ba937660026ea4dd99ba60023756617e020086617c026e98cc154dd5984500802198111bab308a0130bc01375400a6617c026ea40512f5c097ae085980a0f685980c2cc06166030b301430405300137566110026174026ea800e02501a4108617a026174026ea80062a66170029212f65787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206f75747075742e646174756d001642dc04610c026172026ea800902b42b40502a42b40615a030ad0185680a1780230b90130b60137540030a00142cc04610402616a026ea800613c0285b008c2dc040050b5011919800800804912cc004006297ae0899912cc0056600266ebcc2e804c2dc04dd5001008c4c22004c966002611202616e026ea80062900044dd6985d80985c009baa00142d40464b300130890130b701375400314c0103d87a8000899198008009bab30bc0130b901375400444b30010018a6103d87a8000899192cc004c240040062b3001308f0100189846009985f00985e0080125eb82298103d87a800042e40513300400430c00100342e4046eb8c2e804004c2f4040050bb01216a02323300100137566176026178026170026ea800c896600200314c103d87a8000899192cc004cdc880a000c56600266e3c05000626116026617a0261760200497ae08a60103d87a800042e00513300400430bf0100342e0046eb8c2e404004c2f0040050ba01452821680289985c8080119802002000c4cc0100100050b401185c00800985c80800a16c0285400a16802375c00285b808c2d0040050b2011858009baa00185280a15a0285280c2940614a030a50142d404616402615e026ea80062a6615a0292014665787065637420496e6c696e65446174756d28747265655f726f6f7429203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642b00460f6615c026ea8c1f0c2b804dd5000c254050af01185800801a15c020c2a004004c29c04c29c04c29c04c29c04004c28804dd5198301bac30a50100109e01233001309b013754613c026136026ea817a4444b30010018801c4c966002007153309e01491256e6f7420656e6f756768206b65792d76616c75657320746f206d617463682070726f6f667300168992cc004c1ccc28004dd500146600200d9800802cdd7185000800cdd7185080800cdd61852009850809baa002407930a501004985280801a00c8a9984f80a4930657870656374204d5046496e73657274207b2070726f6f663a20696e736572745f70726f6f66207d203d2070726f6f660016427804614602006850808c288040050a0014c26c04dd5032244530013002002985080801cdd5985080985100801cc288040066eb0c2840400522222332298009854809854808014dd61854008014c2a404c2a404c2a404c2a4040066eb8c2a004005222298009bab30ac010049bac30ac0130ad0130ad0130ad0130ad010049856808014dd71856008012444466446465300137566168020033756616802616a0200332330010010102259800800c52f5c11332259800acc004cdd7985c00985a809baa30b80130b90130b501375400400f13086013259800984380985a809baa0018a40011375a617202616c026ea80050b301192cc004c21c04c2d404dd5000c530103d87a8000899198008009bab30ba0130b701375400444b30010018a6103d87a8000899192cc004c238040062b3001308d0100189845009985e00985d0080125eb82298103d87a800042dc0513300400430be0100342dc046eb8c2e004004c2ec040050b90121660232330010013756617202617402616c026ea8c2e404c2e804c2d804dd5001912cc004006298103d87a8000899192cc004cdc8806800c56600266e3c0340062611202661760261720200497ae08a60103d87a800042d80513300400430bd0100342d8046eb8c2dc04004c2e8040050b801452821640289985b8080119802002000c4cc0100100050b201185b00800985b80800a1680248896600200309b018992cc004c2e40400a264b300130850130b501375400313259800800c6600200313259800800c28406264b300130bd010028992cc004c22404c2e404dd5000c4c96600200319800800c566002b30013375e6e98048dd3004c528c54cc2e40524011669735f76616c75655f6275726e74203f2046616c73650014a085c00a2b3001598009919800800809112cc00400629422b30013371e6eb8c30004004056294626600400461820200285d0090be014528c54cc2e4052411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085c00a2b300159800984680985d009baa01c8992cc0056600266e3cdd7185f80985e009baa006489200000000000000000000000000000000000000000000000000000000000000000008a518a9985d00a4950696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085c80a2b30015980099b8f3023001375c617e026178026ea800a29462a66174029215f636f6d707574655f747265655f68617368287472656529203d3d206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203f2046616c73650014a085c80a2b30013375e6e98c0a4004dd31919800800806112cc004006297adef6c60899191980080099802002186200801912cc0040062661860200697adef6c608992cc004cdd799912cc004cdc8001000c530103d87980008acc004cdc7801000c530103d87a80008a6103d87b8000430404860808dca1bae30c10100437286eb8c3040400530103d87980008998620080200144cc31004004cc00c00cc318040090bf01186200800a1840230c10100142fc0514a315330ba014913c657874726163745f6b65795f76616c756573287472656529203d3d20736f727465645f73657269616c697365645f696e70757473203f2046616c73650014a085c80a29410b901452821720230be0130bb01375403913371e60c66eb8c2f804c2ec04dd5000cc004c18cdd7185f00985d809baa0058054dd6185f00985d809baa01c407485c00a29462a661720292011769735f747265655f75706461746564203f2046616c73650014a085c00a29410b801452821700285300a05c85300c2980614c030a601430004617a026174026ea80061480285b808c21804c2e404dd5000c288050ba01185d80800a1720232330010010122259800800c52f5c11332259800acc004cdd7985f00985d809baa00200d8984600992cc004c23404c2ec04dd5000c5200089bad30bf0130bc01375400285c808c966002611a026176026ea8006298103d87a8000899198008009bab30c00130bd01375400444b30010018a6103d87a8000899192cc004c250040062b30013093010018984800998610098600080125eb82298103d87a800042f40513300400430c40100342f4046eb8c2f804004c304040050bf0121720232330010013756617e026180026178026ea800c896600200314c103d87a8000899192cc004cdc8809800c56600266e3c04c0062611e026618202617e0200497ae08a60103d87a800042f00513300400430c30100342f0046eb8c2f404004c300040050be01452821700289985e8080119802002000c4cc0100100050b801185e00800985e80800a1740284f80a05484f80c27c0613e0309f0142f004617202616c026ea80062a66168029214865787065637420496e6c696e65446174756d28696e7075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642cc04610402616a026ea8c20c04c2d404dd5000c270050b601185b80800a16a024c004c8c8cc004004040896600200314bd7044cc8966002600a0051330b70100233004004001899802002000a1640230b60100130b70100142d00446466ebcc2d404c2c804dd5185a80985b009859009baa0020013064375c6168020094bd70901a0008101a000488c9660026104026164026ea800626644b30010018cc00400626616e026e98cc2dc04cdd81ba937660026ea4dd99ba600237566170020086616e026e98cc138dd598418080218251980d9bab30830130b5013754610602616a026ea8014cc2dc04dd480325eb812f5c109b0141d109b0184d80c26c061360285d00a60026eacc20404c2cc04dd51840809859809baa003802404d03b185b009859809baa0018a9985880a4813465787065637420496e6c696e65446174756d28696e7075745f646174756d29203d20696e7075742e6f75747075742e646174756d001642c00460fe6164026ea8c20004c2c804dd50012048375c6164026166026166020046162026162026162026162020046160020041853808011851809baa330613758614c0200413e0221300242600484c009098012130022980091000c0069101004008446466002002601400644b30010018a5eb7bdb18226644b300132330010010062259800800c528456600266e3cdd71852008008024528c4cc008008c2940400509e012144028cc004cc15801800a0032229800800c01600700240c882aa200284e008dd718500080099801001185080800a13c023001001223300122225980099b87002480822009132598009837984e809baa0018cc00401e4400533013005489200000000000000000000000000000000000000000000000000000000000000000008024c12800e004803a26464b30013371000200b153309e0149012e696e76616c696420747265652c206368696c6472656e206d75737420626520736f7274656420627920696e64657800168992cc004c1ccc28004dd5000c56600266e1c01800a3300100a910014cc058022600201522001985080801ccdc5002cc00528d20028032f2480526eacc29004c28404dd5000cc13401a00a80523300100a910014cc058021220120000000000000000000000000000000000000000000000000000000000000000000803cc13401a00a805109e01454cc27c052412a65787065637420536f6d65287461696c5f6e6f64657329203d206c6973742e7461696c286e6f646573290016427804b30010068a6103d87a80008983819851009ba630a4010064bd702142024274046eb4c27804004c8cdd81851008009851009851808009bac30a101309e01375400284d8096600200714c103d87a8000898369984f80991ba7330a001309d01001330a001309e010014bd70185000801a5eb8109e0121340222598009836984d009baa0028991919826800992cc0040062a661380292012e696e76616c6964206368696c64206861736865732c206d7573742062652061206e6f6e2d656d707479206c69737400168acc004c2880400626eb8c2840400626601000297ae0427c0484f808c04e600200d22002a5eb826eacc28004c2840400a90004cdc5001800a00c375c613e020026136026ea800a264646644b3001980099b8f37280040034a14a284e00a2a6613a0266e59241056b65793a20003732660406ea4009220100153309d013372c920106706174683a20003732660406ea4005220100153309d014912d696e76616c696420747265652c2070617468206973206e6f74207468652068617368206f6620746865206b65790016899192cc004cdc7800803c4cc144cc0dc00c008dca1bae30a40130a5010058a9984f8099b964910e706174685f6e6962626c65733a20003732660446ea4005220100153309f013372c9201107072656669785f6e6962626c65733a20003732660446ea401d220100153309f0149128696e76616c696420747265652c2070726566697820646f6573206e6f74206d61746368207061746800164278053001002a400100140dc6e3401509c011bae30a001001375c6140020046140020026136026ea800909801180100109112cc004c17400a264b300100180344c966002003159800984880801466002003003803a00c803a11c02803c01e00f007424804611e02002846808c22c04dd5027456600260b800513259800800c01a264b30010018acc004c2440400a33001001801c01d006401d08e01401e00f007803a12402308f010014234046116026ea813a2b3001305a0028992cc00400600d13259800800c56600261220200519800800c00e00e826200e84700a00f007803c01d09201184780800a11a02308b01375409d159800982b80145660026116026ea813a00300542300515980099b874802000a264b300100180344c966002003159800984880801466002003003803a00a803a11c02803c01e00f007424804611e02002846808c22c04dd50274566002605400513259800800c01a264b30010018acc004c2440400a33001001801c01d005401d08e01401e00f007803a12402308f010014234046116026ea813a00a84400908801211002422004844009088010888c96600260ba00313259800800c00e264b30010018024012264b300130920100389981a000912cc00400a01113259800800c6600200313002309501003804206c804402201100842580461260200484880a00a847808dd6000c012008849008c23c0400508d011845809baa0048acc004c170006264b3001001801c4c96600200300480240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01513259800984c00801c4cc0e8004896600200500e8992cc0040063300100189801184d80801c03903c403a01d00e807213802309901002425c0500b4254046eb000601500a426004612a02002849808dd7000984a00801212a023092010014240046eb8004c2440400909201184780800a11a02308b013754009159800982d000c4c9660020030038992cc0040060090048992cc004c2480400e26606800244b300100280444c96600200319800800c4c008c2540400e01081b2011008804402109601184980801212202802a11e023758003004802212402308f010014234046116026ea8012004844009088012110023089013754007001800c00600284600856600209319800911192cc004c170006264b3001001801c4c96600200300480244c96600261220200713303300122598008014022264b30010018cc0040062600461280200700840d5008804402201084a808c2480400909001401508e011bac001802401109101184700800a11802308a013754009159800982d800c4c9660020030038992cc004006009004802401226644b300100180344c966002003007803c4c9660026128020071330360012259800801402e264b30010018cc00400626004612e0200700b40e100b805c02e01684c008c25404009093014021091011bac001803c01d09401184880800a11e02375c002612002004848808c2380400508c011845009baa0048acc004c164006264b3001001801c4c96600200300480244cc89660020030068992cc00400600f007803c01e264b300130940100389981b002112cc00400a01713259800800c6600200313002309701003805a070805c02e01700b426004612a0200484980a010848808dd7000a12802309101001423c046eb0004c2400400a009004424404611c02002846008c22804dd5002400908701210e02421c046110026ea800e3300123259800982d1843809baa0018992cc004cdc39bad308c01308d01308d010014800626eb8c230040062a6610e0292115657870656374207175616e74697479203d3d202d3100164218046eb0c22c04c22004dd5000c54cc2180524019d65787065637420536f6d652828706f6c6963795f69642c205f61737365745f6e616d652c207175616e746974792929203d0a202020206c6973742e66696e64280a2020202020206d696e742c0a202020202020666e28656e74727929207b0a20202020202020206c657420285f2c205f2c2071747929203d20656e7472790a2020202020202020717479203c20300a2020202020207d2c0a20202020290016421404646600200200444b30010018a60103d87a80008992cc004cdc41bad308d01308e01308e0100148002260b466118026e9c0052f5c1133003003308e01002421c046eb0c2300400508a0148896600260b66110026ea800e264b300100180144c966002003003801c00e0071332259800800c016264b3001001803401a00d006899912cc00400601113259800800c026013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f1332259800800c046264b3001001809404a025012899912cc00400602913259800800c05602b01580ac4cc89660020030178992cc00400603101880c406226644b300100180d44c96600200313259800800c072264b300100180ec07603b1332259800800c07e264b300100181040820411332259800800c08a264b3001001811c08e26644b3001001812c4c96600200313259800985780800c56600266e25200430ae01001813c4cc89660020030298992cc00400605502a81544cc896600200302c8992cc00400605b02d816c4cc896600200302f8992cc00400606103081844cc89660020030328992cc004006067033819c0ce26644b300100181ac4c96600200303681b40da264b300130c3010038cc0040762660ca02844b300100281d44c96600200303a81d40ea075132300330c701004375c002863808c310040090c20140dd07e40dd0c0011bad00181b21860230c00100142f8046eb8004c2fc040090c001185e80800a17602375a00261780200503042f40461740200285c008dd6800985c8080140b50ba01185b80800a16a02375a002616c0200502a42dc04616802002859008c20004c2b804004c2cc0400d0ac01409d0b0011baa001813409a04d02642cc04616002002857008dd6000985780801408e046858008c2b4040050ab011bad00130ac01002810215a0230aa0100142a0046eb4004c2a40400a03a855008c29c040050a501185380801406e03701b80da1500230a501001428c046eb8004c290040090a501185100800a14002375c002614202004851008c27c0400509d011bae001309e01002427c0461380200284d008dd7000984d80801213802309901001425c046eb8004c2600400909901184b00800a12802375c002612a0200484b008c24c04005091011bae001309201002424c04612002002847008dd7000984780801212002308d01001422c046112026ea800e00284300a444464b3001305d308a01375400313259800800c56600260bc6116026ea8006264b300100184400c4c9660020030890184480c2240626644b300100184580c4c96600200308c01899912cc00400611c0313259800800c56600261300200513303a0032259800801456600260d0612a026ea800e264b300100184900c4c9660020030930184980c24c06126031332259800800c25406264b300100184b00c2580612c0313259800985000801c4cc27804dd40071984f009ba600b3309e019800acc00566002646600200202c44b30010018a508acc004cdd7985080984f009baa30a10100100b8a51899801001185100800a13602427c0514a3153309a014911869735f7574786f5f636f6e73756d6564203f2046616c73650014a084c80a2b3001329800800c05602880088896600200514a3159800800c54cc27405240120657870656374205b7369672c202e2e726573745f736967735d203d207369677300168acc00660026eb8c2880400a033375c614402002b95456600330010039851808014c28c040050034528c54cc27405241347665726966795f7369676e61747572657328726573745f6b6579732c206d73672c20726573745f7369677329203f2046616c73650014a084e00a294109c0121400242800514a3153309a014901187369676e6174757265735f636865636b203f2046616c73650014a084c80a2941099015300103d87a8000a60103d879800042640497ae084b80a13a02375a00309601428004613a0200284d808dd7000984e00801213a02309a01001426004612c026ea800e1220284980a26464b300100184980c24c0626644b300100184a80c25406264b300100384b00c4c9660020030970184b80c25c0612e031332259800800c26406264b300100184d00c268061340309a018992cc004c2900400e2b300100684d80c4c96600200309c0184e00c2700626644b300100184f00c4c96600200309f0184f80c27c06264b300130a90100389808185480808c280050a6011bad00184f80a1520230a6010014290046eb4004c2940401e13802853008c28c040190a101426c050a1011bae00142900461420200284f808dd7000985000802214202309e010034270046eb000612a0309501427c046eb0004c2600400a1260309301427404612c0200261320200484b80a11e0284a80a11e0308f0184780c23c0509901184b00800a128023756002612a0200508c0184600c2300509601184980800a12202375a00261240200508901424c04612002002847008c23004dd5000c21c0508901421c0610e030870184380a12202308e01308b0137540031533089014913b65787065637420536f6d65287369676e65645f6461746129203d2063626f722e646573657269616c697365287072696365735f6d65737361676529001642200460140092225980099b880014800229000456600260b600314800a264b3001305c3370c0049002466002009300100399b830024801100444c0066002009300100399b83303300248011004210e0237040048430090860148c96600260b40031305630880137546116026110026ea800a2b300130590018982b1844009baa308b0130880137540051305630880137546116026110026ea800908501210a0230860137540032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b010019184500984580984580984580984580984580984580984580984580984580984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116026116026116026116026116026116026116026116026116026116020032308a01308b01308b01308b010019184500984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116020032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b010019184500984580984580984580984580984580984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116026116026116026116026116026116020032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b010019112cc004c16cc22004dd5001c4c9660020030028992cc004006007003801c4cc89660020030058992cc00400600d00680344c966002612602007008803a12002375a003006424c04612002002847008dd6800984780801400d09001184680800a116023089013754007001421805308501375409291111111111111111111194c00488c8cc00400400c8966002003148002264664466446600400400244b30010018801c4c8c96600260f0614a026ea800626466e00cc014014c2ac04010cdc199b82375a614e020066eb4c2a804004cc0352014375a6154026156020026eb0c2a404c29804dd5000c54cc290052415865787065637420536f6d65282870726963652c207363616c652929203d0a2020202020202020707269636573207c3e2070616972732e6765745f66697273742828706f6c6963795f69642c2061737365745f6e616d6529290016428c0464646600200201644b30010018a60103d87a80008992cc004cdd79ba700430a8010018983c9985580985480800a5eb82266006006615a02004853008c2ac040050a90119853809ba9005330a70130a4010014bd70185380800a14a0237566144020066eb8c27c04004cc00c00cc29004008c288040050a00148896600266ebcc28404c27804dd5000982880144c96600200319800800c4cdd7980a800802420c0505e420c06106030830184180a1480232598009837184f009baa0018985100984f809baa0018a9984e80a492c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016427004614202614402614402613c026ea8006294109b0148896600266ebcc28404c27804dd51836184f009baa00130510028992cc00400633001001899baf301500100484100a0bc84100c20806104030820142900464b3001306e309e013754003130a201309f013754003153309d0149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016427004614202614402614402613c026ea8c28404c28804c27804dd5000c52821360248896600260e000b13232329800985280985280985280985280985280985280985280985280985280800c88c8cc00400400c896600200314a31598009801985400800c4cc008008c2a40400629410a201214c029852009850809baa0649bac30a401003985280801244444b3001307730a50137540c513298009919800800802112cc004006297ae110180008101800044cc8966002b30013375e615c026156026ea8c1e4c2ac04dd5001002c4c96600200319800800c4cdd7800804c23c0506b423c0611e0308f0184780a162023259800983d9855809baa00189857809856009baa0018a9985500a493265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642a404615c02615e02615e026156026ea8c2b804c2bc04c2ac04dd50014528215002899856809ba7330ad010023758615c020026615a02615c02615e0200297ae08998568098570080099856809ba7330ad010023758615c02615e0200297ae042a00461580200266004004615a0200285500a6644b3001307b0018983c99855809856009854809baa006330ab01375200497ae08acc004c1e8006260e866156026158026152026ea8018cc2ac04dd480125eb82266e952004330ab0130ac0130a901375400c66156026ea40092f5c08530090a6011bae30aa0130ab0100630a6013754009305a375c61540200c9112cc00566002660106eb0c2b404c2b80400ca600266ebcc2b804c2ac04dd5183c9855809baa001005a50a5142a00514a315330a801491226e6f5f6f746865725f6f6c645f7363726970745f696e70757473203f2046616c73650014a085380a2b3001598009980400314c004cdd79857009855809baa307930ab0137540020054a14a285400a29462a661500292011c6e6f5f6e65775f7363726970745f696e70757473203f2046616c73650014a085380a2b30015980099baf374c60e460726eb0c2b40400cdd31839181c1bac30ad0132330010013758615c0200c44b30010018a5eb850180008101800044cc8966002b30013375e616202615c026ea8008016264b30010018cc004006266ebc00401e126028372126030930184980c24c050b401192cc004c1f8c2b804dd5000c4c2c804c2bc04dd5000c54cc2b40524012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642b004616202616402616402615c026ea800a29410ab0144cc2c004dd399858008011bac30b101001330b00130b10130b2010014bd7044cc2c004c2c404004cc2c004dd399858008011bac30b10130b2010014bd7021560230af010013300200230b00100142b40514a315330a8014911a69735f76616c75655f707265736572766564203f2046616c73650014a085380a2b30013232330010013758615e0261600261600261600261600261600261600200e44b30010018a508acc004cdc79bae30b0010010038a51899801001185880800a1540242b8046eb8c2b40402a29462a661500292011569735f617574686f72697a6564203f2046616c73650014a085380a29410a7014528214e028a50429c043059375c615202614c026ea818a2a66148029212b65787065637420536372697074286f6c645f7363726970745f6861736829203d2063726564656e7469616c0016428c0430a0013754660bc6eb0c28c0400427004c28c04004c27804dd5033c56600260de00b1332298009852008014dd71851808014c290040066eb0c28c04005222298009854008024dd61853808024c2a00400a6148026ea8cc188dd618538080105000a44453001375661560200930ab0130ac010049856009856008014dd61855808014c2b004c2b004c2b004c2b004c2b004c2b004c2b004c2b004c2b0040066eb8c2ac0400522222298009bac30b10130b20130b20130b20130b2010049bae30b1010029bae30b10130b20130b2010029814182f9bab30b10100448888c96600200308d018992cc004c2e00400a264b30010018acc004c21c04c2d004dd5000c4c96600200309b018992cc0040061380309c0184e00c2700626644b300100184f00c4c96600200313259800800c28006264b300100185080c4c9660026182020071980080244cc18c004896600200513259800800c27006264b300130c5010028992cc00400613e031325980098638080144c96600200319800800c4c96600200319800800c4c8cc8a60026198026198026198026198020053371e02e6eb8c32c0400a6644646600200205044b30010018a5eb841018000810180008101800044cc8966002600c0051330d001374e661a0020046eb0c34404004cc34004c34404c34804004cc34004c34404c34804c348040052f5c1159800980280144cc34004c34404004cc34004dd399868008011bac30d10130d201001330d00130d10130d20130d2010014bd7044cc34004c34404004cc34004c34404c34804004cc34004dd399868008011bac30d10130d20130d2010014bd70219602432c04619e020026600400461a002002866808cc18c03c064cc0ac0040666644646600200204044b30010018a5eb841018000810180008101800044cc8966002600c0051330d001374e661a0020046eb0c34404004cc34004c34404c34804004cc34004c34404c34804c348040052f5c1159800980280144cc34004c34404004cc34004dd399868008011bac30d10130d201001330d00130d10130d20130d2010014bd7044cc34004c34404004cc34004c34404c34804004cc34004dd399868008011bac30d10130d20130d2010014bd70219602432c04619e020026600400461a002002866808cc18803c064cc0b0004065222298009868009868009868008024c33c0401261a00200530d001001983f80ea44445300130d50130d501005cc0040c205d375861a80200b02c4125306f374e64660020026eb0c35404c35804010896600200314bd7044cc896600266ebcc36004c35404dd5186c00986c80986a809baa00200589986b8080119802002000c4cc0100100050d201186b00800986b80800a1a80298379ba73233001001375861aa0261ac0200644b30010018a5eb8226644b30013375e61b00261aa026ea80080162661ae020046600800800313300400400143480461ac0200261ae0200286a00a613202660d46530010019bac30d501003a5eb7bdb1810011112cc00400a200319800801cc3600400a6530010018014dd5986c00986c80986a809baa30d8010034004444b30010028800c4c8cc8a600200d30de010059919800800802912cc0040062661bc0266ec0dd48021ba60034bd6f7b63044ca60026eb8c370040066eacc3740400661c2020049112cc004cdc8004001c4cc38804cdd81ba9008374c00e00b15980099b8f0080038992cc004c2cc04c38004dd5000c4cc38c04cdd81ba900930e40130e1013754002005100243780464b300159800800c528c52821c4028a6103d87a8000898588099871809ba60014bd7021bc02329800800c022006800888966002005100189919914c00401a61d40200b32330010010052259800800c4cc3a804cdd81ba9004375000697adef6c608994c004dd7187400800cdd6987480800cc3b4040092225980099b900080038998770099bb037520106ea001c0162b30013371e01000713259800985f809876009baa0018998778099bb0375201261e00261da026ea800400a2004875008c966002617e0200314c0103d87a80008985e8099877809ba80014bd7021d4023370000e0051330ee01337606ea400cdd400119803003000a1d20243a40430eb0100143a4048030dd71871808009bad30e40100130e6010024390051330e201337606ea400cdd300119803003000a1ba0243740430df010014374048030dd7186b808009bab30d80100130da0100243600480190d5011833194c0040066eb0c3540401297adef6c604004444b30010028800c6600200730d801002994c004006005375661b00261b20261aa026ea8c36004c36404c35404dd5186c00801a002222598008014400626466453001006986f00802cc8cc00400401489660020031330de01337606ea4010dd3001a5eb7bdb1822653001375c61b802003375661ba0200330e10100248896600266e4002000e2661c40266ec0dd48041ba60070058acc004cdc7804001c4c96600261660261c0026ea80062661c60266ec0dd48049872009870809baa001002880121bc023259800acc004006294629410e2014530103d87a8000898588099871809ba60014bd7021bc02329800800c022006800888966002005100189919914c00401a61d40200b32330010010052259800800c4cc3a804cdd81ba9004375000697adef6c608994c004dd7187400800cdd6987480800cc3b4040092225980099b900080038998770099bb037520106ea001c0162b30013371e01000713259800985f809876009baa0018998778099bb0375201261e00261da026ea800400a2004875008c966002617e0200314c0103d87a80008985e8099877809ba80014bd7021d4023370000e0051330ee01337606ea400cdd400119803003000a1d20243a40430eb0100143a4048030dd71871808009bad30e40100130e6010024390051330e201337606ea400cdd300119803003000a1ba0243740430df010014374048030dd7186b808009bab30d80100130da0100243600480190d501244445300130da010059bad30d901005986d0080256600266ebcdd3184f0099837994c0040066eb0c3680403697adef6c604004444b30010028800c6600200730dd01002994c004006005375661ba0261bc0261b4026ea8c37404c37804c36804dd5186e80801a002222598008014400626466453001006987180802cc8cc00400401489660020031330e301337606ea4010dd3001a5eb7bdb1822653001375c61c202003375661c40200330e60100248896600266e4002000e2661ce0266ec0dd48041ba60070058acc004cdc7804001c4c96600261700261ca026ea80062661d00266ec0dd48049874809873009baa001002880121c6023259800acc004006294629410e7014530103d87a80008985b0099874009ba60014bd7021c602329800800c022006800888966002005100189919914c00401a61de0200b32330010010052259800800c4cc3bc04cdd81ba9004375000697adef6c608994c004dd7187680800cdd6987700800cc3c8040092225980099b900080038998798099bb037520106ea001c0162b30013371e010007132598009862009878809baa00189987a0099bb0375201261ea0261e4026ea800400a2004877808c96600261880200314c0103d87a800089861009987a009ba80014bd7021de023370000e0051330f301337606ea400cdd400119803003000a1dc0243b80430f00100143b8048030dd71874008009bad30e90100130eb0100243a4051330e701337606ea400cdd300119803003000a1c40243880430e4010014388048030dd7186e008009bab30dd0100130df0100243740480190da011835994c0040066eb0c3680403297adef6c604004444b30010028800c6600200730dd01002994c004006005375661ba0261bc0261b4026ea8c3740400d0011112cc00400a2003132332298008034c38c04016646600200200a44b30010018998718099bb037520086e9800d2f5bded8c113298009bae30e1010019bab30e2010019873008012444b3001337200100071330e701337606ea4020dd3003802c56600266e3c02000e264b300130b80130e50137540031330e801337606ea4024c3a404c39804dd5000801440090e301192cc0056600200314a314a087380a298103d87a80008985b0099874009ba60014bd7021c602329800800c022006800888966002005100189919914c00401a61de0200b32330010010052259800800c4cc3bc04cdd81ba9004375000697adef6c608994c004dd7187680800cdd6987700800cc3c8040092225980099b900080038998798099bb037520106ea001c0162b30013371e010007132598009862009878809baa00189987a0099bb0375201261ea0261e4026ea800400a2004877808c96600261880200314c0103d87a800089861009987a009ba80014bd7021de023370000e0051330f301337606ea400cdd400119803003000a1dc0243b80430f00100143b8048030dd71874008009bad30e90100130eb0100243a4051330e701337606ea400cdd300119803003000a1c40243880430e4010014388048030dd7186e008009bab30dd0100130df0100243740480190da011ba6001899baf374c0026e98c27804c17c06a29410d30124445300130de010049bad30dd01004985580986c809baa30dd0130de010029981fcc004c18c07a05503241886eacc37404009222298009bad30e1010049bae30e10130e201004acc004c2c00401e2003159800985800803c4006266e0ccdc10008039bad30e10100c436c0486d80a6ecc09522225330e0013372c9201096d70665f6b65793a20003732660c66ea4005220100159800acc00406629462a661c00292011769735f696e74656e745f76616c6964203f2046616c73650014a086f80a2b3001598008034528c54cc3800524011a69735f7072696365735f7665726966696564203f2046616c73650014a086f80a2b300159800807c528c54cc3800524011f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a086f80a2b3001598008074528c54cc380052401206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a086f80a2b300159800804c528c54cc3800524012169735f76616c75655f7472616e736665725f636f7272656374203f2046616c73650014a086f80a2b300159800acc0056600266e1cdd6982b9871009baa01e3370001600514a315330e0014911f69735f746f74616c5f7368617265735f636f7272656374203f2046616c73650014a086f80a2b30015980099b87375a60ac61c4026ea80796600266ebc0a4056266e0001c00a200e86f80a29462a661c00292012269735f6f70657261746f725f7368617265735f636f7272656374203f2046616c73650014a086f80a2b30015980099b87375a60aa61c4026ea8078cdc0002002c528c54cc380052412269735f746f74616c5f6465706f73697465645f636f7272656374203f2046616c73650014a086f80a2b30015980099b8f375c60a861c4026ea8078c966002616a02003133225330e3013372c9210b6e65775f76616c75653a20003732660cc6ea400522010019800984680803401200300241886eb0c39804c38c04dd501d1bb330b301330e5013750006661ca026ea00192f5c1159800985a00800c4c8c8cc896600261720261cc026ea800a264b30010018cc00400633001309001009803c00a0093766617002661d4026ea0cdc01bad30eb0130e8013754002010661d4026ea0cdc01bad30b60130e801375400201697ae041910c90141410c90186480c3240619202876808c3a804c39c04dd5001431c050e40118328009bac30e80130e901002375c61ce0200261c6026ea80ea2a661c2029211e496e76616c6964204d504620616374696f6e20666f72206465706f7369740016438004870008c38404dd501cc528c54cc3800524011e69735f6d65726b6c655f726f6f745f636f7272656374203f2046616c73650014a086f80a2b30015980099b8f375c61ca0261c4026ea8078dd71872809871009baa01f8acc004cdc79bae30b00130e201375403c6eb8c2c004c38804dd500fc56600266e3cdd71857809871009baa01e375c615e0261c4026ea807e2b30013371e6eb8c14cc38804dd500f1bae305330e201375403f15980099b8f375c612e0261c4026ea8078dd7184b809871009baa01f8acc004cdc79bae305230e201375403c6eb8c148c38804dd500fc56600266e3cdd718289871009baa01e375c60a261c4026ea807e2b30013371e6eb8c140c38804dd500f1bae305030e201375403f15980099baf30960130e201375403c612c0261c4026ea807e2b30013370e6eb4c13cc38804dd500f1bad304f30e201375403f15980099b87375a609c61c4026ea8078dd698271871009baa01f8acc004cdd798269871009baa01e304d30e201375403f159800acc004c2cc04c38404dd518261871009baa01e89859809870809baa304c30e201375403f198009859809870809baa304c30e201375403f4a14a286f8090df0144cdc39bad304b30e201375403c6eb4c12cc38804dd500fc52821be028a50437c0514a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be028a518a9987000a492169735f6f746865725f6669656c64735f756e6368616e676564203f2046616c73650014a086f80a29410df01452821be028a50437c0514a086f80a29462a661c00292011f69735f6f7261636c655f646174756d5f75706461746564203f2046616c73650014a086f80a2b300132330010010352259800800c528456600266e3cdd718738080081bc528c4cc008008c3a0040050e10121ca028a518a9987000a491169735f7369676e6564203f2046616c73650014a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be0200c32804c32804c32804004c24404cc32004c324040052f5c0619202618a026ea800a1480281f2148030a40185200c290050ca01192cc004c25004c31004dd5000c4c32004c31404dd5000c54cc30c0524012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016430804618e026190026190026188026ea800a1440281ea144030a20185100c288050c901192cc004c24c04c30c04dd5000c4c31c04c31004dd5000c54cc3080524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016430404618c02618e02618e026186026ea8c31804c31c04c30c04dd5001c280050c401186280800a1860232330010010172259800800c52f5c11332259800991980080099198008009bab30ca0130cb0130c701375400844b30010018a5eb82264664464660020026eacc330040108966002003100389919868009ba7330d001375200a661a002619a02002661a002619c0200297ae03300300330d20100230d0010014338046eb8c32004004cc00c00cc33404008c32c040050c901112cc00400629422b30013371e6eb8c32804dd61865008008084528c4cc008008c32c040050c4012190028998638080119802002000c4cc0100100050c201186300800986380800a1880284e80a1840230c301001430404646600200203a44b30010018a5eb8226644b3001323300100132330010013756619002619202618a026ea8c32004c32404c31404dd5002112cc004006297ae0899199119198008009bab30ca010042259800800c400e2646619c026e9ccc33804dd480299867009865808009986700986600800a5eb80cc00c00cc34004008c338040050cc011bae30c6010013300300330cb0100230c901001431c0444b30010018a508acc004cdc79bae30c801375861900200201d14a313300200230c90100143080486300a26618a0200466008008003133004004001430004618802002618a0200286100a26464b300100185300c2980614c030a601899912cc00400615003133069375600244b30010028980398648080444c8c9660020030ac0185600c2b006158031332259800800c2b80615c030ae0189918031867008039bad00185700a19c02375c002618e02004866008c31404004c320040090c60142a006150030a8014320046eb8004c304040090c601185f8080098610080121800285100a0f885100a17c0237560030a10185080c284050c101185f00800a1780230be0100284f80c27c0613e0309f0142fc0461780200285d008dd7000985d8080121780230b90100142dc04616a026ea80061340285900a1340309a0184d00c268050ba01192cc004c21004c2d004dd5000c4c2e004c2d404dd5000c54cc2cc0524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642c804616e026170026170026168026ea8c2dc04c2e004c2d004dd5000c238050b501185b00800a168023232330010010112259800800c52f5c11332259800acc004cdd7985d00985b809baa30ba0130bb0130b701375400400b1323300100132330010013756617802617a026172026ea8c2f004c2f404c2e404dd5002112cc004006297ae0899199119198008009bab30be010042259800800c400e26466184026e9ccc30804dd48029986100985f808009986100986000800a5eb80cc00c00cc31004008c308040050c0011bae30ba010013300300330bf0100230bd0100142ec0444b30010018a508acc004cdc79bae30bc01375861780200201114a313300200230bd0100142d80485d00a29410b40144cc2e404008cc01001000626600800800285a008c2e004004c2e4040050b60118328008184f009baa061309e0137540cf19800984f009baa0619119b83304933700004002003309e0137540ce9114c004c2940400e6eb8c2900400e44464b300133712002900045200089980319b8200100248320050a20119b81003002985280800cdd6185200800a44445300130aa010059bac30a9010059855008014c29804dd5198321bac30a9010020a2014888a6002615c020093756615a0200930ae0130ae010029bac30ad01002985700985700985700985700985700985700985700985700985700800cdd7185680800a444445300130b301006985980985a008034dd6185980985a00985a00985a00985a008024dd71859808014dd7185980985a00985a008014c0a8c184dd5985980802244444464b300100184880c4c96600261780200513259800800c5660026116026170026ea8006264b300100184a80c4c9660020030960184b00c2580612c031332259800800c26006264b30010018992cc0040061340313259800800c26c061360309b018992cc004c3140400e330010048992cc00400613c031325980098638080144c9660020030a1018992cc004c3240400a264b30010018cc004006264b30010018cc0040062646645300130ce0130ce0130ce0100299911919800800814112cc004006297ae11018000810180008101800044cc8966002600c0051330d201374e661a4020046eb0c34c04004cc34804c34c04c35004004cc34804c34c04c35004c350040052f5c1159800980280144cc34804c34c04004cc34804dd399869008011bac30d30130d401001330d20130d30130d40130d4010014bd7044cc34804c34c04004cc34804c34c04c35004004cc34804dd399869008011bac30d30130d40130d4010014bd70219a0243340461a2020026600400461a402002867808cc0b400405ccc19403405e6644646600200204044b30010018a5eb841018000810180008101800044cc8966002600c0051330d201374e661a4020046eb0c34c04004cc34804c34c04c35004004cc34804c34c04c35004c350040052f5c1159800980280144cc34804c34c04004cc34804dd399869008011bac30d30130d401001330d20130d30130d40130d4010014bd7044cc34804c34c04004cc34804c34c04c35004004cc34804dd399869008011bac30d30130d40130d4010014bd70219a0243340461a2020026600400461a402002867808cc0b800405ccc19003405d2229800986880801cc3400400e61a20200530d10100148888c8c8cc8a600261b202005375a61b00200530d9010019bad30d8010014888a600261ba02009375a61b802009375661b8020053370666e0806400400d22223233223298009bad30e40100199baf0240139bad30e4010144888ca6002b3001003899b8100b025899b8000b0014388053370066e0403c094006613002065375c61d00261d20200b59800801c4026266e0402660020130048012084438804911112cc0056600266e3c0d4dd71876808114528c54cc3a00524011769735f696e74656e745f76616c6964203f2046616c73650014a087380a2b300159800985d809874809baa30ed0130ee010138a518a9987400a491a69735f7072696365735f7665726966696564203f2046616c73650014a087380a2b3001598009844009ba73233001001375861dc0261de0203844b30010018a5eb8226644b30013375e61e20261dc026ea8c3c404c3c804c3b804dd5001003c4cc3c004008cc010010006266008008002875808c3bc04004c3c0040050ed014528c54cc3a0052411f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a087380a2b3001598009844009ba73233001001375861dc0261de0203644b30010018a5eb8226644b30013375e61e20261dc026ea800801e2661e0020046600800800313300400400143ac0461de0200261e00200287680a29462a661d002921206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a087380a2b300159800acc004cdc399827cc004cc20c04ca6002003375861dc020414bd6f7b63020022225980080144006330010039878808014ca60020030029bab30f10130f20130ee01375461e20261e40261dc026ea8c3c40400d0011112cc00400a2003132332298008034c3dc04016646600200200a44b300100189987b8099bb037520086e9800d2f5bded8c113298009bae30f5010019bab30f601001987d008012444b3001337200100071330fb01337606ea4020dd3003802c56600266e3c02000e264b300130cc0130f90137540031330fc01337606ea4024c3f404c3e804dd5000801440090f701192cc0056600200314a314a087d80a2980103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee01183f994c0040066eb0c3b80407e97adef6c604004444b30010028800c6600200730f101002994c004006005375661e20261e40261dc026ea8c3c40400d0011112cc00400a2003132332298008034c3dc04016646600200200a44b300100189987b8099bb037520086e9800d2f5bded8c113298009bae30f5010019bab30f601001987d008012444b3001337200100071330fb01337606ea4020dd3003802c56600266e3c02000e264b300130cc0130f90137540031330fc01337606ea4024c3f404c3e804dd5000801440090f701192cc0056600200314a314a087d80a298103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee0140da07e839003c006266e1ccc13e600266106026530010019bac30ee0101ba5eb7bdb1810011112cc00400a200319800801cc3c40400a6530010018014dd59878809879009877009baa30f1010034004444b30010028800c4c8cc8a600200d30f7010059919800800802912cc0040062661ee0266ec0dd48021ba60034bd6f7b63044ca60026eb8c3d4040066eacc3d80400661f4020049112cc004cdc8004001c4cc3ec04cdd81ba9008374c00e00b15980099b8f0080038992cc004c33004c3e404dd5000c4cc3f004cdd81ba900930fd0130fa013754002005100243dc0464b300159800800c528c52821f6028a6103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee01183f994c0040066eb0c3b80407297adef6c604004444b30010028800c6600200730f101002994c004006005375661e20261e40261dc026ea8c3c404c3c804c3b804dd5187880801a002222598008014400626466453001006987b80802cc8cc00400401489660020031330f701337606ea4010dd3001a5eb7bdb1822653001375c61ea02003375661ec0200330fa0100248896600266e4002000e2661f60266ec0dd48041ba60070058acc004cdc7804001c4c96600261980261f2026ea80062661f80266ec0dd4804987e80987d009baa001002880121ee023259800acc004006294629410fb014530103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee0140da07e839003c00629410e7014528c54cc3a00524012169735f76616c75655f7472616e736665725f636f7272656374203f2046616c73650014a087380a2b300159800acc004022266e24cdc11bad30ed010190043370400a906400c528a1ce028a518a9987400a492d69735f6f70657261746f725f6d696e5f70657263656e746167655f6d61696e7461696e6564203f2046616c73650014a087380a2b300159800acc0056600266e1cdd6982f9875009baa0240048a518a9987400a491f69735f746f74616c5f7368617265735f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60bc61d4026ea809001629462a661d0029212269735f6f70657261746f725f7368617265735f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60ba61d4026ea8090cdc09bad30ed010110098a518a9987400a4812269735f746f74616c5f6465706f73697465645f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60a661d4026ea8090cdc01bad30ed0130ee0100d0068a518a9987400a4812c69735f746f74616c5f6665655f73686172655f636f6c6c65637465645f636f7272656374203f2046616c73650014a087380a2b30015980099b8f375c60b861d4026ea80916600266e2120000068acc004c2f004c3a404dd501cc4c96600266e2401d20008801c4cc8966002617e0200319800984a80802c00a6eccc2f404cc3bc04dd40049987780a6010100004bd704dd61878009876809baa00341a9159800985f00800c4c8c8cc896600261860261e0026ea800a264b30010018cc00400633001309a0100a803c00a0093766618402661e8026ea0cdc01bad30f50130f201375400201c661e80261800261e4026ea80052f5c083721a60282d21a6030d30186980c34c050f701187a009878809baa00286880a1dc02306f001375861e40261e6020046eb8c3c404004c3b404dd5001c54cc3ac0524129496e76616c6964204d504620616374696f6e20666f72206f70657261746f7220666565207368617265001643a804875008dd980e9875009baa00143a00461da0261d4026ea80e62a661d0029212965787065637420536f6d6528616374696f6e29203d206f70657261746f725f6d70665f616374696f6e0016439c051002439c0514a315330e8014911e69735f6d65726b6c655f726f6f745f636f7272656374203f2046616c73650014a087380a2b30015980099b8f375c61da0261d4026ea8090dd71876809875009baa0258acc004cdc79bae30b80130ea0137540486eb8c2e004c3a804dd5012c56600266e3cdd7185b809875009baa024375c616e0261d4026ea80962b30013371e6eb8c16cc3a804dd50121bae305b30ea01375404b15980099b8f375c613e0261d4026ea8090dd7184f809875009baa0258acc004cdc79bae305a30ea0137540486eb8c168c3a804dd5012c56600266e3cdd7182c9875009baa024375c60b261d4026ea80962b30013371e6eb8c160c3a804dd50121bae305830ea01375404b15980099baf309e0130ea013754048613c0261d4026ea80962b30013370e6eb4c15cc3a804dd50121bad305730ea01375404b15980099b87375a60ac61d4026ea8090dd6982b1875009baa0258acc004cdd7982a9875009baa024305530ea01375404b159800985d809874809baa305430ea013754049130bb0130e901375460a861d4026ea80963300130bb0130e901375460a861d4026ea80969429450e70121ce028a50439c0514a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a518a9987400a492169735f6f746865725f6669656c64735f756e6368616e676564203f2046616c73650014a087380a29410e701452821ce028a50439c0514a087380a29410e7014528c54cc3a00524011f69735f6f7261636c655f646174756d5f75706461746564203f2046616c73650014a087380a2b300159800991980080081c912cc00400629422b30013371e6eb8c3bc040040f6294626600400461e0020028748090ed014528c4c966002617a0261d4026ea8006264646600200207644b30010018a508acc004cdc79bae30f1010010038a51899801001187900800a1d60243bc046eb8c3b804c3ac04dd5000c52821d002306001c439c0514a315330e80149011169735f7369676e6564203f2046616c73650014a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a50439c045980080145200089982299b829800804400e00282080380310e1010c96600261600200313232332259800985b809872009baa0028992cc004006330010018acc004cdc38131bad30e90130e60137540031330e80130b40130e6013754002661d0026ea66002611c02011007802400906125eb822a661c80292012b657870656374207368617265735f746f5f72656465656d203d3d206f6c645f656e7472792e7368617265730016438c050c80141390c80186400c3200619002875808c3a004c39404dd5001454cc38c0524013365787065637420536f6d65286f6c645f6461746129203d2063626f722e646573657269616c697365286f6c645f76616c756529001643880460c60026eb0c39804008dd71872809873008009870809baa0318acc004c2c804006264646644b300130b70130e401375400513259800800c6600200315980099b89026375a61d20261cc026ea8006264661d2026ea0004cc3a404dd4cc004c23c04026011003802cdd9985b8099874809ba8337026eb4c3a804c39c04dd500101399874809ba8337026eb4c2d404c39c04dd5001000a5eb8106325eb80cdc199b82375a61680261cc026ea8004098dd69874809873009baa0018a9987200a4812b657870656374206f6c645f656e7472792e736861726573203e3d207368617265735f746f5f72656465656d0016438c050c70141390c70186380c31c0618e02875808c3a004c39404dd50014314050e20118318009bac30e60130e701002375c61ca0200261c2026ea80c62a661be02920121496e76616c6964204d504620616374696f6e20666f72207769746864726177616c001643780486f008c37c04dd50181bae30e101001376604261c202008186b80986b80800cc0040c605d375861ac0200302c412c61ac0200261aa020081866009866009866009866008009849809986500986580800a5eb80c32c04c31c04dd500142980504042980614c030a60185300a198023259800984b009863009baa00189865009863809baa0018a9986280a492c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016431004619202619402619402618c026ea800a1480281fa148030a40185200c290050cb01192cc004c25404c31404dd5000c4c32404c31804dd5000c54cc3100524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016430c04619002619202619202618a026ea8c32004c32404c31404dd5001c288050c601186380800a18a0232330010010172259800800c52f5c11332259800991980080099198008009bab30cc0130cd0130c901375400844b30010018a5eb82264664464660020026eacc338040108966002003100389919869009ba7330d201375200a661a402619e02002661a40261a00200297ae03300300330d40100230d2010014340046eb8c32804004cc00c00cc33c04008c334040050cb01112cc00400629422b30013371e6eb8c33004dd61866008008074528c4cc008008c334040050c6012194028998648080119802002000c4cc0100100050c401186400800986480800a18c0284f80a1880230c501001430c04646600200203a44b30010018a5eb8226644b3001323300100132330010013756619402619602618e026ea8c32804c32c04c31c04dd5002112cc004006297ae0899199119198008009bab30cc010042259800800c400e264661a0026e9ccc34004dd480299868009866808009986800986700800a5eb80cc00c00cc34804008c340040050ce011bae30c8010013300300330cd0100230cb0100143240444b30010018a508acc004cdc79bae30ca01375861940200201914a313300200230cb0100143100486400a26618e0200466008008003133004004001430804618c02002618e0200286200a1380284000a13802861008dd6800c26c050c501186100800a1800230c20100284c80c264061320309901430c0461800200285f008dd7000985f8080121800230bd0100142ec046172026ea80061280285b00a128030940184a00c250050be01192cc004c22004c2e004dd5000c4c2f004c2e404dd5000c54cc2dc052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642d8046176026178026178026170026ea8c2ec04c2f004c2e004dd5000c248050b901185d00800a170023232330010010132259800800c52f5c11332259800acc004cdd7985f00985d809baa30be0130bf0130bb01375400400b1323300100132330010013756618002618202617a026ea8c30004c30404c2f404dd5002112cc004006297ae0899199119198008009bab30c2010042259800800c400e2646618c026e9ccc31804dd480299863009861808009986300986200800a5eb80cc00c00cc32004008c318040050c4011bae30be010013300300330c30100230c10100142fc0444b30010018a508acc004cdc79bae30c001375861800200201114a313300200230c10100142e80485f00a29410b80144cc2f404008cc01001000626600800800285c008c2f004004c2f4040050ba0118348008109b012136021808808a610a026ea812522259800982d800c4c9660020030608992cc0040062b3001308f010028cc0040060090614129061423005061830c1860c2848008c2340400508b011844809baa04c8acc004c168006264b300100183044c966002003061830c1860c31332259800800c18e264b3001001832419226644b300100183344c966002003067899912cc0040060d313259800800c56600261300200513303a006225980080144cc0f0014896600200519800802c0460dc809226464b300100183841c20e1070899912cc0040060e50728992cc0040060e713259800800c1d20e907483a44cc89660020030768992cc0040060ef07783bc1de264b300130a6010038980598530080641e10a3011bae001429804614602002850808dd700098510080121460230a0010014278046eb00060e50724284046eb8004c2680400909f01184c00800984d808012132028992cc0040060db06d836c1b626460066138020086eb800509c01184c80801212e02835212a0283541aa0d506a426404612c0200284a008dd5800984a80801419e0cf067425804612602002848808dd600098490080141920c8849808c2400400508e011bae001308f01002424004611a02002845808c22404dd5026456600260b000313259800800c182264b3001001830c1860c3061899912cc0040060c713259800800c1920c91332259800800c19a264b3001001833c4cc89660020030698992cc004006264b3001001835c4c966002003159800984d0080144cc0f0020896600200513303e007225980080146600200f132598009836800c4c9660020030728992cc0040062b300130a1010028cc00400602d073405d073427805073839c1ce0e6851008c27c0400509d01184d809baa0068acc004c1b00062b3001309b01375400d014838a13802838a130024260046132026ea80160e080a226464b300100183941ca0e5072899912cc0040060e90748992cc0040060eb13259800800c1da0ed07683b44cc89660020030788992cc0040060f307983cc1e6264b300130a8010038980598540080641e90a5011bae00142a004614a02002851808dd7000985200801214a0230a2010014280046eb00060e9074428c046eb8004c270040090a101184d00800984e808012136028992cc0040060df06f837c1be2646006613c020086eb800509e01184d80801213202836212e0283641b20d906c426c0461300200284b008c2600400a0d506a83541a909901184b00800a128023756002612a02005067833c19d09601184980800a1220237580026124020050648322126023090010014238046eb8004c23c0400909001184680800a11602308901375409905f4218048430090860120b905c82e417108b01088c8ca6002003480020068008888c8c9660020071489200000000000000000000000000000000000000000000000000000000000000000008992cc00400626464b3001305e0018994c0040126eb4c240040066eb8c24004c244040050051846009baa0028acc004c1740062646607a66e2cdd69848009846809baa001375c60b6611a026ea8004dd7182d1846809baa001308f01309001308c0137540051323303d33023375c6120020020106eb8c24004c24404004c24004c23004dd50012112024224046114026ea8004c2340401226464b3001305e0018994c0040126eb4c240040066eb8c24004c244040050051846009baa0028acc004c17400626465300100b804c007300100a800c01500a4c24404c2480400901018031bad309001001308c01375400513233223322980080740320039800806c006010806a60c266126026ea0cc0f8008030cc24c04dd4998138010009984980984a00984a8080225eb810131bae3092010023008001309101001375a6120020026118026ea800908901211202308a013754002611a02008845808c2340400d08a01111194c00402600f001cc0040220030044021002403c60080046e00c0cc008dca0011111991194c004006900040110011112cc0040062660726603e00a004009132332259800982f00144c8ca6002015007800e600201100198490080320109bae309101309201002404460046eb4c24004004c23004dd5001c56600260ba005132329800805401e0039800804400661240200c80426122026124020048080c008dd69848008009846009baa00389919914c004dd71849008014c01000661260200e9114c00403a017002cc00403200500140313062330940137506607e006607600466128026ea4cc0a000c008cc25004c25404c258040152f5c080a06122020026eb4c24004004c23004dd5001a112024224046112026ea8004dc0181b001984600800a1140237280066e500081164104820888c966002602e60886ea8006264b30010018acc004c060c114dd5000c4c9660020030208992cc004006043021810c08626644b3001001811c4c96600200302481240920491332259800800c09a264b30010018992cc00400605113259800800c0a6053029814c4cc896600200302b8992cc00400605902c81640b226644b300100181744c96600200313259800800c0c2264b3001001818c0c6063031899912cc00400606713259800800c4c9660020030358992cc00400606d03681b40da26644b300100181c44c96600200303981cc0e60731332259800800c0ee264b300100181e40f207903c899912cc00400607d13259800800c0fe07f03f81fc4c96600260d60071980080d46600202519800806c408a080813a080813a08081320808340dd7000a0d6306800141986eb8004c19c0090681832800a0c6375c00260c80048328c1880050601bae0013061002418860be00282e8c17c00a06903481a40d1060182e800a0b6375c00260b800482e8c168005058182d00140be05f02f817a0b6305800141586eb8004c15c009058182a800a0a6375c00260a800482a8c1480050501829001409e04f027813a0a6305000141386eb8004c13c0090501826800a096375c00260980048268c12800504818231baa00180fa08680fc07e03f01f412c6464b300130190018a99822a481274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0600062a6608a921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168982518239baa00241108220c114dd5000980918229baa3013304537546090608a6ea80062a660869201cd65787065637420536f6d65286465785f6f726465725f626f6f6b5f7265665f696e70757429203d0a20202020696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206465785f6f726465725f626f6f6b5f746f6b656e2c20222229203d3d20310a202020202020202020207d2c0a20202020202020202900164108660120044602c64b300130173045375400314800226eb4c124c118dd5000a0863259800980b98229baa0018a6103d87a8000899198008009bab304a3047375400444b30010018a6103d87a8000899192cc004c0780062b3001301d0018980d19826182500125eb82298103d87a8000411d133004004304e003411c6eb8c120004c12c00504920863300b37566026608a6ea8c04cc114dd500080118209baa0042223259800980b800c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009827001c66002009008803a016803a096375c0028270c12c0050491825801401200900480220983049001411c608a6ea80122b300130160018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b3001304e0038cc004012011007402d007412c6eb800504e1825800a092304b0028024012009004413060920028238c114dd50024566002602800313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002609c00719800802402200e805a00e8258dd7000a09c304b0014124609600500480240120088260c12400504718229baa004801208441088210c10cdd500188a4d15330294911856616c696461746f722072657475726e65642066616c7365001365640a01", + "hash": "34287f56be7722bfbca67475a01e7eec6e15a3dc668f7941430ac130" }, { "title": "hydra_account/core.hydra_account.withdraw", "redeemer": { "title": "redeemer", "schema": { - "$ref": "#/definitions/hydra_dex~1types~1HydraAccountOperation" + "$ref": "#/definitions/Data" } }, "parameters": [ @@ -760,8 +760,8 @@ } } ], - "compiledCode": "59801f010100229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0024888888888a60022a6600692012e6578706563742061737365745f6c6973743a204d56616c7565203d20646573657269616c697365645f76616c756500168a99801a4949657870656374206f75747075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a494665787065637420696e7075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a493e657870656374206f75747075745f646174756d3a20557365724163636f756e74203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a493b65787065637420696e7075745f646174756d3a20557365724163636f756e74203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492a657870656374206163636f756e743a20557365724163636f756e74203d206f75747075745f646174756d00168a99801a494a657870656374206f75747075745f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a497b657870656374204465784163636f756e7442616c616e6365446174756d207b0a202020206163636f756e745f62616c616e63655f6d65726b6c655f726f6f743a20696e7075745f6d65726b6c655f726f6f742c0a20207d3a204465784163636f756e7442616c616e6365446174756d203d20747265655f726f6f7400168a99801a495b657870656374205472616e73666572496e74656e74207b20746f2c20616d6f756e745f6c323a207472616e73666572616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a496a657870656374204d6173746572496e74656e74207b206163636f756e743a2066726f6d2c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495f6578706563742043616e63656c5769746864726177616c496e74656e74207b20616d6f756e745f6c313a207769746864726177616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a4941657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d206465785f6163636f756e745f62616c616e63655f6f75747075747300168a99801a493f657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d206465785f6163636f756e745f62616c616e63655f696e7075747300168a99801a49e7657870656374205b6665655f6f75747075745d203d0a202020202020202020206f746865725f6f7574707574730a2020202020202020202020207c3e206c6973742e66696c746572280a202020202020202020202020202020206372656174655f6163636f756e745f6f7574707574735f66696c746572280a2020202020202020202020202020202020206665655f6163636f756e742c0a20202020202020202020202020202020202068796472615f6163636f756e745f7363726970745f686173682c0a20202020202020202020202020202020292c0a20202020202020202020202020202900168a99801a498b657870656374205769746864726177616c496e74656e74207b0a20202020616d6f756e745f6c313a207769746864726177616c5f616d6f756e745f7261772c0a202020207769746864726177616c5f6665655f6c313a207769746864726177616c5f6665655f7261772c0a20207d3a2048796472614163636f756e74496e74656e74203d20696e74656e7400168a99801a4964657870656374204d6173746572496e74656e74207b206163636f756e742c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a498c657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c696379280a202020202020696e707574732c0a20202020202068796472615f757365725f696e74656e745f616464726573732c0a20202020202068796472615f757365725f696e74656e745f7363726970745f686173682c0a202020202900168a99801a494e657870656374206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a494365787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f6f75747075742e646174756d00168a99801a499d657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d0a202020206f7574707574735f61745f77697468280a2020202020206f7574707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a494c65787065637420696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f646174756d00168a99801a499a657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d0a20202020696e707574735f61745f77697468280a202020202020696e707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a4929657870656374206163636f756e743a20557365724163636f756e74203d20696e7075745f646174756d00168a99801a4958657870656374206465785f6f726465725f626f6f6b5f696e7075745f646174756d3a204465784f72646572426f6f6b446174756d203d0a202020206465785f6f726465725f626f6f6b5f7265665f696e7075745f6461746100168a99801a491e72656465656d65723a2048796472614163636f756e7452656465656d657200168a99801a491f72656465656d65723a2048796472614163636f756e744f7065726174696f6e0016488888888888888888888888889660033001301f375404b3722911009b8f4881009b87480026e1d20029ba5480026e1d2004918119812000c8c08cc090c0900066e9520024888888888a6002605a015302c00a91919800800801112cc004006297adef6c608994c004dd71816000cdd59816800cc0c4009222598009808001c566002601e00710018802a05a89981919bb037520066e98008cc01801800502d0c0bc00502d4888c966002601600313259800800c00e264b300100180240120090048992cc004c0d000e00d00540c46eb80050341818800a05e302d37540091598009805000c4c9660020030038992cc0040060090048024012264b3001303400380340150311bae00140d060620028178c0b4dd5002400902a2054302b37540072232330010010032259800800c5300103d87a8000899192cc004cdc8802800c56600266e3c0140062601666062605e00497ae08a60103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e488c8cc00400400c896600200314c0103d87a80008992cc004c010006260146606000297ae089980180198190012056303000140b922259800801452844ca600264b3001300c302d37540031375a605c60626eacc0c4c0b8dd5000c5200040ac6060003375e6060606200337560069112cc0040062b30013002006899802801a400114a0816a264b30013375e60600029810140008acc004cc018010dd69818981a1bab3031001898019ba630350028a5040b91598009980300224001130030078a5040b88170c0cc0050310ca60020030049119818801198189ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0bc0066eacc0c000660680069112cc004c04c00e2b3001301200389980298079981a9ba60024bd70000c4cc01530103d87a800000640c119800803c006446600e0046606e66ec0dd48029ba6004001401c81806064004818229422942294103124444445300130330079819981a003c88966002602260646ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002607c00519800801c66002003009804201c804201c8042076804402201100840fc607800281d0c0f000a00d006803401903d181d000a070375c002607200481d0c0dc00503518199baa003800a0609112cc004c044c0c8dd5001c4c9660020030028992cc004006264b300100180244c966002003159800981d80146600200713259800980b000c4c9660020030078992cc0040062b3001303e0028992cc004c064006264b300100180544c966002003159800982080146600200300c805a022805a07c805c02e01700b4108607e00281e8c0ecdd50014566002603000313259800800c02a264b3001001805c02e0171332259800800c036264b3001001807403a01d1332259800800c042264b3001001808c046023132598009824001c04e0248228dd6800c0450481822800a086375a002608800500e411460840028200dd68009820801402d042181f800a07a303b375400500940e081c0c0e4dd5000c02103b4022011008804207e303c00140e860706ea800a2b300130150018acc004c0e0dd5001401e00c81ca00c81a9035181b1baa001802a016802a070802c01600b00540f0607200281b8c0e400a007003801c00d03a181b800a06a3033375400700140c091111919912cc004c0500062646644b300100a899912cc004c068006264b300100181044c9660026084005004810a07e304000140f860786ea80322b300130190018acc004c0f0dd5006400a03e81ea2b300130170018acc004c0f0dd5006400a03e81ea03e81c9039207213232332298009bab3041002982118211821182118211821182118211821000cdd71820800cc0f4dd500724444b300130200018acc004c8c8cc004004018896600200314a115980099baf003304430480018a518998010011824800a0844118603466088608a608c00697ae08a518a998202494e7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6f726465725f626f6f6b5f7363726970745f6861736829203f2046616c73650014a081fa2b3001301f0018acc004c8c8cc004004018896600200314a115980099baf003304430480018a518998010011824800a0844118603466088608a00697ae08a518a9982024814b7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6163636f756e745f7363726970745f6861736829203f2046616c73650014a081fa264b300130213042375400313259800acc00566003300130193756603c60886ea8c078c110dd5182398221baa002a60101a0009119b87002001405514a3153304249011369735f6e6f5f76616c7565203f2046616c73650014a0820a29462b300159800981118219baa00b8a508a51410514a315330424911369735f6e6f5f646174756d203f2046616c73650014a08209041454cc1092410f746f646f3a2072656d6f766520697400159800800c528c54cc1092411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0820a294104119198008009bac3047304830480082259800800c528456600266e3cdd71824000802c528c4cc008008c124005042208c8a99820a4813465787065637420536f6d65286f776e5f696e70757429203d20696e70757473207c3e2066696e645f696e70757428696e7075742900164100660286eb0c1140208cdd7982318219baa00100b40fc81f86080608060806080608000260786ea8cc01cdd6181f80081c181f800981d1baa0103039375401501d80ec07603a81f8c0ec004c0ecc0f0004c0dcdd5003456600260240031325980080446600244646600200200644660060026004005370e90054888c966002603400313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f0078992cc004c11800e013008410c6eb80050461821800a082375a0026084005004410c608000281f0c0f0dd50024566002603200313259800800c00e264b300100180240120091332259800800c01a264b30010018acc004c11400a2b3001301f3040375400313259800800c022264b3001001804c0260131332259800800c02e264b3001001806403201900c899912cc00400601d13259800800c03e01f00f807c4c966002609c0070118082096375c0028270c12c0050491bae001304a002412c60900028230dd6800982380140250481822800a0863041375400300740f90074109007803c01e00e8230c10c0050411bad00130420028022086304000140f860786ea80122b300130170018992cc00400600713259800800c012009004899912cc00400600d13259800800c01e00f007803c4cc89660020030098992cc00400601500a805402a264b30013049003806402d0461bae0014124608c0028220dd70009822801208c304300141046eb4004c10800a0088218c10000503e181e1baa004801207240e481c8c0e8dd5001cc0dcdd500424444646644b3001301d0048992cc00400604513259800800c566002608a00519800800c00e046802a0468212047023811c08d0461821800a082303f375401f159800980e00244c9660020030228992cc0040062b300130450028cc00400600702340150234109023811c08e0468230c10c005041181f9baa00f8acc004c068012264b300100181144c9660020031598009822801466002003003811a01a811a084811c08e047023411860860028208c0fcdd5007c56600266e1d20060048acc004c0fcdd5007c00604282022b30013370e900400244c9660020030228992cc0040062b300130450028cc00400600702340110234109023811c08e0468230c10c005041181f9baa00f8acc004c018012264b300100181144c9660020031598009822801466002003003811a008811a084811c08e047023411860860028208c0fcdd5007c08503c207840f081e103c207822259800980f181f9baa0038992cc00400600513259800800c4c9660020030048992cc00400600b132598009824801c4cc8966002604a00313259800800c026264b30010018acc004c13400a26530010018014015001111192cc004c0ac006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c4c96600260ae00713301b0012259800801402a26464b300100180c40620311332259800800c6600202100189802982e803202080d406a03501a41786eb4004c15c00a03082e0c154004c16000905640510541bab001809c04e02682b8c1500050521bae0013053002415060a20028278c134dd5001c566002605400313259800800c03e264b30010018084042021010899912cc00400602513259800800c04e027013809c4cc89660020030158992cc00400602d01680b405a264b3001305a003805c05d0571bae001416860ae00282a8dd7000982b00120ae305400141486eb8004c14c0090541828800a09e304d375400700e41288250c12cdd5001402904a402a01500a805209c304b0014124608e6ea801a2b300130240018992cc00400601313259800800c02a015132598009827001c4cc04800489660020050078992cc00400633001001898011828801c039011403a01d00e80720a4304f002413500b412c6eb000601500a413860960028248c11cdd50034021044208813300d0012259800801402626464b3001001805402a01500a899912cc00400601900c8992cc00400601b13259800800c03a01d00e80744cc89660020030108992cc004006023011808c046264b3001305500389805982a80640490521bae001415460a40028280dd7000982880120a4304f00141346eb000601900c41406eb8004c12400904e1823800982500120903044375400900641186eac00600b005802a09230460014110608c005003801c00e0068238c11000504218201baa003800a07a19800912cc00400629344c966002003149a264b3001337206eb8c100c11000cdd71820000c4cc010010cc10c004c11400a2a6607e921326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f72646572001640f860860028208c10c00504048888c8cc0040040148966002003133045337606ea4014dd300225eb7bdb1822653001375c608600337566088003304800248896600266e4002400e26609266ec0dd48049ba60080058acc004cdc7804801c4c966002604c608e6ea800626609466ec0dd4805182598241baa0010028801208a9800804c022004803a26609266ec0dd48019ba60023300600600141108220608c00282224444646600200200a44b300100189982299bb0375200a6ea00112f5bded8c113298009bae30430019bad304400198240012444b300133720012007133049337606ea4024dd4004002c56600266e3c02400e264b300130263047375400313304a337606ea4028c12cc120dd5000801440090454c004026011002401d133049337606ea400cdd400119803003000a088411030460014111259800800c528c528207e91192cc004c074c0fcdd5000c52f5bded8c113756608660806ea800503d19809001000c888c8cc004004010896600200310048994c004dd71821000cdd69821800ccc00c00cc11c0090041822800a086912cc004006297ae0899820981f1821000998010011821800a080912cc004c070c0f8dd5000c4c8cc108cdd8182180098219822000a5eb7bdb180c10cc0fcdd5000c4c8cc004004c8cc004004dd59822182298209baa0032259800800c52f5c113304430423045001330020023046001410c44b30010018a5eb7bdb1822646644660040046600e00e00244b30010018801c4cc118c11c004cc008008c1200050451822801198010011822800a08440f12329800800c00a97ae04004444b30010028800c660020073045002998219822001000a0064109223304137520020052259800980e99b8600148012266e0ccdc700119b83001480112020899b863371c00466e0c00520044808103c48a6002003337026e34008006004b8c48896600266e2400920008800c6600200733708004900a4cdc599b803370a004900a240c0002801903d488dca19b8a0020019b804800a6e05200091111919800800802912cc004006200b13259800800c4cc010c11c00801a26600a608e004660060060028228c11c0050444dc0240032301a33040301633040375200297ae0330404c0103d87a80004bd704888c8cc004004010896600200310048998019822800998010011823000a0869112cc004c078c0fcdd5001c4c9660020030028992cc004006007003801c00e264b30013047003802c0110441bae001411c60880028210c100dd5001c00503d4dc02400737009003cdc02401f25980099b87371a0029020440062a6607892138657870656374206279746561727261792e6c656e67746828726f6f7429203d3d20626c616b6532625f3235365f6469676573745f73697a65001640ed303c375401b22225980099b88002480c22600200515980099b87002480c2266008900111801000c56600266e20009203889980199b8e488103020408003370000490189180119bca4a2003124bded8c10140000101200040f881f103e4dc3a41fc0722337600046ea0005222222222222222222222222222229800980e80ec888a6002009003801488a6002007001801200840813017017980b00b4c044046444b30010028cc00400e60300034bd7020068992cc004006264b30010038800c6600200b33019301a003001a5eb8100520c0375c60c2007198008024c18800666030004660286eb8c18400cdd71830800a008417c60c200482f244b3001303a3370c002900244cdc5a41fc066602800466e0c0052004899b8b48000cdc59980a8010009980a00119b833011001480110594888c8cc00400400c896600266e2400c0062910100899b8b3301800500133002002301400141712225980099b8900348002266026004003133013001002416922329800800c00e00480088896600200510018994c00401260c800798008014dd7182f800cdd59830000c888c966002604800314c0103d87a800089820198331ba60014bd7020c2329800800c00e00480088896600200510018994c00401260d600798008014dd71833000cdd69833800c888c966002609200314c103d87a800089823998369ba80014bd7020d0337000040028141004183480120ce40888020c18800906048c8cc004004008896600200314bd6f7b63044c8cc180cdd8182e8009ba63233001001375660be00444b30010018a5eb7bdb182264660c666ec0c180004dd4180a9bad3061001330030033065002306300141846600600660c400460c000282f2444b30013375e60c060ba6ea8c0dcc174dd5000980700144c96600200319800800c4cdd7800802415502a41560ab05582aa0c63259800981c982e9baa00189830982f1baa0018a9982e2493265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016416c60c060c260c260ba6ea8c180c184c174dd5000c52820b49112cc004cdd79830182e9baa001300e0028992cc00400633001001899baf00100482b205482b415a0ad056418c64b30013039305d375400313061305e3754003153305c49012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016416c60c060c260c260ba6ea8006294105a48966002003148002260226600400460c000282ea44444653001001801c0090011112cc004cdc480124001130014bd70448c8ca600200d30170059180299834001000cdd69832801200c30630019800804c022002803905f48888c8cc00400400888cc01920022598009804800c4c0092f5c1123232980080348c018cc19c0080066eb4c1900090061831000cc00402200f3017001401882f244453001004801c00a46600800246006002803922222222222222222980091112cc004c134006200919800802400e6464004602c002660e266ec0dd48011ba80014bd6f7b6304888c966002606600314c103d87a8000898279983a9ba60014bd7020e0980080140160092223259800982a000c530103d87a8000898291983c1ba80014bd7020e633700002004819901420d89806006488c8cc00400400c8966002609a0031337149110130000038acc004cdc4000a40011337149101012d0033002002302300189980899b8400148050cdc599b803370a002900a240c0006836106c488896600266e240112002899812cc00401200700140340051330250029800980e802400e002806906c488896600266e2001120048acc004cdc4001240091330259800802400e00280692201200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100899812cc0040120074892000000000000000000000000000000000000000000000000000000000000000000040353001301d002800d22120000000000000000000000000000000000000000000000000000000000000000000403483622b300133712900200144cc095221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f9761009800980e802400e002806a26604b3001002800d2212000000000000000000000000000000000000000000000000000000000000000000040353001301d004801d221200000000000000000000000000000000000000000000000000000000000000000004034836106c4c0100124466002444646466ec0c8dd39983a98390009983a9839800a5eb80cdd8183880118388009839000cc00401a44003004801cdd69838800a00c9800802c88006007002800a00a2233002480088c96600266e2400520048acc004c13c00633001004801c00a460326ea000501a4566002609c00319800802400e66e00009203f9180c9ba830243026001406915980099b87002482f80626466002002460346ea400488cc0192002259800980e000c4c0092201008cc00401e00d33700002903fc8cc0100108c010cdc5001000a01441c519800802400e66e00009207f9180c9ba9001401c837106e20dc8acc004cdc3800a401919800802400e66e0000920ff02919802a40044b30013370e004906600c492f7b63001014000010120008992cc004cdc38012417c0519800803c01a66012012440032301c3374a004002805a330010078034cdc0001241fe0329800804401e66014014440030019180e99ba5003001403480e90712cc004cdc4a41002800513370066e0000920ff134803a266e0000920f10141c0838101a456600266e1c00520088acc004cdc38012417c0519800802400e6600c00c4400323019374e002804233001004801ccdc0001241fe0329800802c0126600e00e440030019180d1ba7001402880d106e4566002607000315980099b87002483f80a2646466002002460366e9800488cc01d2002259800980e800c4c0092f5bded8c1123232980080348c018cc1ec0080066eb4c1e00090061919bb0307b001307b307c001375860ec00330010098044c0ac00500520e433006006220028cc00401200733700004905f8148c8ca60020030039180e1ba60014004444b300133712004900044c0052f5bded8c112323298008034c0ac0164600a660f8004003375a60f20048030c8cdd8183e000983e183e8009bac30770019800805402600280290731980380391001203441b9124bded8c010140000101200041b8837106e20dc33706002902048c8cc004004008896600200314bd6f7b63044ca60026eb8c1b80066eacc1bc0066600600660e60049112cc00400a2a660e092124657870656374205061697228702c205b5f2c202e2e5d206173207829203d20696e6e657200168cc004006007323200432330010010042259800800c5268992cc0040062b30013004375a60ec60f2005149a2a660e892011f76616c756520646f65736e2774207361746973667920707265646963617465001641cd133225980099b90375c60ee0046eb8c1dc0062b30013006375a60f00051330050053307a001307c0038a9983b2491f76616c756520646f65736e2774207361746973667920707265646963617465001641d51533076491276b65797320696e207061697273206172656e277420696e20617363656e64696e67206f72646572001641d460f200460f200283b8c1e400507614c004c14400694294507048894cc1cd2401234475706c696361746520706f6c69637920696e20746865206173736574206c6973742e0016405c839860e200283792222222298009114c004cc0d400c00a97adef6c60911192cc004c160c1e4dd5000c4ca6002007375c60fc003375c60fc60fe00300440406eb0c1f4c1e8dd5000c54cc1e124121546f6b656e2068617368206e6f7420666f756e6420696e20746f6b656e206d6170001641dc646600200200a44b30010018a60103d87a80008992cc004cdc78031bae307b0018982c1983f183e000a5eb8226600600661000200483c8c1f800507c2068911919800800980d001912cc004006297adef6c60899912cc004c8cc004004018896600200314a115980099b8f375c60fc00200914a3133002002307f00141e083e23300133038006002800c88a6002003005801c009011206e8800a0ec375c60f40026600400460f600283c244464b30010038991919911980700119b8a488101280059800800c4cdc52441035b5d2900006899b8a489035b5f20009800800ccdc52441025d2900006914c00402a00530070014029229800805400a002805102e20f85980099b880014803a266e0120f2010018acc004cdc4000a41000513370066e01208014001480362c83b10761bac3079002375a60ee0026466ec0dd4183b8009ba73078001375400713259800800c4cdc52441027b7d00003899b8a489037b5f20003232330010010032259800800c400e264b30010018994c00402a60f8003337149101023a200098008054c1f400600a805100a183f80144ca6002015307c00199b8a489023a200098008054c1f4006600e66008008004805100a183f80120fa307f00141f066e29220102207d0000341e46eac00e264b3001001899b8a489025b5d00003899b8a489035b5f20009800800ccdc52441015d00003914c00401e0053004001401d229800803c00a002803902b20f2375800713300a375a0060051323371491102682700329800800cc0acdc68014cdc52450127000044004444b300133710004900044006264664530010069818002ccdc599b800025980099b88002480522903045206e41ec66e2ccdc0000acc004cdc4000a40291481822903720f6004401866e0c00520203370c002901019b8e00400241e06eb800d07c1b8a4881022c2000911112cc004cdc4802a400d13302e9800802c012005001402800713302e00398009812802c012005001402883aa4444b3001337100089004456600266e200092008899816cc004012007002800a01048812085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100899816cc004012007489200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402530013024002800d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483a22b300133712900400144cc0b52212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b10098009812002400e6048005001402113302d980080140069101200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402530013024004801d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483a1074488c8cc00400400c896600200314bd6f7b63044c8ca60026eacc1e400a6600800860fa0072229800800c022b300159800982d80244c16c00e2941079452210089b943371400800683ca00480890371bae3077001307a00141e130020024888888a6002600a00b22222330359800802c012606200680f260026607000a60620079800a400148102002b8c66002902052040800ae319800a41000348102002b8c66002906000d2040800ae30911112cc004cdc4802a401d13303a9800802c01e007002800a01c00489981d0024c004c0c001600f003801400500e210202488888c96600330013370e0026eb4c20c04c20004dd5001528528a0fa89981b4c00401a00b3032004407c6644b3001337100069008456600266e20009201089981c4c00400e00b002800a016488120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0089981c4c00400e00b4892085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302e002800d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403083fa2b300133712900800144cc0e122120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0098009817001c016605c005001402d1330389800801400691012085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302e003802d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403083f907f1bad30830130800137540046606c6eb8c168c20004dd50011bae30593080013754005153307e49120657870656374206272616e636820213d206e65696768626f722e6e6962626c65001641f46607000a606200723259800982d183d9baa0018992cc0040060f113233046001225980080144c96600266e3cdd99ba60010078800c54cc1fd241306578706563742063626f722e73657269616c6973652876616c756529203d3d2073657269616c697365645f76616c7565001641f8601c0071323259800800c1f60fb07d83ec4cc896600200307f8998261bab001225980080144c01cc2280402226464b300100184180c20c061060308301899912cc00400610a030850184280c4c8c018c23c0401cdd6800c2140508f011bae001308801002423404610c0200261120200484380a0ff07f83fa11202375c002610402004843808c20004004c20c04009081011bab00183c41e20f0841008c1fcc1f0dd5000c54cc1e924014465787065637420536f6d6528646573657269616c697365645f76616c756529203d2063626f722e646573657269616c6973652873657269616c697365645f76616c756529001641e464b3001305a0018a6103d87a80008992cc006600260b66eb4c1f400694294507a4530103d87a80008982c9983f983e000a5eb8107a4c00488006444b3001337120029000452f7b63010140000101200089980119b8e0053370200800266e0400400d07c48896600266e2400520008a5ef6c601014000010120008998014c004cdc0802000c00e00ab8c19b8100100341f1001400c83c8dc6800a44453001223300122225980099b870024808220091325980098311842009baa0018cc00401e440053303f0054881200000000000000000000000000000000000000000000000000000000000000000008024c0e800e004803a26464b30013371000200b15330850149012e696e76616c696420747265652c206368696c6472656e206d75737420626520736f7274656420627920696e64657800168992cc004c198c21c04dd5000c56600266e1c01800a3300100a910014cc108022600201522001984400801ccdc5002cc00528d20028032f2480526eacc22c04c22004dd5000cc0f401a00a80523300100a910014cc108021220120000000000000000000000000000000000000000000000000000000000000000000803cc0f401a00a805108501454cc218052412a65787065637420536f6d65287461696c5f6e6f64657329203d206c6973742e7461696c286e6f646573290016421404b30010068a6103d87a80008983199844809ba6308b010064bd702110024210046eb4c21404004c8cdd81844808009844809845008009bac30880130850137540028410096600200714c103d87a8000898301984300991ba7330870130840100133087013085010014bd70184380801a5eb8108501210202225980098301840809baa002899191981d000992cc0040062a661060292012e696e76616c6964206368696c64206861736865732c206d7573742062652061206e6f6e2d656d707479206c69737400168acc004c2240400626eb8c2200400626603200297ae0421804843008c0fe600200d22002a5eb826eacc21c04c2200400a90004cdc5001800a00c375c610c020026104026ea800a264646644b3001980099b8f37280040034a14a284180a2a661080266e59241056b65793a20003732660186ea40092201001533084013372c920106706174683a20003732660186ea40052201001533084014912d696e76616c696420747265652c2070617468206973206e6f74207468652068617368206f6620746865206b65790016899192cc004cdc7800803c4cc0f8cc0a000c008dca1bae308b01308c010058a998430099b964910e706174685f6e6962626c65733a200037326601c6ea40052201001533086013372c9201107072656669785f6e6962626c65733a200037326601c6ea401d22010015330860149128696e76616c696420747265652c2070726566697820646f6573206e6f74206d61746368207061746800164214053001002a400100140986e34015083011bae308701001375c610e02004610e020026104026ea800907f488c8ca6002003480020068008888c8c96600200714881200000000000000000000000000000000000000000000000000000000000000000008992cc00400626464b300130670018994c0040126eb4c234040066eb8c23404c238040050051844809baa0028acc004c1980062646608066e2cdd69846809845009baa001375c60c86114026ea8004dd718319845009baa001308c01308d013089013754005132330403302a375c611a020020106eb8c23404c23804004c23404c22404dd5001210c02421804610e026ea8004c2280401226464b300130670018994c0040126eb4c234040066eb8c23404c238040050051844809baa0028acc004c19800626465300100b804c007300100a800c01500a4c23804c23c0400900f18031bad308d01001308901375400513233223322980080740320039800806c006010806a60d466120026ea0cc11c008030cc24004dd499817001000998480098488098490080225eb810121bae308f010023008001308e01001375a611a020026112026ea800908601210c023087013754002611402008844008c2280400d08701111194c00402600f001cc0040220030044021002403860080046e00c0e4008dca0014888cc88ca60020034800200880088896600200313303c3302600500200489919912cc004c19c00a26465300100a803c0073001008800cc23c040190084dd718470098478080120203002375a611a020026112026ea800e2b30013066002899194c00402a00f001cc004022003308f010064021308e01308f01002403c60046eb4c23404004c22404dd5001c4c8cc8a60026eb8c23c0400a6008003309001007488a600201d00b80166002019002800a018983599848809ba8330480033041002330910137526605e006004661220261240261260200a97ae0404c308e01001375a611a020026112026ea800d08601210c0230860137540026e00c0f000cc22404005087011b940033728004911194c004a600244003001a441004009222225980099b8f9800802400a006803801633001004800c00d007454cc2140524013465787065637420696e636c7564696e67286b65792c206f6c645f76616c75652c2070726f6f6629203d3d2073656c662e726f6f74001642100522225980099b8f330070030010048cc00400e0050014019153308401490129657870656374206578636c7564696e67286b65792c2070726f6f6629203d3d2073656c662e726f6f740016420c049112cc004c18c0be2646466453001308d01308d010029bac308c01002984680984680800cdd7184600800a444530013756612002009375861200261220261220261220261220200930910130910100298480080124444646530013097010019bae3096010019bac30960100e488a60026eb8c2640400e6eb8c26404c26804c2680400e64646600200200644b30010018a5eb8226644b30015980099baf309e01309b013754613c02613e026136026ea80080162646600200264660020026eacc28004c28404c27404dd5185000985080984e809baa0042259800800c52f5c113233223233001001375661440200844b30010018801c4c8cc29804dd399853009ba9005330a60130a301001330a60130a4010014bd7019801801985400801185300800a14802375c613c020026600600661460200461420200284f808896600200314a115980099b8f375c6140026eb0c28004004026294626600400461420200284d00909e01452821300289984e8080119802002000c4cc01001000509801184e00800984e80800a134023047002984c80984b009baa0669bae309901007984c80802a444444b300100484380c4c96600261420200b13259800800c56600260f6613a026ea8006264b300100184580c4c96600200313259800800c23406264b300130a6010028cc00400e2b30010018acc004c20004c28404dd5000c4c966002003090018992cc004006122031332259800800c24c06264b300100184a00c4c966002615802007133070004225980080144cc1c800c896600200519800981d002cc8c8cc004004064896600200314bd7081018000810180008101800044cc8966002600a0051330b301374e66166020046eb0c2d004004cc2cc04c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c1159800acc004cdd7985a009858809baa30b40130b50130b101375400402d1323300100132330010013756616c02616e026166026ea8c2d804c2dc04c2cc04dd5002112cc004006297ae0899199119198008009bab30b8010042259800800c400e26466178026e9ccc2f004dd48029985e00985c808009985e00985d00800a5eb80cc00c00cc2f804008c2f0040050ba011bae30b4010013300300330b90100230b70100142d40444b30010018a508acc004cdc79bae30b6013758616c0200203314a313300200230b70100142c00485a00a29410ae0144cc2cc04c2d004004cc2cc04dd399859808011bac30b40130b501001330b30130b40130b50130b5010014bd7044cc2cc04c2d004004cc2cc04c2d004c2d404004cc2cc04dd399859808011bac30b40130b50130b5010014bd70215c0242b80461640200266004004616602002858008cc11c03405a64646600200204844b30010018a5eb841018000810180008101800044cc8966002600a0051330b301374e66166020046eb0c2d004004cc2cc04c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c1159800acc004cdd7985a009858809baa0020168991980080099198008009bab30b60130b70130b301375400844b30010018a5eb82264664464660020026eacc2e004010896600200310038991985e009ba7330bc01375200a6617802617202002661780261740200297ae03300300330be0100230bc0100142e8046eb8c2d004004cc00c00cc2e404008c2dc040050b501112cc00400629422b30013371e6eb8c2d804dd6185b0080080cc528c4cc008008c2dc040050b0012168028a5042b8051330b30130b401001330b301374e66166020046eb0c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c11330b30130b401001330b30130b40130b501001330b301374e66166020046eb0c2d004c2d404c2d4040052f5c08570090ae0118590080099801001185980800a160023304600d016488a600266098607a016609600730b3010029bac30b201002985980800cdd6185900800a4444530013758616e020053758616e0261700200530910130443758616e026170020093758616e020089111192cc00400a1500313259800985f00801c56600200d0aa018992cc004c2fc0401e264b3001598008034528c54cc2e8052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085c80a2b3001598008024528c54cc2e80524011e69735f7769746864726177616c5f6665655f70616964203f2046616c73650014a085c80a2b300159800992cc004006330010018992cc004006330010018cc004dd7186080985f009baa0029bae30c10130be013754003376603f30bd01375404a9111192cc004c2840400a266e3e60020030039bb3374c0293758618c026186026ea80a903f002456600261400200513232332259800acc0066002660c86094002031374c6094005223370e00400284c00a29462a6618a0292011a69735f62616c616e63655f75706461746564203f2046616c73650014a086200a2b30013371f3001005803cdd6186500986580801c006004822002229462a6618a029211e69735f6e65775f62616c616e63655f636f7272656374203f2046616c73650014a086200a29410c4011bae30c801001375c6190020046190020026186026ea80aa29410c001218002306d00442e00506d42e006170030b80185c00a186023259800984c80985e809baa0018986080985f009baa0018a9985e00a4812c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642ec04618002618202618202617a026ea800e16c02836216c030b60185b00c2d8050c201192cc004c26004c2f004dd5000c4c30004c2f404dd5000c54cc2ec0524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642e804617e026180026180026178026ea8c2fc04c30004c2f004dd5001c528c54cc2e80524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a085c80a2b30015980099baf374c612202660b2660b265300100180652f5bded8c080088896600200510018cc00400e618602005329800800c00a6eacc30c04c31004c30004dd51861809862009860009baa30c3010034004444b30010028800c4c8cc8a600200d30c9010059919800800802912cc0040062661920266ec0dd48021ba60034bd6f7b63044ca60026eb8c31c040066eacc320040066198020049112cc004cdc8004001c4cc33404cdd81ba9008374c00e00b15980099b8f0080038992cc004c2a804c32c04dd5000c4cc33804cdd81ba900930cf0130cc013754002005100243240464b300159800800c528c528219a028a60103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c001182c194c0040060114bd6f7b63020022225980080144006330010039861808014ca60020030029bab30c30130c40130c0013754618602006800888966002005100189919914c00401a61920200b32330010010052259800800c4cc32404cdd81ba9004374c00697adef6c608994c004dd7186380800cdd5986400800cc330040092225980099b900080038998668099bb037520106e9801c0162b30013371e010007132598009855009865809baa0018998670099bb03752012619e026198026ea800400a2004864808c966002b30010018a518a5043340514c103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c001182c194c0040060154bd6f7b63020022225980080144006330010039861808014ca60020030029bab30c30130c40130c0013754618602006800888966002005100189919914c00401a61920200b32330010010052259800800c4cc32404cdd81ba9004374c00697adef6c608994c004dd7186380800cdd5986400800cc330040092225980099b900080038998668099bb037520106e9801c0162b30013371e010007132598009855009865809baa0018998670099bb03752012619e026198026ea800400a2004864808c966002b30010018a518a5043340514c103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c0011ba60018a518a9985d00a4812569735f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a085c80a2b300159800cc0040be6e98c160cc164c24404dd5984b00985e009baa30960130bc013754040003223370e00400284680a29462a66174029211769735f746f6b656e735f6275726e74203f2046616c73650014a085c80a2b3001323300100102f2259800800c528456600266e3cdd71860808008194528c4cc008008c308040050bb01217e028a518a9985d00a492669735f68796472615f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a085c80a29410b90145282172028a5042e40514a085c80a29410b9011848009982180601242ac050bc01185e8080321760285480a1760230bc0100242e804b30010038a518acc004c2f00400e264b300100185380c4c966002617c020051980098478099821007011cdd31847809bab30940130ba013754003223370e00400284580a1500285d808c2f0040050ba01191919800800802912cc004006297ae0899912cc004c01400a26617e020046600800800313300400400142e804617c02002617e0200285e008cc1480a008a2a6616c02920118756e6578706563746564206f74686572206f7574707574730014a085c8090b9010899192cc0040061360309b0184d80c26c0626644b300100184e80c4cc1e0dd5800912cc00400a2600e616c020111323259800800c28406142030a10185080c4cc89660020030a30185180c28c06264600c61760200e6eb40061460285d808dd7000985a0080121720230b20100130b50100242cc0509d0184e80c274050b5011bae00130ae0100242cc04615802002615e0200485680a26464b300100184c80c264061320309901899912cc00400613603133076375600244b300100289803985a0080444c8c96600200309f0184f80c27c0613e031332259800800c28406142030a1018991803185c808039bad00185080a17202375c00261640200485b808c2c004004c2cc040090b101426c061360309b0142cc046eb8004c2b0040090b10118550080098568080121560284a80a1520237560030940184a00c250050ac01185480800a14e0237560026150020050910184880c244050a901185300800a1480230a201375400308f01427c0508f0184780c23c0611e0285380a11c02837211c02851808c290040050a2011852008014230061180308c0184600a14a0230a201001428004613c026ea80061140284d80a1140308a0184500c228050a301192cc004c1e4c27404dd5000c4c28404c27804dd5000c54cc270052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016426c04614002614202614202613a026ea8c28004c28404c27404dd5000c2200509e01184f80802213a020c25804c25804c25804004c25404008308b010013087013754660a46eb0c2280400420c04c22804004c21404dd502dc4ca600253001001a5eb7bdb182446604c0046eacc18cc22404dd518319844809baa001400929800800d2f5bded8c12233026002375660c66112026ea8005002488896600266e3e6002007002800a014004899805801800c54cc220052413065787065637420696e636c7564696e67286b65792c2076616c75652c2070726f6f6629203d3d2073656c662e726f6f740016421c049112cc004c1980ce26464664530013091013091010029bac309001002984880984880984880984880800cdd7184800800a4445300137566128020093758612802612a02612a02612a02612a020093095010029bae30940100248888ca6002613402003375c613202003375861320201a9114c004dd7184e00801cdd7184e00984e80984e80801cc8c8cc00400400c896600200314bd7044cc8966002b30013375e614202613c026ea8c28404c28804c27804dd5001002c4c8cc004004c8cc004004dd59851809852009850009baa30a30130a40130a001375400844b30010018a5eb82264664464660020026eacc294040108966002003100389919854809ba7330a901375200a6615202614c020026615202614e0200297ae03300300330ab0100230a901001429c046eb8c28404004cc00c00cc29804008c290040050a201112cc00400629422b30013371e6eb8c28c04dd6185180800804c528c4cc008008c2900400509d012142028a50426c051330a00100233004004001899802002000a13602309f0100130a0010014274046094005309c0130990137540d3309c0100648888966002007089018992cc004c28c04012264b30010018acc004c1f4c27c04dd5000c4c96600200308d018992cc004006264b300100184780c4c96600261500200519800801c5660020031598009840809851809baa0018992cc00400612c0313259800800c25c06264b300130ab01003899837800912cc00400a26645300130af010029bac30ae01002985780800cdd6185700800a444530013758616402005308c01303f3758616402616602009308d01303f3758616402616602005375861640200891112cc0040061440313259800985c00801456600200b0a4018992cc004c2e40401a264b3001598008034528c54cc2d005241176e6f5f6f746865725f696e70757473203f2046616c73650014a085980a2b300159800802c528c54cc2d0052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085980a2b30015980099912cc004006330010018992cc004006330010018cc004dd7185e00985c809baa0029bae30bc0130b9013754003376603130b801375403a9111192cc004c2640400a266e3e60020030039bb3374c0113758618202617c026ea8089036002456600261360200513232332259800cc004cc17cc114004c1780326e98c11400a4466e1c0080050930144cdc7cc00401600f3758618a02618c02007001801207e0088a5042fc046eb8c30c04004dd7186180801186180800985f009baa0228a5042ec0485d808c1a00110b30141a10b30185980c2cc061660285f008c9660026128026170026ea800626178026172026ea80062a6616e029212c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642d8046176026178026178026170026ea801216202833a162030b10185880c2c4050bd011822008192cc004c24804c2d804dd5000c4c2e804c2dc04dd5000c54cc2d4052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642d004617202617402617402616c026ea8c2e404c2e804c2d804dd5001c528c54cc2d00524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a085980a2b30015980099baf374c611602660a6605e01060a460600146e9800629462a66168029212c69735f63616e63656c5f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a085980a2b300159800cc0040966e98cc14cc148c22c04dd5984800985b009baa30900130b6013754030003223370e00400284380a29462a66168029211d69735f6d696e745f76616c75655f636f7272656374203f2046616c73650014a085980a2b300132330010010252259800800c528456600266e3cdd7185d808008144528c4cc008008c2f0040050b5012172028a518a9985a00a492d69735f68796472615f63616e63656c5f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a085980a29410b30145282166028a5042cc0514a085980a29410b3011981e982180780dc294050b601185b80802a16a0285180a16a0230b60100142d004194c00404a97ae10101800081018000810180004896600260060051330ae01374e6615c020046eb0c2bc04004cc2b804c21804004cc2b804c214040052f5c1159800acc004cdd79857809856009baa30860130ac01375400401f1323300100132330010013756611002615c026ea8c22004c2b804dd5002112cc004006297ae08991991199119801001000912cc0040062007132330b701374e6616e026ea4014cc2dc04c2d004004cc2dc04c2d4040052f5c066006006617202004616e0200285a808dd59859008019bae30af010013300300330b40100230b20100142c00444b30010018a508acc004cdc79bae30b101375861620200203514a313300200230b20100142ac0485780a29410a90144cc2b804c2bc04004cc2b804dd399857008011bac308601001330ae013085010014bd7044cc2b804c2bc04004cc2b804c21804004cc2b804dd399857008011bac3085010014bd7021520242a40482d0cc110020040c8c8cc004004074896600200314bd7081018000810180008101800044cc8966002600a0051330b001374e66160020046eb0c2c404004cc2c004c2c404c2c804004cc2c004c2c404c2c804c2c8040052f5c1159800acc004cdd79858809857009baa0020118991980080099198008009bab30b30130b40130b001375400844b30010018a5eb82264664464660020026eacc2d404010896600200310038991985c809ba7330b901375200a6617202616c020026617202616e0200297ae03300300330bb0100230b90100142dc046eb8c2c404004cc00c00cc2d804008c2d0040050b201112cc00400629422b30013371e6eb8c2cc04dd618598080080e4528c4cc008008c2d0040050ad012162028a5042ac051330b00130b101001330b001374e66160020046eb0c2c404c2c804004cc2c004c2c404c2c804c2c8040052f5c11330b00130b101001330b00130b10130b201001330b001374e66160020046eb0c2c404c2c804c2c8040052f5c08558090ab0118578080099801001185800800a15a0233043008010899192cc0040061380309c0184e00c2700626644b300100184f00c4cc1d4dd5800912cc00400a2600e6166020111323259800800c28806144030a20185100c4cc89660020030a40185200c29006264600c61700200e6eb40061480285c008dd7000985880801216c0230af0100130b20100242c00509e0184f00c278050b2011bae00130ab0100242c00461520200261580200485500a13002854008dd5800c25c0612e030970142ac04615002002853008c29004dd5000c254050a10142540612a030950184a80a1520284800a0e084800a14a0230a601001429004614c0200508e0184700c2380611c02853808c290040050a2011850009baa00184600a13a0284600c230061180308c0142940464b3001307b309f013754003130a30130a0013754003153309e014913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016427404614402614602614602613e026ea8c28804c28c04c27c04dd5000c228050a001185080801a13e020c26404c26404c26404008308f01001308b013754660ac6eb0c2380400421c04c23804004c22404dd502fc4c96600260ca069132323298009bae3090013091013091013091013091013091013091013091013091013091010019848009846809baa05d98488080124446644b3001598009804984a80984b008014528c54cc240052401176e6f5f6f746865725f696e70757473203f2046616c73650014a084780a2b3001598009804984a80984b00800c528c54cc240052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a084780a2b30015980099baf374c60ce6530010019bac309601003a5eb7bdb1810011112cc00400a200319800801cc2640400a6530010018014dd5984c80984d00984b009baa309901309a013096013754613202006800888966002005100189919914c00401a613e0200b32330010010052259800800c4cc27c04cdd81ba9004374c00697adef6c608994c004dd7184e80800cdd5984f00800cc288040092225980099b900080038998518099bb037520106e9801c0162b30013371e010007132598009840009850809baa0018998520099bb03752012614a026144026ea800400a200484f808c966002b30010018a518a50428c0514c0103d87a80008983f19852009ba60014bd70213e02329800800c022006800888966002005100189919914c00401a61560200b32330010010052259800800c4cc2ac04cdd81ba9004375000697adef6c608994c004dd7185480800cdd6985500800cc2b8040092225980099b900080038998578099bb037520106ea001c0162b30013371e010007132598009846009856809baa0018998580099bb03752012616202615c026ea800400a2004855808c96600261180200314c0103d87a8000898450099858009ba80014bd702156023370000e0051330af01337606ea400cdd400119803003000a1540242a80430ac0100142a8048030dd71852008009bad30a50100130a7010024294051330a301337606ea400cdd300119803003000a13c0242780430a0010014278048030dd7184c008009bab309901001309b010024264048019096011ba63067329800800cdd6184b0080152f5bded8c080088896600200510018cc00400e613202005329800800c00a6eacc26404c26804c25804dd5184c80801a002222598008014400626466453001006984f80802cc8cc004004014896600200313309f01337606ea4010dd3001a5eb7bdb1822653001375c613a020033756613c0200330a20100248896600266e4002000e2661460266ec0dd48041ba60070058acc004cdc7804001c4c9660026100026142026ea80062661480266ec0dd48049852809851009baa0010028801213e023259800acc004006294629410a3014530103d87a80008983f19852009ba60014bd70213e02329800800c022006800888966002005100189919914c00401a61560200b32330010010052259800800c4cc2ac04cdd81ba9004375000697adef6c608994c004dd7185480800cdd6985500800cc2b8040092225980099b900080038998578099bb037520106ea001c0162b30013371e010007132598009846009856809baa0018998580099bb03752012616202615c026ea800400a2004855808c96600261180200314c0103d87a8000898450099858009ba80014bd702156023370000e0051330af01337606ea400cdd400119803003000a1540242a80430ac0100142a8048030dd71852008009bad30a50100130a7010024294051330a301337606ea400cdd300119803003000a13c0242780430a0010014278048030dd7184c008009bab309901001309b010024264048019096014528c54cc2400524011e69735f6163636f756e745f76616c75655f657175616c203f2046616c73650014a084780a2b30013232330010013758612e0261300261300261300261300261300261300200a44b30010018a508acc004cdc79bae3098010010038a51899801001184c80800a124024258046eb8c2540401a29462a661200292012d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a084780a294108f014528211e028a50423c046466446600400400244b30010018a5eb8410180008101800044cc8966002600a00513309701374e6612e020046eb0c26004004cc25c04c26004c264040052f5c1133097013098010013309701374e6612e020046eb0c26004c264040052f5c0849008c25804004cc008008c25c04005094011bac3094010073302b002003323322330020020012259800800c52f5c210180008101800044cc8966002600a00513309701374e6612e020046eb0c26004004cc25c04c26004c264040052f5c1133097013098010013309701374e6612e020046eb0c26004c264040052f5c0849008c25804004cc008008c25c04005094011bac3094010023302a0020031846009baa330573758611e0200211002611e020026114026ea81822b30013370e900301a44c8c8cc8a600261240261240200537586122020053092013092013092013092013092013092013092013092010019bae3091010014888a60026eacc254040126eb0c25404c25804c25804c25804c258040126eb8c2540400a6eb8c25404c2580400a6eb0c25404021222223259800800c20c06264b3001309d010028992cc0040062b30013077309901375400313259800800c23406264b30010018992cc00400611e0313259800985100801466002007159800800c56600260f2613a026ea8006264b300100184900c4c96600200313259800800c25006264b300100184a80c4c966002614e020071980080244cc1ac00489660020051332233223259800acc004c21c04c0e8dd6185680985700801c528c54cc2a0052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085380a2b30015980098109856809857008014528c54cc2a0052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085380a2b300159800acc004cdd79ba6307f3304730243758615a0200a608c60466eb0c2b404010dd3000c4cdd79ba6001374c607001114a085380a29462a66150029211a69735f76616c7565735f6d61746368696e67203f2046616c73650014a085380a2b300159800991980080080c112cc00400629422b30013371e6eb8c2bc0400406e29462660040046160020028548090ad014528c54cc2a0052412d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085380a2b3001980080c4dd31823183f9bab30840130aa0137546108026154026ea804a4466e1c00800507b4528c54cc2a00524011d69735f696e74656e745f746f6b656e5f6275726e74203f2046616c73650014a085380a29410a7014528214e028a50429c0514a0853808c1f8cc118c088dd6185600800982298119bac30ac0100230ab0100230ab01001332232330010010122259800800c52f5c21018000810180008101800044cc8966002600c0051330ad01374e6615a020046eb0c2b804004cc2b404c2b804c2bc04004cc2b404c2b804c2bc04c2bc040052f5c1159800980280144cc2b404c2b804004cc2b404dd399856808011bac30ae0130af01001330ad0130ae0130af0130af010014bd7044cc2b404c2b804004cc2b404c2b804c2bc04004cc2b404dd399856808011bac30ae0130af0130af010014bd7021500242a00461580200266004004615a02002855008cc100028040cc100018040cc88c8cc004004064896600200314bd7081018000810180008101800044cc8966002600c0051330ad01374e6615a020046eb0c2b804004cc2b404c2b804c2bc04004cc2b404c2b804c2bc04c2bc040052f5c1159800980280144cc2b404c2b804004cc2b404dd399856808011bac30ae0130af01001330ad0130ae0130af0130af010014bd7044cc2b404c2b804004cc2b404c2b804c2bc04004cc2b404dd399856808011bac30ae0130af0130af010014bd7021500242a00461580200266004004615a02002855008cc0fc028040cc0fc01804226464b300100184d00c268061340309a01899912cc00400613803133071375600244b30010028980398578080444c8c9660020030a00185000c28006140031332259800800c28806144030a2018991803185a008039bad00185100a16802375c002615a02004859008c2ac04004c2b8040090ac014270061380309c0142b8046eb8004c29c040090ac01185280800985400801214c0284b00a0de84b00a1480237560030950184a80c254050a701185200800a1440230a40100284980c24c061260309301429404614402002850008c27804dd5000c2440509b01424406122030910184880a1460284800a0d484800a13e0230a00100142780461400200508e0184700c2380611c02850808c2780400509c01184d009baa00184600a12e0284600c230061180308c01427c0464b3001307530990137540031309d01309a01375400315330980149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016425c04613802613a02613a026132026ea8c27004c27404c26404dd5000c2100509a01184d80800a132023232330010010032259800800c52f5c11332259800acc004cdd7984f80984e009baa309f0130a001309c01375400400b1323300100132330010013756614202614402613c026ea8c28404c28804c27804dd5002112cc004006297ae0899199119198008009bab30a3010042259800800c400e2646614e026e9ccc29c04dd480299853809852008009985380985280800a5eb80cc00c00cc2a404008c29c040050a5011bae309f010013300300330a40100230a20100142800444b30010018a508acc004cdc79bae30a101375861420200201514a313300200230a201001426c0484f80a29410990144cc27804008cc01001000626600800800284c808c27404004c2780400509b01182400186120020026118026ea8cc15cdd6184780800844009847808009845009baa0608acc004c1440d233001308a013754611a026114026ea816a4444b30010018801c4c966002007153308d0149012a6e6f7420656e6f756768206b65792d76616c756520706169727320746f206d617463682070726f6f667300168992cc004c1acc23c04dd500146600200d9800802cdd7184780800cdd7184800800cdd61849809848009baa0024021309401004984a00801a00c8a9984700a4930657870656374204d504644656c657465207b2070726f6f663a2064656c6574655f70726f6f66207d203d2070726f6f660016423404612402006848008c2440400508f014c22804dd5030244530013002002984800801cdd5984800984880801cc2440400522223232329800984c00984c00984c00984c00800cc25c040066eb8c25c0400922298009bae309a01309b01309b0100398241bae309a0100399198008009bac309b0100c2259800800c52f5c11332259800acc004cdd7984f00984d809baa309e01309f01309b01375400400d130783259800983c984d809baa0018a40011375a613e026138026ea800509901192cc004c1e4c26c04dd5000c5300103d87a8000899198008009bab30a001309d01375400444b30010018a6103d87a8000899192cc004c200040062b3001307f0018983e198510098500080125eb82298103d87a800042740513300400430a4010034274046eb8c27804004c2840400509f0121320232330010013756613e026140026138026ea8c27c04c28004c27004dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c024006260f66614202613e0200497ae08a60103d87a800042700513300400430a3010034270046eb8c27404004c2800400509e01452821300289984e8080119802002000c4cc01001000509801184e00800984e80800a134029bac309a01309b010079bae309a0100648888966002007082018992cc004c28404012264b30013079309d01375400313259800800c56600260fa613c026ea8006264b300100184a00c4c9660020030950184a80c2540612a0313259800985300801c4c96600200308b018992cc004c2a00400a264b300130800130a401375400313259800800c660020031323259800acc004cdd79ba63303437566156026158026158026158026158026150026ea81f8cc2a804dd4808a5eb80c2ac04c2b00400a29462a6614c029211769735f76616c75655f6d696e746564203f2046616c73650014a085280a2b30015980099198008009bac30ac0130ad0130ad0130ad0130ad0130ad0130ad0130ad0130ad0130a90137540fe44b30010018a508acc004cdc79bae30ad0100100f8a51899801001185700800a14e0242ac0514a315330a60149011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085280a2b3001598009843009853809baa01a8992cc0056600266e3cc09c00402229462a6614e02920134636f6d707574655f747265655f68617368287472656529203d3d20696e7075745f6d65726b6c655f726f6f74203f2046616c73650014a085300a2b30015980099baf374c60980026e9800a29462a6614e029212f6b65795f76616c756573203d3d206f75747075745f6d65726b6c655f7265636f72645f6c697374203f2046616c73650014a085300a2b30013371e6eb8c2b004c2a404dd5002245200000000000000000000000000000000000000000000000000000000000000000008a518a9985380a494d6f75747075745f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085300a29410a6014528214c0230ab0130a801375403513371e60a66eb8c2ac04c2a004dd5001cc004c14c01e00337586156026150026ea806901b214a028a518a9985300a4811769735f747265655f75706461746564203f2046616c73650014a085280a29410a5014528214a0237566154020033001323300100100d2259800800c52f5c1133225980099baf30ad0130aa0137540040251330ac0100233004004001899802002000a14e0230ab0100130ac0100142a4054bd708101a0008101a000488c9660026108026150026ea800626644b30010018cc00400626615a026e98cc2b404cdd81ba937660026ea4dd99ba60023756615c020086615a026e98cc120dd59842808021981b9bab30850130ab01375400a6615a026ea40512f5c097ae085080a0ee85080c28406142030a10142c005300137566106026152026ea800e02501a40d86158026152026ea80062a6614e029212f65787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206f75747075742e646174756d00164298046102026150026ea8009056426c05055426c061360309b0184d80a1560230a80130a501375400308e0142880460fa6148026ea800611802852808c298040050a4011919800800804912cc004006297ae0899912cc0056600266ebcc2a404c29804dd5001008c4c20c04c966002610802614c026ea80062900044dd69855009853809baa00142900464b300130840130a601375400314c0103d87a8000899198008009bab30ab0130a801375400444b30010018a6103d87a8000899192cc004c22c040062b3001308a010018984380998568098558080125eb82298103d87a800042a00513300400430af0100342a0046eb8c2a404004c2b0040050aa0121480232330010013756615402615602614e026ea800c896600200314c103d87a8000899192cc004cdc880a000c56600266e3c0500062610c02661580261540200497ae08a60103d87a8000429c0513300400430ae01003429c046eb8c2a004004c2ac040050a90145282146028998540080119802002000c4cc0100100050a301185380800985400800a14a0284b00a14602375c002853008c28c040050a101184f809baa00184980a1380284980c24c061260309301429004614202613c026ea80062a661380292014665787065637420496e6c696e65446174756d28747265655f726f6f7429203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d0016426c0460ec613a026ea8c1dcc27404dd5000c20c0509e01184f80801a13a020c25c04004c25804c25804c25804c25804004c24404dd51982e1bac30940100108d01233001308a013754611a026114026ea816a4444b30010018801c4c966002007153308d01491256e6f7420656e6f756768206b65792d76616c75657320746f206d617463682070726f6f667300168992cc004c1b8c23c04dd500146600200d9800802cdd7184780800cdd7184800800cdd61849809848009baa0024031309401004984a00801a00c8a9984700a4930657870656374204d5046496e73657274207b2070726f6f663a20696e736572745f70726f6f66207d203d2070726f6f660016423404612402006848008c2440400508f014c22804dd5030244530013002002984800801cdd5984800984880801cc244040066eb0c240040052222233229800984c00984c008014dd6184b808014c26004c26004c26004c260040066eb8c25c04005222298009bab309b010049bac309b01309c01309c01309c01309c01004984e008014dd7184d80801244446644646530013756614602003375661460261480200332330010010102259800800c52f5c11332259800acc004cdd79853809852009baa30a70130a80130a401375400400f130810132598009841009852009baa0018a40011375a615002614a026ea80050a201192cc004c20804c29004dd5000c530103d87a8000899198008009bab30a90130a601375400444b30010018a6103d87a8000899192cc004c224040062b30013088010018984280998558098548080125eb82298103d87a800042980513300400430ad010034298046eb8c29c04004c2a8040050a80121440232330010013756615002615202614a026ea8c2a004c2a404c29404dd5001912cc004006298103d87a8000899192cc004cdc8806800c56600266e3c0340062610802661540261500200497ae08a60103d87a800042940513300400430ac010034294046eb8c29804004c2a4040050a70145282142028998530080119802002000c4cc0100100050a101185280800985300800a14602488966002003089018992cc004c2a00400a264b300130800130a401375400313259800800c6600200313259800800c23c06264b300130ac010028992cc004c21004c2a004dd5000c4c96600200319800800c566002b30013375e6e98048dd3004c528c54cc2a00524011669735f76616c75655f6275726e74203f2046616c73650014a085380a2b3001598009919800800809112cc00400629422b30013371e6eb8c2bc0400405629462660040046160020028548090ad014528c54cc2a0052411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085380a2b3001598009844009854809baa01c8992cc0056600266e3cdd71857009855809baa006489200000000000000000000000000000000000000000000000000000000000000000008a518a9985480a4950696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085400a2b30015980099b8f3029001375c615c026156026ea800a29462a66152029215f636f6d707574655f747265655f68617368287472656529203d3d206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203f2046616c73650014a085400a2b30013375e6e98c138004dd31919800800806112cc004006297adef6c60899191980080099802002185980801912cc0040062661640200697adef6c608992cc004cdd799912cc004cdc8001000c530103d87980008acc004cdc7801000c530103d87a80008a6103d87b800042c004858008dca1bae30b00100437286eb8c2c00400530103d87980008998598080200144cc2cc04004cc00c00cc2d4040090ae01185980800a1620230b00100142b80514a315330a9014913c657874726163745f6b65795f76616c756573287472656529203d3d20736f727465645f73657269616c697365645f696e70757473203f2046616c73650014a085400a29410a801452821500230ad0130aa01375403913371e60aa6eb8c2b404c2a804dd5000cc004c154dd71856809855009baa0058054dd61856809855009baa01c407485380a29462a661500292011769735f747265655f75706461746564203f2046616c73650014a085380a29410a7014528214e0284a00a0b284a00c25006128030940142bc046158026152026ea800612402853008c20404c2a004dd5000c240050a901185500800a1500232330010010122259800800c52f5c11332259800acc004cdd79856809855009baa00200d8984380992cc004c22004c2a804dd5000c5200089bad30ae0130ab013754002854008c9660026110026154026ea8006298103d87a8000899198008009bab30af0130ac01375400444b30010018a6103d87a8000899192cc004c23c040062b3001308e010018984580998588098578080125eb82298103d87a800042b00513300400430b30100342b0046eb8c2b404004c2c0040050ae0121500232330010013756615c02615e026156026ea800c896600200314c103d87a8000899192cc004cdc8809800c56600266e3c04c00626114026616002615c0200497ae08a60103d87a800042ac0513300400430b20100342ac046eb8c2b004004c2bc040050ad014528214e028998560080119802002000c4cc0100100050a701185580800985600800a1520284680a0aa84680c2340611a0308d0142ac04615002614a026ea80062a66146029214865787065637420496e6c696e65446174756d28696e7075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642880460fa6148026ea8c1f8c29004dd5000c228050a501185300800a148024c004c8c8cc004004040896600200314bd7044cc8966002600a0051330a60100233004004001899802002000a1420230a50100130a601001428c0446466ebcc29004c28404dd51852009852809850809baa0020013051375c6146020094bd70901a0008101a000488c96600260fa6142026ea800626644b30010018cc00400626614c026e98cc29804cdd81ba937660026ea4dd99ba60023756614e020086614c026e98cc104dd5983f0021820198181bab307e30a401375460fc6148026ea8014cc29804dd480325eb812f5c10890141c10890184480c224061120285480a60026eacc1f0c28804dd5183e1851009baa003802404d02f1852809851009baa0018a9985000a4813465787065637420496e6c696e65446174756d28696e7075745f646174756d29203d20696e7075742e6f75747075742e646174756d0016427c0460f46142026ea8c1ecc28404dd5001209e375c614202614402614402004614002614002614002614002004613e02004184b008011849009baa3305d3758612a0200411c02210e02421c04843808dd7a601018000421804222329800800c01200680088896600200510018cc00400e611e0200533004001308e01002400c846009082010c00c00c02223259800980f000c4c9660020030038992cc0040060090048992cc004c11c00e26601600244b300100280444c96600200319800800c4c008c12800e0108062011008804402104b1824001208c802a0883758003004802208e3044001410860806ea80122b3001301d0018992cc00400600713259800800c01200900480244cc89660020030068992cc00400600f007803c01e26644b3001001804c4c96600200300a80544c966002609a0071330110012259800801403a264b30010018cc0040062600460a000700e404900e807403a01c8288c13800904c402d04a1bac001805402904d1825000a090375c00260920048250c11c0050451bae0013046002411c60880028210c100dd50024566002603600313259800800c00e264b30010018024012264b30013047003899805800912cc00400a01113259800800c6600200313002304a00380420188044022011008412c6090004823200a8220dd6000c0120088238c11000504218201baa004801207a40f481e8c0f8dd5001a03501a80d406903d181d181b9baa0068b206840d04464b300130163037375400313259800800c566002602e60706ea8006264b300100180f44c96600200301f80fc07e03f1332259800800c086264b3001001811408a045022899912cc00400604913259800800c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b30010018992cc00400605d13259800800c0be05f02f817c4cc89660020030318992cc004006264b3001001819c4c96600200303481a40d20691332259800800c0da264b300100181bc0de06f037899912cc00400607313259800800c0ea07503a81d44cc896600200303c8992cc00400607b03d81ec0f6264b3001305e0038cc00406a330010128cc004036204503e409d03e409d03e409903e416c6eb800505e182d800a0b2375c00260b400482d8c1600050561bae0013057002416060aa0028298dd7000982a00120aa3052001414060a400503281940ca0648298c14000504e1bae001304f0024140609a0028258c13400a05b02d816c0b504e1825800a092375c00260940048258c1200050461bae00130470024120608a0028218c11400a04b025812c0950461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0e4dd5000c075036407603b01d80ea07c323259800980c000c54cc0e12401274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c05c0062a66070921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981e981d1baa00240dc81b8c0e0dd50009808981c1baa301230383754607660706ea80062a6606c9201cd65787065637420536f6d65286465785f6f726465725f626f6f6b5f7265665f696e70757429203d0a20202020696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206465785f6f726465725f626f6f6b5f746f6b656e2c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640d4660120044602a64b300130163038375400314800226eb4c0f0c0e4dd5000a06c3259800980b181c1baa0018a6103d87a8000899198008009bab303d303a375400444b30010018a6103d87a8000899192cc004c0740062b3001301c0018980c9981f981e80125eb82298103d87a800040e9133004004304100340e86eb8c0ec004c0f800503c206c3300b3756602460706ea8c048c0e0dd5000801181a1baa0042223259800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009820801c66002009008803a016803a07c375c0028208c0f800503c181f0014012009004802207e303c00140e860706ea80122b300130150018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130410038cc004012011007402d00740f86eb8005041181f000a078303e002802401200900440fc607800281d0c0e0dd50024566002602600313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002608200719800802402200e805a00e81f0dd7000a082303e00140f0607c005004802401200881f8c0f000503a181c1baa004801206a40d481a8c0d8dd500188a4d153301d4911856616c696461746f722072657475726e65642066616c7365001365640701", - "hash": "598070a13f97093036bc75e11891e9931a98f2e2e4da8225bb6a1eaa" + "compiledCode": "59d54d010100229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0024888888888a60022a66006920148657870656374204d657373616765207b207661756c745f6571756974792c207072696365732c207574786f5f726566207d3a204d657373616765203d207369676e65645f6461746100168a99801a492e6578706563742061737365745f6c6973743a204d56616c7565203d20646573657269616c697365645f76616c756500168a99801a4949657870656374206f75747075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a494665787065637420696e7075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492a657870656374206163636f756e743a20557365724163636f756e74203d206f75747075745f646174756d00168a99801a494a657870656374206f75747075745f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a497b657870656374204465784163636f756e7442616c616e6365446174756d207b0a202020206163636f756e745f62616c616e63655f6d65726b6c655f726f6f743a20696e7075745f6d65726b6c655f726f6f742c0a20207d3a204465784163636f756e7442616c616e6365446174756d203d20747265655f726f6f7400168a99801a495b657870656374205472616e73666572496e74656e74207b20746f2c20616d6f756e745f6c323a207472616e73666572616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a496a657870656374204d6173746572496e74656e74207b206163636f756e743a2066726f6d2c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495f6578706563742043616e63656c5769746864726177616c496e74656e74207b20616d6f756e745f6c313a207769746864726177616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a4941657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d206465785f6163636f756e745f62616c616e63655f6f75747075747300168a99801a493f657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d206465785f6163636f756e745f62616c616e63655f696e7075747300168a99801a49e7657870656374205b6665655f6f75747075745d203d0a202020202020202020206f746865725f6f7574707574730a2020202020202020202020207c3e206c6973742e66696c746572280a202020202020202020202020202020206372656174655f6163636f756e745f6f7574707574735f66696c746572280a2020202020202020202020202020202020206665655f6163636f756e742c0a20202020202020202020202020202020202068796472615f6163636f756e745f7363726970745f686173682c0a20202020202020202020202020202020292c0a20202020202020202020202020202900168a99801a498b657870656374205769746864726177616c496e74656e74207b0a20202020616d6f756e745f6c313a207769746864726177616c5f616d6f756e745f7261772c0a202020207769746864726177616c5f6665655f6c313a207769746864726177616c5f6665655f7261772c0a20207d3a2048796472614163636f756e74496e74656e74203d20696e74656e7400168a99801a4964657870656374204d6173746572496e74656e74207b206163636f756e742c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a498c657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c696379280a202020202020696e707574732c0a20202020202068796472615f757365725f696e74656e745f616464726573732c0a20202020202068796472615f757365725f696e74656e745f7363726970745f686173682c0a202020202900168a99801a494e657870656374206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a494365787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f6f75747075742e646174756d00168a99801a499d657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d0a202020206f7574707574735f61745f77697468280a2020202020206f7574707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a494c65787065637420696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f646174756d00168a99801a499a657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d0a20202020696e707574735f61745f77697468280a202020202020696e707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a4929657870656374206163636f756e743a20557365724163636f756e74203d20696e7075745f646174756d00168a99801a499d657870656374205661756c744465706f736974496e74656e74446174756d4c32207b0a202020207661756c745f6f7261636c655f6e66742c0a202020206465706f7369746f722c0a202020206465706f7369745f616d6f756e742c0a20207d3a205661756c744465706f736974496e74656e74446174756d4c32203d20696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a493e657870656374206f75747075745f646174756d3a20557365724163636f756e74203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a493b65787065637420696e7075745f646174756d3a20557365724163636f756e74203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492e657870656374206f6c645f656e7472793a205368617265735265636f7264456e747279203d206f6c645f6461746100168a99801a492f657870656374206f6c645f656e7472793a205368617265735265636f7264456e747279203d2066726f6d5f6461746100168a99801a492f65787065637420536f6d652866726f6d5f6461746129203d2063626f722e646573657269616c6973652866726f6d2900168a99801a495b657870656374206f75747075745f6f7261636c655f646174756d3a205661756c744f7261636c65446174756d203d0a202020206f75747075745f696e6c696e655f646174756d287661756c745f6f7261636c655f6f75747075742900168a99801a495865787065637420696e7075745f6f7261636c655f646174756d3a205661756c744f7261636c65446174756d203d0a20202020696e7075745f696e6c696e655f646174756d287661756c745f6f7261636c655f696e7075742900168a99801a494d657870656374205b7661756c745f6f7261636c655f6f75747075745d203d206f7574707574735f776974685f706f6c696379286f7574707574732c207661756c745f6f7261636c655f6e66742900168a99801a494a657870656374205b7661756c745f6f7261636c655f696e7075745d203d20696e707574735f776974685f706f6c69637928696e707574732c207661756c745f6f7261636c655f6e66742900168a99801a49a6657870656374205661756c745769746864726177616c496e74656e74446174756d4c32207b0a202020207661756c745f6f7261636c655f6e66742c0a20202020776974686472617765722c0a202020207368617265735f746f5f72656465656d2c0a20207d3a205661756c745769746864726177616c496e74656e74446174756d4c32203d20696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495b657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c69637928696e707574732c20696e74656e745f616464726573732c20696e74656e745f706f6c6963795f69642900168a99801a4958657870656374206465785f6f726465725f626f6f6b5f696e7075745f646174756d3a204465784f72646572426f6f6b446174756d203d0a202020206465785f6f726465725f626f6f6b5f7265665f696e7075745f6461746100168a99801a493465787065637420536f6d65286f776e5f696e70757429203d20696e70757473207c3e2066696e645f696e70757428696e7075742900168a99801a491e72656465656d65723a2048796472614163636f756e7452656465656d657200168a99801a493d657870656374206f7065726174696f6e3a2050726f6365737348796472614163636f756e744f7468657252656465656d6572203d2072656465656d65720016488888888888888888888888888888888888889660033001302b37540633722911009b8f4881009b87480026e1d20029ba5480026e1d2004918179818000c8c0bcc0c0c0c00066e1d20069ba548009222222222229800981d005cc0e402e4646600200200444b30010018a5eb7bdb1822653001375c607200337566074003303e00248896600260220071598009808001c4006200a81d226607e66ec0dd48019ba60023300600600140e8303c00140e922232598009806000c4c9660020030038992cc0040060090048024012264b30013041003803401503e1bae0014104607c00281e0c0e8dd50024566002601600313259800800c00e264b300100180240120090048992cc004c10400e00d00540f86eb8005041181f000a078303a375400900240dc81b8c0e0dd5001c88c8cc00400400c896600200314c103d87a8000899192cc004cdc8802800c56600266e3c014006260186607c607800497ae08a60103d87a800040e5133004004304000340e46eb8c0e8004c0f400503b488c8cc00400400c896600200314c0103d87a80008992cc004c010006260166607a00297ae0899801801981f8012070303d00140ed22259800801452844ca600264b3001300d303a37540031375a6076607c6eacc0f8c0ecdd5000c5200040e0607a003375e607a607c00337560069112cc0040062b30013002006899802801a400114a081d2264b30013375e607a0029810140008acc004cc018010dd6981f18209bab303e001898019ba630420028a5040ed1598009980300224001130030078a5040ec81d8c10000503e0ca6002003004911981f0011981f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0f00066eacc0f400660820069112cc004c05000e2b300130130038998029808198211ba60024bd70000c4cc01530103d87a800000640f519800803c006446600e0046608866ec0dd48029ba6004001401c81e8607e00481ea29422942294103e244444453001304000798201820803c889660026024607e6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002609600519800801c66002003009804201c804201c80420908044022011008413060920028238c12400a00d006803401904a1823800a08a375c002608c0048238c11000504218201baa003800a07a9112cc004c048c0fcdd5001c4c9660020030028992cc004006264b300100180244c966002003159800982400146600200713259800980b800c4c9660020030078992cc0040062b3001304b0028992cc004c068006264b300100180544c966002003159800982700146600200300c805a022805a096805c02e01700b413c60980028250c120dd50014566002603200313259800800c02a264b3001001805c02e0171332259800800c036264b3001001807403a01d1332259800800c042264b3001001808c04602313259800982a801c04e0248290dd6800c0450551829000a0a0375a00260a200500e4148609e0028268dd68009827001402d04f1826000a0943048375400500941148228c118dd5000c021048402201100880420983049001411c608a6ea800a2b300130160018acc004c114dd5001401e00c823200c821104218219baa001802a016802a08a802c01600b0054124608c0028220c11800a007003801c00d0471822000a0843040375400700140f491111919912cc004c0540062646644b300100a899912cc004c06c006264b3001001810c4c966002609e0050048112098304d001412c60926ea80322b3001301a0018acc004c124dd5006400a04082522b300130180018acc004c124dd5006400a04082522b300130150018acc004c124dd5006400a04082520408231046208c411826464664530013756609c0053758609c609e609e005304f304f304f304f304f304f304f304f304f0019bae304e00198251baa00e9119809001119baf3051304e37540020053758609c00891111112cc004c09000e2b30013232330010010092259800800c528456600266ebc00cc150c160006294626600400460b20028291056180e9982a182a982b002a5eb8229462a660a09214e7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6f726465725f626f6f6b5f7363726970745f6861736829203f2046616c73650014a0827a2b300130230038acc004c8c8cc004004024896600200314a115980099baf003305430580018a51899801001182c800a0a44158603a660a860aa00a97ae08a518a9982824814b7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6163636f756e745f7363726970745f6861736829203f2046616c73650014a0827a2b3001301e0038992cc004c094c148dd5000c4c966002604a60a66ea80062b300132323300100100b2259800800c528456600266ebc00cc158c168006294626600400460b600282a1058180f9982b182b982a1baa0014bd704528c54cc149241417769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c206f776e5f7363726970745f6861736829203f2046616c73650014a0828a2a660a49215665787065637420536372697074286f776e5f7363726970745f6861736829203d0a202020202020202020206f776e5f696e7075742e6f75747075742e616464726573732e7061796d656e745f63726564656e7469616c0016414460ac60a66ea8c158c14cdd5181098299baa30563053375400302b41406600400201b13259800981298291baa0018acc00566002b30019800980d9bab302130533754604260a66ea8c158c14cdd5000d30101a0009119b87002001405d14a3153305149011369735f6e6f5f76616c7565203f2046616c73650014a0828229462b300159800981298291baa00d8a508a51414114a315330514911369735f6e6f5f646174756d203f2046616c73650014a082810504566002646600200201044b30010018a508acc004cdc79bae30580010078a51899801001182c800a0a4415914a315330514911f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a08282294105040ad05019801000806a09e413c8278609a609a609a609a609a00260926ea8cc01cdd61826000822982600098239baa0103046375401501e80f407a03c8260c120004c120c124004c110dd50034566002602600319800982398221baa006912cc00400629344c966002003149a264b3001337206eb8c11cc12c00cdd71823800c4cc010010cc128004c13000a2a6608c9201326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f726465720016411460940028240c12800504748888c8cc004004014896600200313304c337606ea4014dd300225eb7bdb1822653001375c609400337566096003304f00248896600266e4002400e2660a066ec0dd48049ba60080058acc004cdc7804801c4c9660026042609c6ea80062660a266ec0dd4805182918279baa001002880120989800804c022004803a2660a066ec0dd48019ba600233006006001412c8258609a002825a4444646600200200a44b300100189982619bb0375200a6ea00112f5bded8c113298009bae304a0019bad304b00198278012444b300133720012007133050337606ea4024dd4004002c56600266e3c02400e264b30013021304e3754003133051337606ea4028c148c13cdd50008014400904c4c004026011002401d133050337606ea400cdd400119803003000a096412c304d001412d259800800c528c528208c91192cc004c060c118dd5000c52f5bded8c1137566094608e6ea800504419806001000c888c8cc004004010896600200310048994c004dd71824800cdd69825000ccc00c00cc1380090041826000a094918241824982498249824800c8c120c124c124c124c124c124c124c124c1240064602a6608e60206608e6ea40052f5c06608e980103d87a80004bd704888ca6002003004801a00222259800801440063300100398270014cc010004c134009003209691919800800801112cc004006297ae08991991199119801001000912cc00400620071323304f374e6609e6ea4014cc13cc130004cc13cc1340052f5c06600600660a2004609e0028268dd598250019bae304700133003003304c002304a001412122372866e280080066e0120039b804801e44b300130183370c002900244cdc199b8e0023370600290022404113370c66e38008cdc1800a4008901020869b804800a45300100199b81371a0040030025c626e01200f9b80480064b30013370e6e3400520408800c54cc10d24138657870656374206279746561727261792e6c656e67746828726f6f7429203d3d20626c616b6532625f3235365f6469676573745f73697a650016410937029000488c8cc00400400c88cc00c004c00800a44464b3001301a0018992cc00400600713259800800c012009004899912cc00400600d13259800800c01e00f007803c4c96600260a4007009804209e375c0028290c13c00504d1bad001304e002802209e304c001412860906ea80122b300130190018992cc00400600713259800800c012009004899912cc00400600d13259800800c56600260a2005159800980f98261baa0018992cc00400601113259800800c026013009899912cc00400601713259800800c03201900c80644cc896600200300e8992cc00400601f00f807c03e264b3001305a003808c0410571bae001416860ae00282a8dd7000982b00120ae305400141486eb4004c14c00a01282a0c14400504f18269baa001803a094803a09c803c01e00f0074148609e0028268dd68009827001401104f1826000a09430483754009159800980b800c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e26644b3001001804c4c96600200300a805402a01513259800982a801c0320168290dd7000a0aa305200141406eb8004c1440090521827800a09a375a002609c005004413c60980028250c120dd50024009045208a4114608c6ea800e444b3001337120049000440063300100399b840024805266e2ccdc019b85002480512060001400c82224444646600200200a44b30010018802c4c966002003133004304e002006899802982700119801801800a098304e001412d22225980099b88002480c22600200515980099b87002480c2266008900111801000c56600266e20009203889980199b8e488103020408003370000490189180119bca4a2003124bded8c101400001012000411482290454dc3a41fc0722337600046ea00066e1d200a9baf4c10180004888888888888888888888888888888a6002603c03d22229800802400e0052229800801c006004802102148896600266ebcc1a4c198dd5181a18331baa00130190028992cc00400633001001899baf001004825204c825412a09504a41b064b30013036306637540031306a3067375400315330654913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016419060d260d460d460cc6ea8c1a4c1a8c198dd5000c52820c69112cc004cdd7983498331baa00130190028992cc00400633001001899baf001004825a04c825c12e09704b41b064b30013036306637540031306a30673754003153306549012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016419060d260d460d460cc6ea80062941063488ca60020030038012002222598008014400626530010049836801e6002005375c60d0003375660d200322232598009812800c5300103d87a80008981e998379ba60014bd7020d4329800800c00e00480088896600200510018994c00401260e800798008014dd71837800cdd69838000c888c966002608c00314c103d87a8000898221983b1ba80014bd7020e2337000040028149004183900120e0408c8020c1ac00906948896600266e2400d200089980b001000c4cc0580040090634888c8cc00400400c896600266e2400c0062910100899b8b3301500500133002002301400141952259800981b99b8600148012266e2d20fe033301000233706002900244cdc5a400066e2ccc048008004cc040008cdc19808800a400883124646600200200444b30010018a5eb7bdb182264660d266ec0c198004dd319198008009bab30680022259800800c52f5bded8c11323306c3376060d20026ea0c044dd698350009980180198370011836000a0d433003003306b0023069001419d300700791111194c0040060070024004444b300133712004900044c0052f5c112323298008034c05c0164600a660e2004003375a60dc0048030c1b00066002013008800a00e41a1222232330010010022233006480089660026016003130024bd70448c8ca600200d23006330700020019bad306d002401860d60033001008803cc05c00500620ce91114c00401200700291980200091801800a0124888888888888a60024444b300130460018802466002009003991900118090009983b19bb037520046ea00052f5bded8c122232598009818000c530103d87a8000898241983d1ba60014bd7020ea9800801401600922232598009826800c530103d87a8000898259983e9ba80014bd7020f033700002004818101020e294c00400697adef6c6091198060011bab304130733754608260e66ea80050234a60020034bd6f7b630488cc030008dd5982098399baa001408d22225980099b890044800a2660493001004801c00500c00144cc09000a60026046009003800a01841c522225980099b88004480122b300133710004900244cc0926002009003800a0184881200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f9761008998124c00401200748920000000000000000000000000000000000000000000000000000000000000000000403130013023002800d221200000000000000000000000000000000000000000000000000000000000000000004030838a2b300133712900200144cc091221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f97610098009811802400e00280622660493001002800d22120000000000000000000000000000000000000000000000000000000000000000000403130013023004801d2212000000000000000000000000000000000000000000000000000000000000000000040308389071488c8cc00400400c8966002608c0031337149110130000038acc004cdc4000a40011337149101012d0033002002301b00189980419b8400148050cdc599b803370a002900a240c00068389071488cc004888c8c8cdd8191ba73307a30770013307a30780014bd7019bb030760023076001307700198008034880060090039bad30760014019300100591000c00e0050014014446600490011192cc004cdc4800a40091598009824000c6600200900380148c05cdd4000a0308acc004c11c00633001004801ccdc00012407f2301737506040603c00280c22b30013370e004905f00c4c8cc0040048c060dd48009119803240044b3001301a00189801245008cc00401e00d33700002903fc8cc0100108c010cdc5001000a01441d919800802400e66e00009207f9180b9ba9001401c839907320e68acc004cdc3800a401919800802400e66e0000920ff02919802a40044b30013370e004906600c492f7b63001014000010120008992cc004cdc38012417c0519800803c01a66012012440032301a3374a004002805a330010078034cdc0001241fe0329800804401e66014014440030019180d99ba5003001403480d90762cc004cdc4a41002800513370066e0000920ff134803a266e0000920f10141d483a9018456600266e1c00520088acc004cdc38012417c0519800802400e6600c00c4400323017374e002804233001004801ccdc0001241fe0329800802c0126600e00e440030019180c1ba7001402880c10734566002602a00315980099b87002483f80a2646466002002460326e9800488cc01d2002259800980d800c4c0092f5bded8c1123232980080348c018cc200040080066eb4c1f40090061919bb0308001001308001308101001375860f600330010098044c09c00500520ee33006006220028cc00401200733700004905f8148c8ca60020030039180d1ba60014004444b300133712004900044c0052f5bded8c112323298008034c09c0164600a6610202004003375a60fc0048030c8cdd81840808009840809841008009bac307c0019800805402600280290781980380391001203041cd124bded8c010140000101200041cc839907320e633706002902048c8cc004004008896600200314bd6f7b63044ca60026eb8c1cc0066eacc1d00066600600660f00049112cc00400a2a660ea92124657870656374205061697228702c205b5f2c202e2e5d206173207829203d20696e6e657200168cc004006007323200432330010010042259800800c5268992cc0040062b30013004375a60f660fc005149a2a660f292011f76616c756520646f65736e2774207361746973667920707265646963617465001641e1133225980099b90375c60f80046eb8c1f00062b30013006375a60fa0051330050053307f0013081010038a9983da491f76616c756520646f65736e2774207361746973667920707265646963617465001641e9153307b491276b65797320696e207061697273206172656e277420696e20617363656e64696e67206f72646572001641e860fc00460fc00283e0c1f800507b14c004c12800694294507548894cc1e12401234475706c696361746520706f6c69637920696e20746865206173736574206c6973742e0016404c83c060ec00283a12222222298009114c004cc0c800c00a97adef6c60911192cc004c144c1f8dd5000c4ca6002007375c610602003375c61060261080200300440406eb0c20804c1fcdd5000c54cc1f524121546f6b656e2068617368206e6f7420666f756e6420696e20746f6b656e206d6170001641f0646600200200a44b30010018a60103d87a80008992cc004cdc78031bae308001001898289984180984080800a5eb82266006006610a0200483f0c20c04005081012062911112cc004cdc4802a400d13302d9800802c012005001402800713302d00398009815802c012005001402883d24444b3001337100089004456600266e2000920088998164c004012007002800a01048812085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b1008998164c004012007489200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040253001302a002800d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483ca2b300133712900400144cc0b12212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b10098009815002400e6054005001402113302c980080140069101200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040253001302a004801d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483c90794888c9660020071323233223300b0023371491101280059800800c4cdc52441035b5d2900006899b8a489035b5f20009800800ccdc52441025d2900006914c00402a00530070014029229800805400a00280510232102025980099b880014803a266e0120f2010018acc004cdc4000a41000513370066e01208014001480362c83d907b1bac307e002375a60f80026466ec0dd4183e0009ba7307d001375400713259800800c4cdc52441027b7d00003899b8a489037b5f20003232330010010032259800800c400e264b30010018994c00402a610202003337149101023a200098008054c2080400600a805100a18420080144ca600201530810100199b8a489023a200098008054c20804006600e66008008004805100a18420080121040230840100142040466e29220102207d0000341f86eac00e264b3001001899b8a489025b5d00003899b8a489035b5f20009800800ccdc52441015d00003914c00401e0053004001401d229800803c00a002803902020fc3758007133007375a0060051323371491102682700329800800cc09cdc68014cdc52450127000044004444b300133710004900044006264664530010069816002ccdc599b800025980099b88002480522903045206e42000466e2ccdc0000acc004cdc4000a402914818229037210002004401866e0c00520203370c002901019b8e00400241f46eb800d081011b8a4881022c20009801001244445300122222330329800802c012605600680ca60026605e00a60560079800a400148102002b8c66002902052040800ae319800a41000348102002b8c66002906000d2040800ae30911112cc004cdc4802a401d1330379800802c01e007002800a01c00489981b8024c004c0c401600f003801400500e210802488888c96600330013370e0026eb4c21804c20c04dd5001528528a10002899819cc00401a00b302c00440686644b3001337100069008456600266e20009201089981acc00400e00b002800a01648920b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0089981acc00400e00b4892085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302f002800d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403084100a2b300133712900800144cc0d522120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0098009817801c016605e005001402d1330359800801400691012085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302f003802d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a441200000000000000000000000000000000000000000000000000000000000000000004030841009082011bad3086013083013754004660666eb8c144c20c04dd50011bae3050308301375400515330810149120657870656374206272616e636820213d206e65696768626f722e6e6962626c6500164200046605e00a605600730020029192cc004c144006298103d87a80008992cc006600260a46eb4c2000400694294507d4530103d87a8000898281984100983f800a5eb8107d4c00488006444b3001337120029000452f7b63010140000101200089980119b8e0053370200800266e0400400d07f48896600266e2400520008a5ef6c601014000010120008998014c004cdc0802000c00e00ab8c19b8100100341fd001400c83e0dc6800a44446645300122225980099b8f330060030010048cc00400e0050014015153308501490129657870656374206578636c7564696e67286b65792c2070726f6f6629203d3d2073656c662e726f6f740016421005222225980099b8f9800802400a006803001633001004800c00d006454cc2180524013465787065637420696e636c7564696e67286b65792c206f6c645f76616c75652c2070726f6f6629203d3d2073656c662e726f6f74001642140522225980099b8f9800801c00a002802801226600c00600315330850149013065787065637420696e636c7564696e67286b65792c2076616c75652c2070726f6f6629203d3d2073656c662e726f6f740016421004911192cc00412a265300122259800982e9845009baa0038992cc00400600513259800800c4c9660020030048992cc00400600b13259800984a00801c4cc896600260c800313259800800c026264b30010018acc004c2600400a26530010018014015001111192cc004c1a8006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c4c9660026144020071330440012259800801402a26464b300100180c40620311332259800800c6600202100189802985400803202080d406a03501a42a4046eb4004c2880400a030853808c28004004c28c040090a101405109f011bab001809c04e026851008c27c0400509d011bae001309e01002427c0461380200284d008c26004dd5001c56600260d200313259800800c03e264b30010018084042021010899912cc00400602513259800800c04e027013809c4cc89660020030158992cc00400602d01680b405a264b300130a501003805c05d0a2011bae001429404614402002850008dd7000985080801214402309f010014274046eb8004c2780400909f01184e00800a13402309801375400700e42540484a808c25804dd5001402909501402a01500a8052132023096010014250046124026ea801a2b300130630018992cc00400601313259800800c02a01513259800984c80801c4cc0ec00489660020050078992cc0040063300100189801184e00801c039011403a01d00e807213a02309a0100242600500b4258046eb000601500a426404612c0200284a008c24804dd5003402108f01211e021330360012259800801402626464b3001001805402a01500a899912cc00400601900c8992cc00400601b13259800800c03a01d00e80744cc89660020030108992cc004006023011808c046264b300130a00100389805985000806404909d011bae001428004613a0200284d808dd7000984e00801213a02309a010014260046eb000601900c426c046eb8004c2500400909901184900800984a80801212602308f0137540090064244046eac00600b005802a12802309101001423c04612202005003801c00e006849008c23c0400508d011845809baa003800a110029843809baa04b8cc004896600200314bd7044cc23004c22404c23404004cc008008c2380400508b014896600260b66112026ea80062646611a0266ec0c23804004c23804c23c040052f5bded8c0611c026114026ea80062646600200264660020026eacc23c04c24004c23004dd5001912cc004006297ae08998478098468098480080099801001184880800a11c022259800800c52f5bded8c1132332233002002330070070012259800800c400e2661220261240200266004004612602002848008c24004008cc008008c2400400508d01210e029194c0040060054bd7020022225980080144006330010039848008014cc23804c23c04008005003211a029119846009ba90010029111919800800802112cc00400620091330033090010013300200230910100142380522259800982e9845009baa0038992cc00400600513259800800c00e007003801c4c966002612402007005802211e02375c002849008c23c0400508d011845809baa003800a110029843809baa04b912cc0040062900044c0d8cc008008c2380400508b01488c8cc00400400c896600200314bd6f7b63044c8ca60026eacc2380400a660080086124020072229800800c022b300159800983200244c19000e294108e014522010089b943371400800684700a00481090441bae308c01001308f0100142340523259800982e1844809baa0018992cc00400610a0313233032001225980080144c96600266e3cdd99ba60010078800c54cc234052401306578706563742063626f722e73657269616c6973652876616c756529203d3d2073657269616c697365645f76616c75650016423004602e0071323259800800c228061140308a0184500c4cc896600200308c0189981c1bab001225980080144c01cc2600402226464b300100184800c240061200309001899912cc004006124030920184900c4c8c018c2740401cdd6800c2480509d011bae001309601002426c04612802002612e0200484a80a1180308c0184600a12e02375c00261200200484a808c23804004c2440400908f011bab00184280c2140610a02848008c23404c22804dd5000c54cc2200524014465787065637420536f6d6528646573657269616c697365645f76616c756529203d2063626f722e646573657269616c6973652873657269616c697365645f76616c7565290016421c04601200291111111114c004c02802a601201322259800801466002007300b001a5eb8100344c96600200313259800801c400633001005998061806801800d2f5c08029098011bae3099010038cc0040126134020033300b00233046375c6132020066eb8c26404005004212e02309901002425805300300348888c8c8c8cc896600260da01b13232332298009851809851808014dd61851008014c28c04c28c040066eb8c28804005222298009bab30a6010049bac30a60130a70130a70130a70130a7010049853809853808014c29804009222232329800985680800cdd7185600800cdd618560080724453001375c615e02007375c615e026160026160020073232330010010032259800800c52f5c11332259800acc004cdd7985a009858809baa30b40130b50130b101375400400b1323300100132330010013756616c02616e026166026ea8c2d804c2dc04c2cc04dd5002112cc004006297ae0899199119198008009bab30b8010042259800800c400e26466178026e9ccc2f004dd48029985e00985c808009985e00985d00800a5eb80cc00c00cc2f804008c2f0040050ba011bae30b4010013300300330b90100230b70100142d40444b30010018a508acc004cdc79bae30b6013758616c0200201314a313300200230b70100142c00485a00a29410ae0144cc2cc04008cc010010006266008008002857008c2c804004c2cc040050b001182f8014c2bc04c2b004dd5037cdd7185780803cc2bc0401522222259800802427806264b300130b7010058992cc0040062b300130850130b301375400313259800800c28806264b30010018992cc0040061480313259800985e00801466002007159800800c566002611402616e026ea8006264b300100185380c4c9660020030a801899912cc0040061540313259800800c2ac06264b300130c201003899832002112cc00400a2660cc00644b30010028cc004c12c01664646600200203244b30010018a5eb841018000810180008101800044cc8966002600a0051330c901374e66192020046eb0c32804004cc32404c32804c32c04004cc32404c32804c32c04c32c040052f5c1159800acc004cdd79865009863809baa30ca0130cb0130c701375400402d1323300100132330010013756619802619a026192026ea8c33004c33404c32404dd5002112cc004006297ae0899199119198008009bab30ce010042259800800c400e264661a4026e9ccc34804dd480299869009867808009986900986800800a5eb80cc00c00cc35004008c348040050d0011bae30ca010013300300330cf0100230cd01001432c0444b30010018a508acc004cdc79bae30cc01375861980200203314a313300200230cd0100143180486500a29410c40144cc32404c32804004cc32404dd399864808011bac30ca0130cb01001330c90130ca0130cb0130cb010014bd7044cc32404c32804004cc32404c32804c32c04004cc32404dd399864808011bac30ca0130cb0130cb010014bd7021880243100461900200266004004619202002863008cc17403405a64646600200204844b30010018a5eb841018000810180008101800044cc8966002600a0051330c901374e66192020046eb0c32804004cc32404c32804c32c04004cc32404c32804c32c04c32c040052f5c1159800acc004cdd79865009863809baa0020168991980080099198008009bab30cc0130cd0130c901375400844b30010018a5eb82264664464660020026eacc338040108966002003100389919869009ba7330d201375200a661a402619e02002661a40261a00200297ae03300300330d40100230d2010014340046eb8c32804004cc00c00cc33c04008c334040050cb01112cc00400629422b30013371e6eb8c33004dd618660080080cc528c4cc008008c334040050c6012194028a504310051330c90130ca01001330c901374e66192020046eb0c32804c32c04004cc32404c32804c32c04c32c040052f5c11330c90130ca01001330c90130ca0130cb01001330c901374e66192020046eb0c32804c32c04c32c040052f5c08620090c40118640080099801001186480800a18c023305c00d016488a6002660bc609c01660b400730c9010029bac30c801002986480800cdd6186400800a4444530013758619a020053758619a02619c02005309b0130353758619a02619c020093758619a020089111192cc00400a17e0313259800986a00801c56600200d0c1018992cc004c3540401e264b3001598008034528c54cc340052401176e6f5f6f746865725f696e70757473203f2046616c73650014a086780a2b3001598008024528c54cc3400524011e69735f7769746864726177616c5f6665655f70616964203f2046616c73650014a086780a2b300159800992cc004006330010018992cc004006330010018cc004dd7186b80986a009baa0029bae30d70130d4013754003376603f30d301375404a9111192cc004c2ac0400a266e3e60020030039bb3374c029375861b80261b2026ea80a9056002456600261540200513232332259800acc0066002660ec6098002031374c6098005223370e00400285080a29462a661b60292011a69735f62616c616e63655f75706461746564203f2046616c73650014a086d00a2b30013371f3001005803cdd6187000987080801c00600482c802229462a661b6029211e69735f6e65775f62616c616e63655f636f7272656374203f2046616c73650014a086d00a29410da011bae30de01001375c61bc0200461bc0200261b2026ea80aa29410d60121ac0230800100443340504743340619a030cd0186680a1b20232598009851809869809baa0018986b80986a009baa0018a9986900a4812c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001643440461ac0261ae0261ae0261a6026ea800e196028232196030cb0186580c32c050d801192cc004c28804c34804dd5000c4c35804c34c04dd5000c54cc3440524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001643400461aa0261ac0261ac0261a4026ea8c35404c35804c34804dd5001c528c54cc3400524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a086780a2b30015980099baf374c613402660d6660d665300100180652f5bded8c080088896600200510018cc00400e61b202005329800800c00a6eacc36404c36804c35804dd5186c80986d00986b009baa30d9010034004444b30010028800c4c8cc8a600200d30df010059919800800802912cc0040062661be0266ec0dd48021ba60034bd6f7b63044ca60026eb8c374040066eacc3780400661c4020049112cc004cdc8004001c4cc38c04cdd81ba9008374c00e00b15980099b8f0080038992cc004c2d004c38404dd5000c4cc39004cdd81ba900930e50130e20137540020051002437c0464b300159800800c528c52821c6028a60103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011833994c0040060114bd6f7b6302002222598008014400633001003986c808014ca60020030029bab30d90130da0130d601375461b202006800888966002005100189919914c00401a61be0200b32330010010052259800800c4cc37c04cdd81ba9004374c00697adef6c608994c004dd7186e80800cdd5986f00800cc388040092225980099b900080038998718099bb037520106e9801c0162b30013371e01000713259800985a009870809baa0018998720099bb0375201261ca0261c4026ea800400a200486f808c966002b30010018a518a50438c0514c103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011833994c0040060154bd6f7b6302002222598008014400633001003986c808014ca60020030029bab30d90130da0130d601375461b202006800888966002005100189919914c00401a61be0200b32330010010052259800800c4cc37c04cdd81ba9004374c00697adef6c608994c004dd7186e80800cdd5986f00800cc388040092225980099b900080038998718099bb037520106e9801c0162b30013371e01000713259800985a009870809baa0018998720099bb0375201261ca0261c4026ea800400a200486f808c966002b30010018a518a50438c0514c103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011ba60018a518a9986800a4812569735f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a086780a2b300159800cc0040be6e98c19ccc1acc26804dd59850009869009baa30a00130d2013754040003223370e00400284b00a29462a661a0029211769735f746f6b656e735f6275726e74203f2046616c73650014a086780a2b3001323300100102f2259800800c528456600266e3cdd7186b808008194528c4cc008008c360040050d10121aa028a518a9986800a492669735f68796472615f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a086780a29410cf014528219e028a50433c0514a086780a29410cf01184c80998208060124308050d20118698080321a20286000a1a20230d201002434004b30010038a518acc004c3480400e264b300100185f00c4c96600261a80200519800984c0099820007011cdd3184c009bab309e0130d0013754003223370e00400284a00a17e02868808c348040050d001191919800800802912cc004006297ae0899912cc004c01400a2661aa020046600800800313300400400143400461a80200261aa02002869008cc1a00a008a2a6619802920118756e6578706563746564206f74686572206f7574707574730014a08678090cf010899192cc004006164030b20185900c2c80626644b300100185a00c4cc1b0dd5800912cc00400a2600e6198020111323259800800c2e006170030b80185c00c4cc89660020030ba0185d00c2e806264600c61a20200e6eb400617402868808dd7000986500801219e0230c80100130cb010024324050b40185a00c2d0050cb011bae00130c401002432404618402002618a0200486180a26464b300100185800c2c006160030b001899912cc0040061640313306a375600244b30010028980398650080444c8c9660020030b60185b00c2d80616c031332259800800c2e006170030b80189918031867808039bad00185c00a19e02375c002619002004866808c31804004c324040090c70142c806164030b2014324046eb8004c308040090c70118600080098618080121820285600a17e0237560030ab0185580c2ac050c201185f80800a17a023756002617c020050a80185400c2a0050bf01185e00800a1740230b80137540030a60142d4050a60185300c2980614c0285e80a14a0283ba14a0285c808c2e8040050b801185d00801428c06146030a30185180a1760230b80100142d8046168026ea80061420285880a142030a10185080c284050b901192cc004c20c04c2cc04dd5000c4c2dc04c2d004dd5000c54cc2c8052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642c404616c02616e02616e026166026ea8c2d804c2dc04c2cc04dd5000c27c050b401185a808022166020c2b004c2b004c2b004004c2ac0400830a101001309d013754660b66eb0c2800400426404c28004004c26c04dd5032456600260d801b13232332298009851809851808014dd61851008014c28c04c28c04c28c04c28c040066eb8c28804005222298009bab30a6010049bac30a60130a70130a70130a70130a7010049853808014dd71853008012444465300130ac010019bae30ab010019bac30ab0100d488a60026eb8c2b80400e6eb8c2b804c2bc04c2bc0400e64646600200200644b30010018a5eb8226644b30015980099baf30b30130b00137546166026168026160026ea80080162646600200264660020026eacc2d404c2d804c2c804dd5185a80985b009859009baa0042259800800c52f5c1132332232330010013756616e0200844b30010018801c4c8cc2ec04dd39985d809ba9005330bb0130b801001330bb0130b9010014bd7019801801985e80801185d80800a17202375c61660200266006006617002004616c0200285a008896600200314a115980099b8f375c616a026eb0c2d4040040262946266004004616c020028578090b3014528215a028998590080119802002000c4cc0100100050ad01185880800985900800a15e02305e0029857009855809baa06e985700803244444b300100384e00c4c966002616a0200913259800800c5660026106026162026ea8006264b300100185000c4c96600200313259800800c28806264b300130ba010028cc00400e2b30010018acc004c21c04c2d404dd5000c4c9660020030a9018992cc0040061540313259800985e80801c4cc17c00489660020051332298009860808014dd61860008014c304040066eb0c30004005222298009bac30c40100298490098161bac30c40130c50100498498098161bac30c40130c5010029bac30c40100448889660020030b5018992cc004c3280400a2b300100585b80c4c96600261960200d13259800acc00401a29462a6618c02921176e6f5f6f746865725f696e70757473203f2046616c73650014a086280a2b300159800802c528c54cc318052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a086280a2b30015980099912cc004006330010018992cc004006330010018cc004dd71867009865809baa0029bae30ce0130cb013754003376603130ca01375403a9111192cc004c27c0400a266e3e60020030039bb3374c011375861a60261a0026ea808904b002456600261420200513232332259800cc004cc1b4c10c004c1a40326e98c10c00a4466e1c0080050980144cdc7cc00401600f375861ae0261b00200700180120a00088a504344046eb8c35404004dd7186a80801186a808009868009baa0228a50433404866808c1dc0110c40140f90c40186200c3100618802868008c9660026134026194026ea80062619c026196026ea80062a66192029212c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016432004619a02619c02619c026194026ea80121840281ea184030c20186100c308050cf011828808192cc004c26004c32004dd5000c4c33004c32404dd5000c54cc31c052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d00164318046196026198026198026190026ea8c32c04c33004c32004dd5001c528c54cc3180524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a086280a2b30015980099baf374c612002660c260ac01060ba60ae0146e9800629462a6618c029212c69735f63616e63656c5f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a086280a2b300159800cc0040966e98cc184c174c24004dd5984b009864009baa30960130c8013754030003223370e00400284600a29462a6618c029211d69735f6d696e745f76616c75655f636f7272656374203f2046616c73650014a086280a2b300132330010010252259800800c528456600266e3cdd71866808008144528c4cc008008c338040050c7012196028a518a9986300a492d69735f68796472615f63616e63656c5f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a086280a29410c5014528218a028a5043140514a086280a29410c5011981b982800780dc2e0050c801186480802a18e0285b00a18e0230c801001431804194c00404a97ae10101800081018000810180004896600260060051330c001374e66180020046eb0c30404004cc30004c23004004cc30004c22c040052f5c1159800acc004cdd7986080985f009baa308c0130be01375400401f1323300100130703756611a02617e026ea8c23404c2fc04dd5001912cc00400629422b30013371e6eb8c30c04dd618618080080d4528c4cc008008c310040050bd012182028a5042ec051330c00130c101001330c001374e66180020046eb0c23004004cc30004c22c040052f5c11330c00130c101001330c001308c01001330c001374e66180020046eb0c22c040052f5c085d8090bb0120603305600801032323300100101d2259800800c52f5c21018000810180008101800044cc8966002600a0051330c201374e66184020046eb0c30c04004cc30804c30c04c31004004cc30804c30c04c31004c310040052f5c1159800acc004cdd79861809860009baa0020118991980080099198008009bab30c50130c60130c201375400844b30010018a5eb82264664464660020026eacc31c040108966002003100389919865809ba7330cb01375200a6619602619002002661960261920200297ae03300300330cd0100230cb010014324046eb8c30c04004cc00c00cc32004008c318040050c401112cc00400629422b30013371e6eb8c31404dd618628080080e4528c4cc008008c318040050bf012186028a5042f4051330c20130c301001330c201374e66184020046eb0c30c04c31004004cc30804c30c04c31004c310040052f5c11330c20130c301001330c20130c30130c401001330c201374e66184020046eb0c30c04c31004c310040052f5c085e8090bd0118608080099801001186100800a17e0233055008010899192cc00400615e030af0185780c2bc0626644b300100185880c4cc194dd5800912cc00400a2600e618a020111323259800800c2d40616a030b50185a80c4cc89660020030b70185b80c2dc06264600c61940200e6eb400616e02865008dd700098618080121900230c10100130c4010024308050b10185880c2c4050c4011bae00130bd01002430804617602002617c0200485e00a1560285d008dd5800c2a806154030aa0142f40461740200285c008c2d804dd5000c2a0050b30142a006150030a80185400a1760285180a0ea85180a16e0230b80100142d8046170020050a10185080c284061420285c808c2d8040050b4011859009baa00184f80a15e0284f80c27c0613e0309f0142dc0464b300130810130b1013754003130b50130b201375400315330b0014913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642bc04616802616a02616a026162026ea8c2d004c2d404c2c404dd5000c274050b201185980801a162020c2ac04c2ac04c2ac0400830a101001309d013754660b66eb0c2800400426404c28004004c26c04dd5032456600260d401b132323298009bae30a10130a20130a20130a20130a20130a20130a20130a20130a20130a201001985080984f009baa06198510080124446644b30015980098209853009853808014528c54cc284052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085000a2b3001598009820985300985380800c528c54cc284052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085000a2b30015980099baf374c60d66530010019bac30a701003a5eb7bdb1810011112cc00400a200319800801cc2a80400a6530010018014dd59855009855809853809baa30aa0130ab0130a7013754615402006800888966002005100189919914c00401a61600200b32330010010052259800800c4cc2c004cdd81ba9004374c00697adef6c608994c004dd7185700800cdd5985780800cc2cc040092225980099b9000800389985a0099bb037520106e9801c0162b30013371e010007132598009842809859009baa00189985a8099bb03752012616c026166026ea800400a2004858008c966002b30010018a518a5042d00514c0103d87a800089841809985a809ba60014bd70216002329800800c022006800888966002005100189919914c00401a61780200b32330010010052259800800c4cc2f004cdd81ba9004375000697adef6c608994c004dd7185d00800cdd6985d80800cc2fc040092225980099b900080038998600099bb037520106ea001c0162b30013371e01000713259800984880985f009baa0018998608099bb03752012618402617e026ea800400a200485e008c96600261220200314c0103d87a8000898478099860809ba80014bd702178023370000e0051330c001337606ea400cdd400119803003000a1760242ec0430bd0100142ec048030dd7185a808009bad30b60100130b80100242d8051330b401337606ea400cdd300119803003000a15e0242bc0430b10100142bc048030dd71854808009bab30aa0100130ac0100242a80480190a7011ba6306b329800800cdd618538080152f5bded8c080088896600200510018cc00400e615402005329800800c00a6eacc2a804c2ac04c29c04dd5185500801a002222598008014400626466453001006985800802cc8cc00400401489660020031330b001337606ea4010dd3001a5eb7bdb1822653001375c615c020033756615e0200330b30100248896600266e4002000e2661680266ec0dd48041ba60070058acc004cdc7804001c4c966002610a026164026ea800626616a0266ec0dd4804985b009859809baa00100288012160023259800acc004006294629410b4014530103d87a800089841809985a809ba60014bd70216002329800800c022006800888966002005100189919914c00401a61780200b32330010010052259800800c4cc2f004cdd81ba9004375000697adef6c608994c004dd7185d00800cdd6985d80800cc2fc040092225980099b900080038998600099bb037520106ea001c0162b30013371e01000713259800984880985f009baa0018998608099bb03752012618402617e026ea800400a200485e008c96600261220200314c0103d87a8000898478099860809ba80014bd702178023370000e0051330c001337606ea400cdd400119803003000a1760242ec0430bd0100142ec048030dd7185a808009bad30b60100130b80100242d8051330b401337606ea400cdd300119803003000a15e0242bc0430b10100142bc048030dd71854808009bab30aa0100130ac0100242a80480190a7014528c54cc2840524011e69735f6163636f756e745f76616c75655f657175616c203f2046616c73650014a085000a2b3001323233001001375861500261520261520261520261520261520261520200a44b30010018a508acc004cdc79bae30a9010010038a51899801001185500800a14602429c046eb8c2980401a29462a661420292012d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085000a29410a00145282140028a504280046466446600400400244b30010018a5eb8410180008101800044cc8966002600a0051330a801374e66150020046eb0c2a404004cc2a004c2a404c2a8040052f5c11330a80130a901001330a801374e66150020046eb0c2a404c2a8040052f5c0851808c29c04004cc008008c2a0040050a5011bac30a5010073303c002003323322330020020012259800800c52f5c210180008101800044cc8966002600a0051330a801374e66150020046eb0c2a404004cc2a004c2a404c2a8040052f5c11330a80130a901001330a801374e66150020046eb0c2a404c2a8040052f5c0851808c29c04004cc008008c2a0040050a5011bac30a5010023303b002003184e809baa3305b3758614002002132026140020026136026ea81922b3001306700d8991919914c004c28c04c28c0400a6eb0c2880400a614602614602614602614602614602614602614602614602003375c61440200291114c004dd59853008024dd61853009853809853809853809853808024dd71853008014dd71853009853808014dd618530080424444464b300100184a80c4c966002615c0200513259800800c56600260f86154026ea8006264b300100184f80c4c96600200313259800800c28406264b300130b3010028cc00400e2b30010018acc004c1f8c2b804dd5000c4c9660020030a4018992cc004006264b300100185300c4c9660020030a7018992cc004c2e00400e3300100489982d000912cc00400a2664466446644b300159800982d1ba73233001001375861800261820200a44b30010018a5eb8226644b30013375e6186026180026ea8c30c04c31004c30004dd5001002c4cc30804008cc01001000626600800800285e808c30404004c308040050bf014528c54cc2e80524011f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a085c80a2b300159800982d1ba73233001001375861800261820200844b30010018a5eb8226644b30013375e6186026180026ea8008016266184020046600800800313300400400142f40461820200261840200285f80a29462a6617402921206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a085c80a2b300159800acc004cdd79ba630840133055304b3758617e0200c60a260946eb0c2fc04014dd300144cdd79ba6002374c608a01314a085c80a29462a66174029211a69735f76616c7565735f6d61746368696e67203f2046616c73650014a085c80a2b300159800991980080080c912cc00400629422b30013371e6eb8c30404004072294626600400461840200285d8090bf014528c54cc2e8052412d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085c80a2b3001980080ccdd318289842009bab308a0130bc0137546114026178026ea804e4466e1c008005080014528c54cc2e80524011d69735f696e74656e745f746f6b656e5f6275726e74203f2046616c73650014a085c80a29410b90145282172028a5042e40514a085c808c20804cc14cc120dd6185e80800982798249bac30bd01002306d01430bc0100230bc01001332232330010010122259800800c52f5c3018000810180008101800044cc8966002600c0051330be01374e6617c020046eb0c2fc04004cc2f804c2fc04c30004004cc2f804c2fc04c30004c300040052f5c1159800980280144cc2f804c2fc04004cc2f804dd39985f008011bac30bf0130c001001330be0130bf0130c00130c0010014bd7044cc2f804c2fc04004cc2f804c2fc04c30004004cc2f804dd39985f008011bac30bf0130c00130c0010014bd7021720242e404617a0200266004004617c0200285d808cc144028040cc144018040cc88c8cc004004064896600200314bd7081018000810180008101800044cc8966002600c0051330be01374e6617c020046eb0c2fc04004cc2f804c2fc04c30004004cc2f804c2fc04c30004c300040052f5c1159800980280144cc2f804c2fc04004cc2f804dd39985f008011bac30bf0130c001001330be0130bf0130c00130c0010014bd7044cc2f804c2fc04004cc2f804c2fc04c30004004cc2f804dd39985f008011bac30bf0130c00130c0010014bd7021720242e404617a0200266004004617c0200285d808cc140028040cc14001804226464b300100185600c2b006158030ac01899912cc00400615c03133060375600244b30010028980398600080444c8c9660020030b20185900c2c806164031332259800800c2d006168030b40189918031862808039bad00185a00a18a02375c002617c02004861808c2f004004c2fc040090bd0142b80615c030ae0142fc046eb8004c2e0040090bd01185b00800985c80801216e0285400a0e685400a16a0237560030a70185380c29c050b801185a80800a1660230b50100285280c2940614a030a50142d804616602002858808c2bc04dd5000c28c050ac01428c06146030a30185180a1680285100a0dc85100a1600230b10100142bc046162020050a00185000c2800614002859008c2bc040050ad011855809baa00184f00a1500284f00c2780613c0309e0142c00464b3001307a30aa013754003130ae0130ab01375400315330a90149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642a004615a02615c02615c026154026ea8c2b404c2b804c2a804dd5000c258050ab01185600800a154023232330010010032259800800c52f5c11332259800acc004cdd79858009856809baa30b00130b10130ad01375400400b1323300100132330010013756616402616602615e026ea8c2c804c2cc04c2bc04dd5002112cc004006297ae0899199119198008009bab30b4010042259800800c400e26466170026e9ccc2e004dd48029985c00985a808009985c00985b00800a5eb80cc00c00cc2e804008c2e0040050b6011bae30b0010013300300330b50100230b30100142c40444b30010018a508acc004cdc79bae30b201375861640200201514a313300200230b30100142b00485800a29410aa0144cc2bc04008cc010010006266008008002855008c2b804004c2bc040050ac01182d8018614202002613a026ea8cc16cdd618500080084c80985000800984d809baa0648acc004c0e803633001309b013754613c026136026ea817a4444b30010018801c4c966002007153309e0149012a6e6f7420656e6f756768206b65792d76616c756520706169727320746f206d617463682070726f6f667300168992cc004c1c0c28004dd500146600200d9800802cdd7185000800cdd7185080800cdd61852009850809baa002407130a501004985280801a00c8a9984f80a4930657870656374204d504644656c657465207b2070726f6f663a2064656c6574655f70726f6f66207d203d2070726f6f660016427804614602006850808c288040050a0014c26c04dd5032244530013002002985080801cdd5985080985100801cc2880400522223232329800985480985480985480985480800cc2a0040066eb8c2a00400922298009bae30ab0130ac0130ac01003982d9bae30ab0100399198008009bac30ac0100c2259800800c52f5c11332259800acc004cdd79857809856009baa30af0130b00130ac01375400400d1307d3259800983f1856009baa0018a40011375a616002615a026ea80050aa01192cc004c1f8c2b004dd5000c5300103d87a8000899198008009bab30b10130ae01375400444b30010018a6103d87a8000899192cc004c214040062b30013084010018984080998598098588080125eb82298103d87a800042b80513300400430b50100342b8046eb8c2bc04004c2c8040050b00121540232330010013756616002616202615a026ea8c2c004c2c404c2b404dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062610002661640261600200497ae08a60103d87a800042b40513300400430b40100342b4046eb8c2b804004c2c4040050af0145282152028998570080119802002000c4cc0100100050a901185680800985700800a156029bac30ab0130ac010079bae30ab0100648888966002007094018992cc004c2c804012264b3001307e30ae01375400313259800800c566002610402615e026ea8006264b300100185300c4c9660020030a70185380c29c0614e0313259800985b80801c4c96600200309d018992cc004c2e40400a264b300130850130b501375400313259800800c660020031323259800acc004cdd79ba63301f375660dc6172026ea820804cc2ec04dd4808a5eb80c2f004c2f40400a29462a6616e029211769735f76616c75655f6d696e746564203f2046616c73650014a085b00a2b30015980099198008009bac306e30ba0137541060244b30010018a508acc004cdc79bae30be0100100f8a51899801001185f80800a1700242f00514a315330b70149011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085b00a2b300159800984580985c009baa01a8992cc0056600266e3cc08400402229462a6617002920134636f6d707574655f747265655f68617368287472656529203d3d20696e7075745f6d65726b6c655f726f6f74203f2046616c73650014a085b80a2b30015980099baf374c604e0026e9800a29462a66170029212f6b65795f76616c756573203d3d206f75747075745f6d65726b6c655f7265636f72645f6c697374203f2046616c73650014a085b80a2b30013371e6eb8c2f404c2e804dd5002245200000000000000000000000000000000000000000000000000000000000000000008a518a9985c00a494d6f75747075745f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085b80a29410b7014528216e0230bc0130b901375403513371e60c26eb8c2f004c2e404dd5001cc004c18401e00337586178026172026ea806901b216c028a518a9985b80a4811769735f747265655f75706461746564203f2046616c73650014a085b00a29410b6014528216c0237566176020033001323300100100d2259800800c52f5c1133225980099baf30be0130bb0137540040251330bd0100233004004001899802002000a1700230bc0100130bd0100142e8054bd708101a0008101a000488c9660026112026172026ea800626644b30010018cc00400626617c026e98cc2f804cdd81ba937660026ea4dd99ba60023756617e020086617c026e98cc154dd5984500802198111bab308a0130bc01375400a6617c026ea40512f5c097ae085980a0f685980c2cc06166030b301430405300137566110026174026ea800e02501a4108617a026174026ea80062a66170029212f65787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206f75747075742e646174756d001642dc04610c026172026ea800902b42b40502a42b40615a030ad0185680a1780230b90130b60137540030a00142cc04610402616a026ea800613c0285b008c2dc040050b5011919800800804912cc004006297ae0899912cc0056600266ebcc2e804c2dc04dd5001008c4c22004c966002611202616e026ea80062900044dd6985d80985c009baa00142d40464b300130890130b701375400314c0103d87a8000899198008009bab30bc0130b901375400444b30010018a6103d87a8000899192cc004c240040062b3001308f0100189846009985f00985e0080125eb82298103d87a800042e40513300400430c00100342e4046eb8c2e804004c2f4040050bb01216a02323300100137566176026178026170026ea800c896600200314c103d87a8000899192cc004cdc880a000c56600266e3c05000626116026617a0261760200497ae08a60103d87a800042e00513300400430bf0100342e0046eb8c2e404004c2f0040050ba01452821680289985c8080119802002000c4cc0100100050b401185c00800985c80800a16c0285400a16802375c00285b808c2d0040050b2011858009baa00185280a15a0285280c2940614a030a50142d404616402615e026ea80062a6615a0292014665787065637420496e6c696e65446174756d28747265655f726f6f7429203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642b00460f6615c026ea8c1f0c2b804dd5000c254050af01185800801a15c020c2a004004c29c04c29c04c29c04c29c04004c28804dd5198301bac30a50100109e01233001309b013754613c026136026ea817a4444b30010018801c4c966002007153309e01491256e6f7420656e6f756768206b65792d76616c75657320746f206d617463682070726f6f667300168992cc004c1ccc28004dd500146600200d9800802cdd7185000800cdd7185080800cdd61852009850809baa002407930a501004985280801a00c8a9984f80a4930657870656374204d5046496e73657274207b2070726f6f663a20696e736572745f70726f6f66207d203d2070726f6f660016427804614602006850808c288040050a0014c26c04dd5032244530013002002985080801cdd5985080985100801cc288040066eb0c2840400522222332298009854809854808014dd61854008014c2a404c2a404c2a404c2a4040066eb8c2a004005222298009bab30ac010049bac30ac0130ad0130ad0130ad0130ad010049856808014dd71856008012444466446465300137566168020033756616802616a0200332330010010102259800800c52f5c11332259800acc004cdd7985c00985a809baa30b80130b90130b501375400400f13086013259800984380985a809baa0018a40011375a617202616c026ea80050b301192cc004c21c04c2d404dd5000c530103d87a8000899198008009bab30ba0130b701375400444b30010018a6103d87a8000899192cc004c238040062b3001308d0100189845009985e00985d0080125eb82298103d87a800042dc0513300400430be0100342dc046eb8c2e004004c2ec040050b90121660232330010013756617202617402616c026ea8c2e404c2e804c2d804dd5001912cc004006298103d87a8000899192cc004cdc8806800c56600266e3c0340062611202661760261720200497ae08a60103d87a800042d80513300400430bd0100342d8046eb8c2dc04004c2e8040050b801452821640289985b8080119802002000c4cc0100100050b201185b00800985b80800a1680248896600200309b018992cc004c2e40400a264b300130850130b501375400313259800800c6600200313259800800c28406264b300130bd010028992cc004c22404c2e404dd5000c4c96600200319800800c566002b30013375e6e98048dd3004c528c54cc2e40524011669735f76616c75655f6275726e74203f2046616c73650014a085c00a2b3001598009919800800809112cc00400629422b30013371e6eb8c30004004056294626600400461820200285d0090be014528c54cc2e4052411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085c00a2b300159800984680985d009baa01c8992cc0056600266e3cdd7185f80985e009baa006489200000000000000000000000000000000000000000000000000000000000000000008a518a9985d00a4950696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085c80a2b30015980099b8f3023001375c617e026178026ea800a29462a66174029215f636f6d707574655f747265655f68617368287472656529203d3d206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203f2046616c73650014a085c80a2b30013375e6e98c0a4004dd31919800800806112cc004006297adef6c60899191980080099802002186200801912cc0040062661860200697adef6c608992cc004cdd799912cc004cdc8001000c530103d87980008acc004cdc7801000c530103d87a80008a6103d87b8000430404860808dca1bae30c10100437286eb8c3040400530103d87980008998620080200144cc31004004cc00c00cc318040090bf01186200800a1840230c10100142fc0514a315330ba014913c657874726163745f6b65795f76616c756573287472656529203d3d20736f727465645f73657269616c697365645f696e70757473203f2046616c73650014a085c80a29410b901452821720230be0130bb01375403913371e60c66eb8c2f804c2ec04dd5000cc004c18cdd7185f00985d809baa0058054dd6185f00985d809baa01c407485c00a29462a661720292011769735f747265655f75706461746564203f2046616c73650014a085c00a29410b801452821700285300a05c85300c2980614c030a601430004617a026174026ea80061480285b808c21804c2e404dd5000c288050ba01185d80800a1720232330010010122259800800c52f5c11332259800acc004cdd7985f00985d809baa00200d8984600992cc004c23404c2ec04dd5000c5200089bad30bf0130bc01375400285c808c966002611a026176026ea8006298103d87a8000899198008009bab30c00130bd01375400444b30010018a6103d87a8000899192cc004c250040062b30013093010018984800998610098600080125eb82298103d87a800042f40513300400430c40100342f4046eb8c2f804004c304040050bf0121720232330010013756617e026180026178026ea800c896600200314c103d87a8000899192cc004cdc8809800c56600266e3c04c0062611e026618202617e0200497ae08a60103d87a800042f00513300400430c30100342f0046eb8c2f404004c300040050be01452821700289985e8080119802002000c4cc0100100050b801185e00800985e80800a1740284f80a05484f80c27c0613e0309f0142f004617202616c026ea80062a66168029214865787065637420496e6c696e65446174756d28696e7075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642cc04610402616a026ea8c20c04c2d404dd5000c270050b601185b80800a16a024c004c8c8cc004004040896600200314bd7044cc8966002600a0051330b70100233004004001899802002000a1640230b60100130b70100142d00446466ebcc2d404c2c804dd5185a80985b009859009baa0020013064375c6168020094bd70901a0008101a000488c9660026104026164026ea800626644b30010018cc00400626616e026e98cc2dc04cdd81ba937660026ea4dd99ba600237566170020086616e026e98cc138dd598418080218251980d9bab30830130b5013754610602616a026ea8014cc2dc04dd480325eb812f5c109b0141d109b0184d80c26c061360285d00a60026eacc20404c2cc04dd51840809859809baa003802404d03b185b009859809baa0018a9985880a4813465787065637420496e6c696e65446174756d28696e7075745f646174756d29203d20696e7075742e6f75747075742e646174756d001642c00460fe6164026ea8c20004c2c804dd50012048375c6164026166026166020046162026162026162026162020046160020041853808011851809baa330613758614c0200413e0221300242600484c009098012130022980091000c0069101004008446466002002601400644b30010018a5eb7bdb18226644b300132330010010062259800800c528456600266e3cdd71852008008024528c4cc008008c2940400509e012144028cc004cc15801800a0032229800800c01600700240c882aa200284e008dd718500080099801001185080800a13c023001001223300122225980099b87002480822009132598009837984e809baa0018cc00401e4400533013005489200000000000000000000000000000000000000000000000000000000000000000008024c12800e004803a26464b30013371000200b153309e0149012e696e76616c696420747265652c206368696c6472656e206d75737420626520736f7274656420627920696e64657800168992cc004c1ccc28004dd5000c56600266e1c01800a3300100a910014cc058022600201522001985080801ccdc5002cc00528d20028032f2480526eacc29004c28404dd5000cc13401a00a80523300100a910014cc058021220120000000000000000000000000000000000000000000000000000000000000000000803cc13401a00a805109e01454cc27c052412a65787065637420536f6d65287461696c5f6e6f64657329203d206c6973742e7461696c286e6f646573290016427804b30010068a6103d87a80008983819851009ba630a4010064bd702142024274046eb4c27804004c8cdd81851008009851009851808009bac30a101309e01375400284d8096600200714c103d87a8000898369984f80991ba7330a001309d01001330a001309e010014bd70185000801a5eb8109e0121340222598009836984d009baa0028991919826800992cc0040062a661380292012e696e76616c6964206368696c64206861736865732c206d7573742062652061206e6f6e2d656d707479206c69737400168acc004c2880400626eb8c2840400626601000297ae0427c0484f808c04e600200d22002a5eb826eacc28004c2840400a90004cdc5001800a00c375c613e020026136026ea800a264646644b3001980099b8f37280040034a14a284e00a2a6613a0266e59241056b65793a20003732660406ea4009220100153309d013372c920106706174683a20003732660406ea4005220100153309d014912d696e76616c696420747265652c2070617468206973206e6f74207468652068617368206f6620746865206b65790016899192cc004cdc7800803c4cc144cc0dc00c008dca1bae30a40130a5010058a9984f8099b964910e706174685f6e6962626c65733a20003732660446ea4005220100153309f013372c9201107072656669785f6e6962626c65733a20003732660446ea401d220100153309f0149128696e76616c696420747265652c2070726566697820646f6573206e6f74206d61746368207061746800164278053001002a400100140dc6e3401509c011bae30a001001375c6140020046140020026136026ea800909801180100109112cc004c17400a264b300100180344c966002003159800984880801466002003003803a00c803a11c02803c01e00f007424804611e02002846808c22c04dd5027456600260b800513259800800c01a264b30010018acc004c2440400a33001001801c01d006401d08e01401e00f007803a12402308f010014234046116026ea813a2b3001305a0028992cc00400600d13259800800c56600261220200519800800c00e00e826200e84700a00f007803c01d09201184780800a11a02308b01375409d159800982b80145660026116026ea813a00300542300515980099b874802000a264b300100180344c966002003159800984880801466002003003803a00a803a11c02803c01e00f007424804611e02002846808c22c04dd50274566002605400513259800800c01a264b30010018acc004c2440400a33001001801c01d005401d08e01401e00f007803a12402308f010014234046116026ea813a00a84400908801211002422004844009088010888c96600260ba00313259800800c00e264b30010018024012264b300130920100389981a000912cc00400a01113259800800c6600200313002309501003804206c804402201100842580461260200484880a00a847808dd6000c012008849008c23c0400508d011845809baa0048acc004c170006264b3001001801c4c96600200300480240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01513259800984c00801c4cc0e8004896600200500e8992cc0040063300100189801184d80801c03903c403a01d00e807213802309901002425c0500b4254046eb000601500a426004612a02002849808dd7000984a00801212a023092010014240046eb8004c2440400909201184780800a11a02308b013754009159800982d000c4c9660020030038992cc0040060090048992cc004c2480400e26606800244b300100280444c96600200319800800c4c008c2540400e01081b2011008804402109601184980801212202802a11e023758003004802212402308f010014234046116026ea8012004844009088012110023089013754007001800c00600284600856600209319800911192cc004c170006264b3001001801c4c96600200300480244c96600261220200713303300122598008014022264b30010018cc0040062600461280200700840d5008804402201084a808c2480400909001401508e011bac001802401109101184700800a11802308a013754009159800982d800c4c9660020030038992cc004006009004802401226644b300100180344c966002003007803c4c9660026128020071330360012259800801402e264b30010018cc00400626004612e0200700b40e100b805c02e01684c008c25404009093014021091011bac001803c01d09401184880800a11e02375c002612002004848808c2380400508c011845009baa0048acc004c164006264b3001001801c4c96600200300480244cc89660020030068992cc00400600f007803c01e264b300130940100389981b002112cc00400a01713259800800c6600200313002309701003805a070805c02e01700b426004612a0200484980a010848808dd7000a12802309101001423c046eb0004c2400400a009004424404611c02002846008c22804dd5002400908701210e02421c046110026ea800e3300123259800982d1843809baa0018992cc004cdc39bad308c01308d01308d010014800626eb8c230040062a6610e0292115657870656374207175616e74697479203d3d202d3100164218046eb0c22c04c22004dd5000c54cc2180524019d65787065637420536f6d652828706f6c6963795f69642c205f61737365745f6e616d652c207175616e746974792929203d0a202020206c6973742e66696e64280a2020202020206d696e742c0a202020202020666e28656e74727929207b0a20202020202020206c657420285f2c205f2c2071747929203d20656e7472790a2020202020202020717479203c20300a2020202020207d2c0a20202020290016421404646600200200444b30010018a60103d87a80008992cc004cdc41bad308d01308e01308e0100148002260b466118026e9c0052f5c1133003003308e01002421c046eb0c2300400508a0148896600260b66110026ea800e264b300100180144c966002003003801c00e0071332259800800c016264b3001001803401a00d006899912cc00400601113259800800c026013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f1332259800800c046264b3001001809404a025012899912cc00400602913259800800c05602b01580ac4cc89660020030178992cc00400603101880c406226644b300100180d44c96600200313259800800c072264b300100180ec07603b1332259800800c07e264b300100181040820411332259800800c08a264b3001001811c08e26644b3001001812c4c96600200313259800985780800c56600266e25200430ae01001813c4cc89660020030298992cc00400605502a81544cc896600200302c8992cc00400605b02d816c4cc896600200302f8992cc00400606103081844cc89660020030328992cc004006067033819c0ce26644b300100181ac4c96600200303681b40da264b300130c3010038cc0040762660ca02844b300100281d44c96600200303a81d40ea075132300330c701004375c002863808c310040090c20140dd07e40dd0c0011bad00181b21860230c00100142f8046eb8004c2fc040090c001185e80800a17602375a00261780200503042f40461740200285c008dd6800985c8080140b50ba01185b80800a16a02375a002616c0200502a42dc04616802002859008c20004c2b804004c2cc0400d0ac01409d0b0011baa001813409a04d02642cc04616002002857008dd6000985780801408e046858008c2b4040050ab011bad00130ac01002810215a0230aa0100142a0046eb4004c2a40400a03a855008c29c040050a501185380801406e03701b80da1500230a501001428c046eb8004c290040090a501185100800a14002375c002614202004851008c27c0400509d011bae001309e01002427c0461380200284d008dd7000984d80801213802309901001425c046eb8004c2600400909901184b00800a12802375c002612a0200484b008c24c04005091011bae001309201002424c04612002002847008dd7000984780801212002308d01001422c046112026ea800e00284300a444464b3001305d308a01375400313259800800c56600260bc6116026ea8006264b300100184400c4c9660020030890184480c2240626644b300100184580c4c96600200308c01899912cc00400611c0313259800800c56600261300200513303a0032259800801456600260d0612a026ea800e264b300100184900c4c9660020030930184980c24c06126031332259800800c25406264b300100184b00c2580612c0313259800985000801c4cc27804dd40071984f009ba600b3309e019800acc00566002646600200202c44b30010018a508acc004cdd7985080984f009baa30a10100100b8a51899801001185100800a13602427c0514a3153309a014911869735f7574786f5f636f6e73756d6564203f2046616c73650014a084c80a2b3001329800800c05602880088896600200514a3159800800c54cc27405240120657870656374205b7369672c202e2e726573745f736967735d203d207369677300168acc00660026eb8c2880400a033375c614402002b95456600330010039851808014c28c040050034528c54cc27405241347665726966795f7369676e61747572657328726573745f6b6579732c206d73672c20726573745f7369677329203f2046616c73650014a084e00a294109c0121400242800514a3153309a014901187369676e6174757265735f636865636b203f2046616c73650014a084c80a2941099015300103d87a8000a60103d879800042640497ae084b80a13a02375a00309601428004613a0200284d808dd7000984e00801213a02309a01001426004612c026ea800e1220284980a26464b300100184980c24c0626644b300100184a80c25406264b300100384b00c4c9660020030970184b80c25c0612e031332259800800c26406264b300100184d00c268061340309a018992cc004c2900400e2b300100684d80c4c96600200309c0184e00c2700626644b300100184f00c4c96600200309f0184f80c27c06264b300130a90100389808185480808c280050a6011bad00184f80a1520230a6010014290046eb4004c2940401e13802853008c28c040190a101426c050a1011bae00142900461420200284f808dd7000985000802214202309e010034270046eb000612a0309501427c046eb0004c2600400a1260309301427404612c0200261320200484b80a11e0284a80a11e0308f0184780c23c0509901184b00800a128023756002612a0200508c0184600c2300509601184980800a12202375a00261240200508901424c04612002002847008c23004dd5000c21c0508901421c0610e030870184380a12202308e01308b0137540031533089014913b65787065637420536f6d65287369676e65645f6461746129203d2063626f722e646573657269616c697365287072696365735f6d65737361676529001642200460140092225980099b880014800229000456600260b600314800a264b3001305c3370c0049002466002009300100399b830024801100444c0066002009300100399b83303300248011004210e0237040048430090860148c96600260b40031305630880137546116026110026ea800a2b300130590018982b1844009baa308b0130880137540051305630880137546116026110026ea800908501210a0230860137540032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b010019184500984580984580984580984580984580984580984580984580984580984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116026116026116026116026116026116026116026116026116026116020032308a01308b01308b01308b010019184500984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116020032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b010019184500984580984580984580984580984580984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116026116026116026116026116026116020032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b010019112cc004c16cc22004dd5001c4c9660020030028992cc004006007003801c4cc89660020030058992cc00400600d00680344c966002612602007008803a12002375a003006424c04612002002847008dd6800984780801400d09001184680800a116023089013754007001421805308501375409291111111111111111111194c00488c8cc00400400c8966002003148002264664466446600400400244b30010018801c4c8c96600260f0614a026ea800626466e00cc014014c2ac04010cdc199b82375a614e020066eb4c2a804004cc0352014375a6154026156020026eb0c2a404c29804dd5000c54cc290052415865787065637420536f6d65282870726963652c207363616c652929203d0a2020202020202020707269636573207c3e2070616972732e6765745f66697273742828706f6c6963795f69642c2061737365745f6e616d6529290016428c0464646600200201644b30010018a60103d87a80008992cc004cdd79ba700430a8010018983c9985580985480800a5eb82266006006615a02004853008c2ac040050a90119853809ba9005330a70130a4010014bd70185380800a14a0237566144020066eb8c27c04004cc00c00cc29004008c288040050a00148896600266ebcc28404c27804dd5000982880144c96600200319800800c4cdd7980a800802420c0505e420c06106030830184180a1480232598009837184f009baa0018985100984f809baa0018a9984e80a492c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016427004614202614402614402613c026ea8006294109b0148896600266ebcc28404c27804dd51836184f009baa00130510028992cc00400633001001899baf301500100484100a0bc84100c20806104030820142900464b3001306e309e013754003130a201309f013754003153309d0149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016427004614202614402614402613c026ea8c28404c28804c27804dd5000c52821360248896600260e000b13232329800985280985280985280985280985280985280985280985280985280800c88c8cc00400400c896600200314a31598009801985400800c4cc008008c2a40400629410a201214c029852009850809baa0649bac30a401003985280801244444b3001307730a50137540c513298009919800800802112cc004006297ae110180008101800044cc8966002b30013375e615c026156026ea8c1e4c2ac04dd5001002c4c96600200319800800c4cdd7800804c23c0506b423c0611e0308f0184780a162023259800983d9855809baa00189857809856009baa0018a9985500a493265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642a404615c02615e02615e026156026ea8c2b804c2bc04c2ac04dd50014528215002899856809ba7330ad010023758615c020026615a02615c02615e0200297ae08998568098570080099856809ba7330ad010023758615c02615e0200297ae042a00461580200266004004615a0200285500a6644b3001307b0018983c99855809856009854809baa006330ab01375200497ae08acc004c1e8006260e866156026158026152026ea8018cc2ac04dd480125eb82266e952004330ab0130ac0130a901375400c66156026ea40092f5c08530090a6011bae30aa0130ab0100630a6013754009305a375c61540200c9112cc00566002660106eb0c2b404c2b80400ca600266ebcc2b804c2ac04dd5183c9855809baa001005a50a5142a00514a315330a801491226e6f5f6f746865725f6f6c645f7363726970745f696e70757473203f2046616c73650014a085380a2b3001598009980400314c004cdd79857009855809baa307930ab0137540020054a14a285400a29462a661500292011c6e6f5f6e65775f7363726970745f696e70757473203f2046616c73650014a085380a2b30015980099baf374c60e460726eb0c2b40400cdd31839181c1bac30ad0132330010013758615c0200c44b30010018a5eb850180008101800044cc8966002b30013375e616202615c026ea8008016264b30010018cc004006266ebc00401e126028372126030930184980c24c050b401192cc004c1f8c2b804dd5000c4c2c804c2bc04dd5000c54cc2b40524012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642b004616202616402616402615c026ea800a29410ab0144cc2c004dd399858008011bac30b101001330b00130b10130b2010014bd7044cc2c004c2c404004cc2c004dd399858008011bac30b10130b2010014bd7021560230af010013300200230b00100142b40514a315330a8014911a69735f76616c75655f707265736572766564203f2046616c73650014a085380a2b30013232330010013758615e0261600261600261600261600261600261600200e44b30010018a508acc004cdc79bae30b0010010038a51899801001185880800a1540242b8046eb8c2b40402a29462a661500292011569735f617574686f72697a6564203f2046616c73650014a085380a29410a7014528214e028a50429c043059375c615202614c026ea818a2a66148029212b65787065637420536372697074286f6c645f7363726970745f6861736829203d2063726564656e7469616c0016428c0430a0013754660bc6eb0c28c0400427004c28c04004c27804dd5033c56600260de00b1332298009852008014dd71851808014c290040066eb0c28c04005222298009854008024dd61853808024c2a00400a6148026ea8cc188dd618538080105000a44453001375661560200930ab0130ac010049856009856008014dd61855808014c2b004c2b004c2b004c2b004c2b004c2b004c2b004c2b004c2b0040066eb8c2ac0400522222298009bac30b10130b20130b20130b20130b2010049bae30b1010029bae30b10130b20130b2010029814182f9bab30b10100448888c96600200308d018992cc004c2e00400a264b30010018acc004c21c04c2d004dd5000c4c96600200309b018992cc0040061380309c0184e00c2700626644b300100184f00c4c96600200313259800800c28006264b300100185080c4c9660026182020071980080244cc18c004896600200513259800800c27006264b300130c5010028992cc00400613e031325980098638080144c96600200319800800c4c96600200319800800c4c8cc8a60026198026198026198026198020053371e02e6eb8c32c0400a6644646600200205044b30010018a5eb841018000810180008101800044cc8966002600c0051330d001374e661a0020046eb0c34404004cc34004c34404c34804004cc34004c34404c34804c348040052f5c1159800980280144cc34004c34404004cc34004dd399868008011bac30d10130d201001330d00130d10130d20130d2010014bd7044cc34004c34404004cc34004c34404c34804004cc34004dd399868008011bac30d10130d20130d2010014bd70219602432c04619e020026600400461a002002866808cc18c03c064cc0ac0040666644646600200204044b30010018a5eb841018000810180008101800044cc8966002600c0051330d001374e661a0020046eb0c34404004cc34004c34404c34804004cc34004c34404c34804c348040052f5c1159800980280144cc34004c34404004cc34004dd399868008011bac30d10130d201001330d00130d10130d20130d2010014bd7044cc34004c34404004cc34004c34404c34804004cc34004dd399868008011bac30d10130d20130d2010014bd70219602432c04619e020026600400461a002002866808cc18803c064cc0b0004065222298009868009868009868008024c33c0401261a00200530d001001983f80ea44445300130d50130d501005cc0040c205d375861a80200b02c4125306f374e64660020026eb0c35404c35804010896600200314bd7044cc896600266ebcc36004c35404dd5186c00986c80986a809baa00200589986b8080119802002000c4cc0100100050d201186b00800986b80800a1a80298379ba73233001001375861aa0261ac0200644b30010018a5eb8226644b30013375e61b00261aa026ea80080162661ae020046600800800313300400400143480461ac0200261ae0200286a00a613202660d46530010019bac30d501003a5eb7bdb1810011112cc00400a200319800801cc3600400a6530010018014dd5986c00986c80986a809baa30d8010034004444b30010028800c4c8cc8a600200d30de010059919800800802912cc0040062661bc0266ec0dd48021ba60034bd6f7b63044ca60026eb8c370040066eacc3740400661c2020049112cc004cdc8004001c4cc38804cdd81ba9008374c00e00b15980099b8f0080038992cc004c2cc04c38004dd5000c4cc38c04cdd81ba900930e40130e1013754002005100243780464b300159800800c528c52821c4028a6103d87a8000898588099871809ba60014bd7021bc02329800800c022006800888966002005100189919914c00401a61d40200b32330010010052259800800c4cc3a804cdd81ba9004375000697adef6c608994c004dd7187400800cdd6987480800cc3b4040092225980099b900080038998770099bb037520106ea001c0162b30013371e01000713259800985f809876009baa0018998778099bb0375201261e00261da026ea800400a2004875008c966002617e0200314c0103d87a80008985e8099877809ba80014bd7021d4023370000e0051330ee01337606ea400cdd400119803003000a1d20243a40430eb0100143a4048030dd71871808009bad30e40100130e6010024390051330e201337606ea400cdd300119803003000a1ba0243740430df010014374048030dd7186b808009bab30d80100130da0100243600480190d5011833194c0040066eb0c3540401297adef6c604004444b30010028800c6600200730d801002994c004006005375661b00261b20261aa026ea8c36004c36404c35404dd5186c00801a002222598008014400626466453001006986f00802cc8cc00400401489660020031330de01337606ea4010dd3001a5eb7bdb1822653001375c61b802003375661ba0200330e10100248896600266e4002000e2661c40266ec0dd48041ba60070058acc004cdc7804001c4c96600261660261c0026ea80062661c60266ec0dd48049872009870809baa001002880121bc023259800acc004006294629410e2014530103d87a8000898588099871809ba60014bd7021bc02329800800c022006800888966002005100189919914c00401a61d40200b32330010010052259800800c4cc3a804cdd81ba9004375000697adef6c608994c004dd7187400800cdd6987480800cc3b4040092225980099b900080038998770099bb037520106ea001c0162b30013371e01000713259800985f809876009baa0018998778099bb0375201261e00261da026ea800400a2004875008c966002617e0200314c0103d87a80008985e8099877809ba80014bd7021d4023370000e0051330ee01337606ea400cdd400119803003000a1d20243a40430eb0100143a4048030dd71871808009bad30e40100130e6010024390051330e201337606ea400cdd300119803003000a1ba0243740430df010014374048030dd7186b808009bab30d80100130da0100243600480190d501244445300130da010059bad30d901005986d0080256600266ebcdd3184f0099837994c0040066eb0c3680403697adef6c604004444b30010028800c6600200730dd01002994c004006005375661ba0261bc0261b4026ea8c37404c37804c36804dd5186e80801a002222598008014400626466453001006987180802cc8cc00400401489660020031330e301337606ea4010dd3001a5eb7bdb1822653001375c61c202003375661c40200330e60100248896600266e4002000e2661ce0266ec0dd48041ba60070058acc004cdc7804001c4c96600261700261ca026ea80062661d00266ec0dd48049874809873009baa001002880121c6023259800acc004006294629410e7014530103d87a80008985b0099874009ba60014bd7021c602329800800c022006800888966002005100189919914c00401a61de0200b32330010010052259800800c4cc3bc04cdd81ba9004375000697adef6c608994c004dd7187680800cdd6987700800cc3c8040092225980099b900080038998798099bb037520106ea001c0162b30013371e010007132598009862009878809baa00189987a0099bb0375201261ea0261e4026ea800400a2004877808c96600261880200314c0103d87a800089861009987a009ba80014bd7021de023370000e0051330f301337606ea400cdd400119803003000a1dc0243b80430f00100143b8048030dd71874008009bad30e90100130eb0100243a4051330e701337606ea400cdd300119803003000a1c40243880430e4010014388048030dd7186e008009bab30dd0100130df0100243740480190da011835994c0040066eb0c3680403297adef6c604004444b30010028800c6600200730dd01002994c004006005375661ba0261bc0261b4026ea8c3740400d0011112cc00400a2003132332298008034c38c04016646600200200a44b30010018998718099bb037520086e9800d2f5bded8c113298009bae30e1010019bab30e2010019873008012444b3001337200100071330e701337606ea4020dd3003802c56600266e3c02000e264b300130b80130e50137540031330e801337606ea4024c3a404c39804dd5000801440090e301192cc0056600200314a314a087380a298103d87a80008985b0099874009ba60014bd7021c602329800800c022006800888966002005100189919914c00401a61de0200b32330010010052259800800c4cc3bc04cdd81ba9004375000697adef6c608994c004dd7187680800cdd6987700800cc3c8040092225980099b900080038998798099bb037520106ea001c0162b30013371e010007132598009862009878809baa00189987a0099bb0375201261ea0261e4026ea800400a2004877808c96600261880200314c0103d87a800089861009987a009ba80014bd7021de023370000e0051330f301337606ea400cdd400119803003000a1dc0243b80430f00100143b8048030dd71874008009bad30e90100130eb0100243a4051330e701337606ea400cdd300119803003000a1c40243880430e4010014388048030dd7186e008009bab30dd0100130df0100243740480190da011ba6001899baf374c0026e98c27804c17c06a29410d30124445300130de010049bad30dd01004985580986c809baa30dd0130de010029981fcc004c18c07a05503241886eacc37404009222298009bad30e1010049bae30e10130e201004acc004c2c00401e2003159800985800803c4006266e0ccdc10008039bad30e10100c436c0486d80a6ecc09522225330e0013372c9201096d70665f6b65793a20003732660c66ea4005220100159800acc00406629462a661c00292011769735f696e74656e745f76616c6964203f2046616c73650014a086f80a2b3001598008034528c54cc3800524011a69735f7072696365735f7665726966696564203f2046616c73650014a086f80a2b300159800807c528c54cc3800524011f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a086f80a2b3001598008074528c54cc380052401206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a086f80a2b300159800804c528c54cc3800524012169735f76616c75655f7472616e736665725f636f7272656374203f2046616c73650014a086f80a2b300159800acc0056600266e1cdd6982b9871009baa01e3370001600514a315330e0014911f69735f746f74616c5f7368617265735f636f7272656374203f2046616c73650014a086f80a2b30015980099b87375a60ac61c4026ea80796600266ebc0a4056266e0001c00a200e86f80a29462a661c00292012269735f6f70657261746f725f7368617265735f636f7272656374203f2046616c73650014a086f80a2b30015980099b87375a60aa61c4026ea8078cdc0002002c528c54cc380052412269735f746f74616c5f6465706f73697465645f636f7272656374203f2046616c73650014a086f80a2b30015980099b8f375c60a861c4026ea8078c966002616a02003133225330e3013372c9210b6e65775f76616c75653a20003732660cc6ea400522010019800984680803401200300241886eb0c39804c38c04dd501d1bb330b301330e5013750006661ca026ea00192f5c1159800985a00800c4c8c8cc896600261720261cc026ea800a264b30010018cc00400633001309001009803c00a0093766617002661d4026ea0cdc01bad30eb0130e8013754002010661d4026ea0cdc01bad30b60130e801375400201697ae041910c90141410c90186480c3240619202876808c3a804c39c04dd5001431c050e40118328009bac30e80130e901002375c61ce0200261c6026ea80ea2a661c2029211e496e76616c6964204d504620616374696f6e20666f72206465706f7369740016438004870008c38404dd501cc528c54cc3800524011e69735f6d65726b6c655f726f6f745f636f7272656374203f2046616c73650014a086f80a2b30015980099b8f375c61ca0261c4026ea8078dd71872809871009baa01f8acc004cdc79bae30b00130e201375403c6eb8c2c004c38804dd500fc56600266e3cdd71857809871009baa01e375c615e0261c4026ea807e2b30013371e6eb8c14cc38804dd500f1bae305330e201375403f15980099b8f375c612e0261c4026ea8078dd7184b809871009baa01f8acc004cdc79bae305230e201375403c6eb8c148c38804dd500fc56600266e3cdd718289871009baa01e375c60a261c4026ea807e2b30013371e6eb8c140c38804dd500f1bae305030e201375403f15980099baf30960130e201375403c612c0261c4026ea807e2b30013370e6eb4c13cc38804dd500f1bad304f30e201375403f15980099b87375a609c61c4026ea8078dd698271871009baa01f8acc004cdd798269871009baa01e304d30e201375403f159800acc004c2cc04c38404dd518261871009baa01e89859809870809baa304c30e201375403f198009859809870809baa304c30e201375403f4a14a286f8090df0144cdc39bad304b30e201375403c6eb4c12cc38804dd500fc52821be028a50437c0514a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be028a518a9987000a492169735f6f746865725f6669656c64735f756e6368616e676564203f2046616c73650014a086f80a29410df01452821be028a50437c0514a086f80a29462a661c00292011f69735f6f7261636c655f646174756d5f75706461746564203f2046616c73650014a086f80a2b300132330010010352259800800c528456600266e3cdd718738080081bc528c4cc008008c3a0040050e10121ca028a518a9987000a491169735f7369676e6564203f2046616c73650014a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be0200c32804c32804c32804004c24404cc32004c324040052f5c0619202618a026ea800a1480281f2148030a40185200c290050ca01192cc004c25004c31004dd5000c4c32004c31404dd5000c54cc30c0524012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016430804618e026190026190026188026ea800a1440281ea144030a20185100c288050c901192cc004c24c04c30c04dd5000c4c31c04c31004dd5000c54cc3080524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016430404618c02618e02618e026186026ea8c31804c31c04c30c04dd5001c280050c401186280800a1860232330010010172259800800c52f5c11332259800991980080099198008009bab30ca0130cb0130c701375400844b30010018a5eb82264664464660020026eacc330040108966002003100389919868009ba7330d001375200a661a002619a02002661a002619c0200297ae03300300330d20100230d0010014338046eb8c32004004cc00c00cc33404008c32c040050c901112cc00400629422b30013371e6eb8c32804dd61865008008084528c4cc008008c32c040050c4012190028998638080119802002000c4cc0100100050c201186300800986380800a1880284e80a1840230c301001430404646600200203a44b30010018a5eb8226644b3001323300100132330010013756619002619202618a026ea8c32004c32404c31404dd5002112cc004006297ae0899199119198008009bab30ca010042259800800c400e2646619c026e9ccc33804dd480299867009865808009986700986600800a5eb80cc00c00cc34004008c338040050cc011bae30c6010013300300330cb0100230c901001431c0444b30010018a508acc004cdc79bae30c801375861900200201d14a313300200230c90100143080486300a26618a0200466008008003133004004001430004618802002618a0200286100a26464b300100185300c2980614c030a601899912cc00400615003133069375600244b30010028980398648080444c8c9660020030ac0185600c2b006158031332259800800c2b80615c030ae0189918031867008039bad00185700a19c02375c002618e02004866008c31404004c320040090c60142a006150030a8014320046eb8004c304040090c601185f8080098610080121800285100a0f885100a17c0237560030a10185080c284050c101185f00800a1780230be0100284f80c27c0613e0309f0142fc0461780200285d008dd7000985d8080121780230b90100142dc04616a026ea80061340285900a1340309a0184d00c268050ba01192cc004c21004c2d004dd5000c4c2e004c2d404dd5000c54cc2cc0524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642c804616e026170026170026168026ea8c2dc04c2e004c2d004dd5000c238050b501185b00800a168023232330010010112259800800c52f5c11332259800acc004cdd7985d00985b809baa30ba0130bb0130b701375400400b1323300100132330010013756617802617a026172026ea8c2f004c2f404c2e404dd5002112cc004006297ae0899199119198008009bab30be010042259800800c400e26466184026e9ccc30804dd48029986100985f808009986100986000800a5eb80cc00c00cc31004008c308040050c0011bae30ba010013300300330bf0100230bd0100142ec0444b30010018a508acc004cdc79bae30bc01375861780200201114a313300200230bd0100142d80485d00a29410b40144cc2e404008cc01001000626600800800285a008c2e004004c2e4040050b60118328008184f009baa061309e0137540cf19800984f009baa0619119b83304933700004002003309e0137540ce9114c004c2940400e6eb8c2900400e44464b300133712002900045200089980319b8200100248320050a20119b81003002985280800cdd6185200800a44445300130aa010059bac30a9010059855008014c29804dd5198321bac30a9010020a2014888a6002615c020093756615a0200930ae0130ae010029bac30ad01002985700985700985700985700985700985700985700985700985700800cdd7185680800a444445300130b301006985980985a008034dd6185980985a00985a00985a00985a008024dd71859808014dd7185980985a00985a008014c0a8c184dd5985980802244444464b300100184880c4c96600261780200513259800800c5660026116026170026ea8006264b300100184a80c4c9660020030960184b00c2580612c031332259800800c26006264b30010018992cc0040061340313259800800c26c061360309b018992cc004c3140400e330010048992cc00400613c031325980098638080144c9660020030a1018992cc004c3240400a264b30010018cc004006264b30010018cc0040062646645300130ce0130ce0130ce0100299911919800800814112cc004006297ae11018000810180008101800044cc8966002600c0051330d201374e661a4020046eb0c34c04004cc34804c34c04c35004004cc34804c34c04c35004c350040052f5c1159800980280144cc34804c34c04004cc34804dd399869008011bac30d30130d401001330d20130d30130d40130d4010014bd7044cc34804c34c04004cc34804c34c04c35004004cc34804dd399869008011bac30d30130d40130d4010014bd70219a0243340461a2020026600400461a402002867808cc0b400405ccc19403405e6644646600200204044b30010018a5eb841018000810180008101800044cc8966002600c0051330d201374e661a4020046eb0c34c04004cc34804c34c04c35004004cc34804c34c04c35004c350040052f5c1159800980280144cc34804c34c04004cc34804dd399869008011bac30d30130d401001330d20130d30130d40130d4010014bd7044cc34804c34c04004cc34804c34c04c35004004cc34804dd399869008011bac30d30130d40130d4010014bd70219a0243340461a2020026600400461a402002867808cc0b800405ccc19003405d2229800986880801cc3400400e61a20200530d10100148888c8c8cc8a600261b202005375a61b00200530d9010019bad30d8010014888a600261ba02009375a61b802009375661b8020053370666e0806400400d22223233223298009bad30e40100199baf0240139bad30e4010144888ca6002b3001003899b8100b025899b8000b0014388053370066e0403c094006613002065375c61d00261d20200b59800801c4026266e0402660020130048012084438804911112cc0056600266e3c0d4dd71876808114528c54cc3a00524011769735f696e74656e745f76616c6964203f2046616c73650014a087380a2b300159800985d809874809baa30ed0130ee010138a518a9987400a491a69735f7072696365735f7665726966696564203f2046616c73650014a087380a2b3001598009844009ba73233001001375861dc0261de0203844b30010018a5eb8226644b30013375e61e20261dc026ea8c3c404c3c804c3b804dd5001003c4cc3c004008cc010010006266008008002875808c3bc04004c3c0040050ed014528c54cc3a0052411f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a087380a2b3001598009844009ba73233001001375861dc0261de0203644b30010018a5eb8226644b30013375e61e20261dc026ea800801e2661e0020046600800800313300400400143ac0461de0200261e00200287680a29462a661d002921206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a087380a2b300159800acc004cdc399827cc004cc20c04ca6002003375861dc020414bd6f7b63020022225980080144006330010039878808014ca60020030029bab30f10130f20130ee01375461e20261e40261dc026ea8c3c40400d0011112cc00400a2003132332298008034c3dc04016646600200200a44b300100189987b8099bb037520086e9800d2f5bded8c113298009bae30f5010019bab30f601001987d008012444b3001337200100071330fb01337606ea4020dd3003802c56600266e3c02000e264b300130cc0130f90137540031330fc01337606ea4024c3f404c3e804dd5000801440090f701192cc0056600200314a314a087d80a2980103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee01183f994c0040066eb0c3b80407e97adef6c604004444b30010028800c6600200730f101002994c004006005375661e20261e40261dc026ea8c3c40400d0011112cc00400a2003132332298008034c3dc04016646600200200a44b300100189987b8099bb037520086e9800d2f5bded8c113298009bae30f5010019bab30f601001987d008012444b3001337200100071330fb01337606ea4020dd3003802c56600266e3c02000e264b300130cc0130f90137540031330fc01337606ea4024c3f404c3e804dd5000801440090f701192cc0056600200314a314a087d80a298103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee0140da07e839003c006266e1ccc13e600266106026530010019bac30ee0101ba5eb7bdb1810011112cc00400a200319800801cc3c40400a6530010018014dd59878809879009877009baa30f1010034004444b30010028800c4c8cc8a600200d30f7010059919800800802912cc0040062661ee0266ec0dd48021ba60034bd6f7b63044ca60026eb8c3d4040066eacc3d80400661f4020049112cc004cdc8004001c4cc3ec04cdd81ba9008374c00e00b15980099b8f0080038992cc004c33004c3e404dd5000c4cc3f004cdd81ba900930fd0130fa013754002005100243dc0464b300159800800c528c52821f6028a6103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee01183f994c0040066eb0c3b80407297adef6c604004444b30010028800c6600200730f101002994c004006005375661e20261e40261dc026ea8c3c404c3c804c3b804dd5187880801a002222598008014400626466453001006987b80802cc8cc00400401489660020031330f701337606ea4010dd3001a5eb7bdb1822653001375c61ea02003375661ec0200330fa0100248896600266e4002000e2661f60266ec0dd48041ba60070058acc004cdc7804001c4c96600261980261f2026ea80062661f80266ec0dd4804987e80987d009baa001002880121ee023259800acc004006294629410fb014530103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee0140da07e839003c00629410e7014528c54cc3a00524012169735f76616c75655f7472616e736665725f636f7272656374203f2046616c73650014a087380a2b300159800acc004022266e24cdc11bad30ed010190043370400a906400c528a1ce028a518a9987400a492d69735f6f70657261746f725f6d696e5f70657263656e746167655f6d61696e7461696e6564203f2046616c73650014a087380a2b300159800acc0056600266e1cdd6982f9875009baa0240048a518a9987400a491f69735f746f74616c5f7368617265735f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60bc61d4026ea809001629462a661d0029212269735f6f70657261746f725f7368617265735f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60ba61d4026ea8090cdc09bad30ed010110098a518a9987400a4812269735f746f74616c5f6465706f73697465645f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60a661d4026ea8090cdc01bad30ed0130ee0100d0068a518a9987400a4812c69735f746f74616c5f6665655f73686172655f636f6c6c65637465645f636f7272656374203f2046616c73650014a087380a2b30015980099b8f375c60b861d4026ea80916600266e2120000068acc004c2f004c3a404dd501cc4c96600266e2401d20008801c4cc8966002617e0200319800984a80802c00a6eccc2f404cc3bc04dd40049987780a6010100004bd704dd61878009876809baa00341a9159800985f00800c4c8c8cc896600261860261e0026ea800a264b30010018cc00400633001309a0100a803c00a0093766618402661e8026ea0cdc01bad30f50130f201375400201c661e80261800261e4026ea80052f5c083721a60282d21a6030d30186980c34c050f701187a009878809baa00286880a1dc02306f001375861e40261e6020046eb8c3c404004c3b404dd5001c54cc3ac0524129496e76616c6964204d504620616374696f6e20666f72206f70657261746f7220666565207368617265001643a804875008dd980e9875009baa00143a00461da0261d4026ea80e62a661d0029212965787065637420536f6d6528616374696f6e29203d206f70657261746f725f6d70665f616374696f6e0016439c051002439c0514a315330e8014911e69735f6d65726b6c655f726f6f745f636f7272656374203f2046616c73650014a087380a2b30015980099b8f375c61da0261d4026ea8090dd71876809875009baa0258acc004cdc79bae30b80130ea0137540486eb8c2e004c3a804dd5012c56600266e3cdd7185b809875009baa024375c616e0261d4026ea80962b30013371e6eb8c16cc3a804dd50121bae305b30ea01375404b15980099b8f375c613e0261d4026ea8090dd7184f809875009baa0258acc004cdc79bae305a30ea0137540486eb8c168c3a804dd5012c56600266e3cdd7182c9875009baa024375c60b261d4026ea80962b30013371e6eb8c160c3a804dd50121bae305830ea01375404b15980099baf309e0130ea013754048613c0261d4026ea80962b30013370e6eb4c15cc3a804dd50121bad305730ea01375404b15980099b87375a60ac61d4026ea8090dd6982b1875009baa0258acc004cdd7982a9875009baa024305530ea01375404b159800985d809874809baa305430ea013754049130bb0130e901375460a861d4026ea80963300130bb0130e901375460a861d4026ea80969429450e70121ce028a50439c0514a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a518a9987400a492169735f6f746865725f6669656c64735f756e6368616e676564203f2046616c73650014a087380a29410e701452821ce028a50439c0514a087380a29410e7014528c54cc3a00524011f69735f6f7261636c655f646174756d5f75706461746564203f2046616c73650014a087380a2b300159800991980080081c912cc00400629422b30013371e6eb8c3bc040040f6294626600400461e0020028748090ed014528c4c966002617a0261d4026ea8006264646600200207644b30010018a508acc004cdc79bae30f1010010038a51899801001187900800a1d60243bc046eb8c3b804c3ac04dd5000c52821d002306001c439c0514a315330e80149011169735f7369676e6564203f2046616c73650014a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a50439c045980080145200089982299b829800804400e00282080380310e1010c96600261600200313232332259800985b809872009baa0028992cc004006330010018acc004cdc38131bad30e90130e60137540031330e80130b40130e6013754002661d0026ea66002611c02011007802400906125eb822a661c80292012b657870656374207368617265735f746f5f72656465656d203d3d206f6c645f656e7472792e7368617265730016438c050c80141390c80186400c3200619002875808c3a004c39404dd5001454cc38c0524013365787065637420536f6d65286f6c645f6461746129203d2063626f722e646573657269616c697365286f6c645f76616c756529001643880460c60026eb0c39804008dd71872809873008009870809baa0318acc004c2c804006264646644b300130b70130e401375400513259800800c6600200315980099b89026375a61d20261cc026ea8006264661d2026ea0004cc3a404dd4cc004c23c04026011003802cdd9985b8099874809ba8337026eb4c3a804c39c04dd500101399874809ba8337026eb4c2d404c39c04dd5001000a5eb8106325eb80cdc199b82375a61680261cc026ea8004098dd69874809873009baa0018a9987200a4812b657870656374206f6c645f656e7472792e736861726573203e3d207368617265735f746f5f72656465656d0016438c050c70141390c70186380c31c0618e02875808c3a004c39404dd50014314050e20118318009bac30e60130e701002375c61ca0200261c2026ea80c62a661be02920121496e76616c6964204d504620616374696f6e20666f72207769746864726177616c001643780486f008c37c04dd50181bae30e101001376604261c202008186b80986b80800cc0040c605d375861ac0200302c412c61ac0200261aa020081866009866009866009866008009849809986500986580800a5eb80c32c04c31c04dd500142980504042980614c030a60185300a198023259800984b009863009baa00189865009863809baa0018a9986280a492c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016431004619202619402619402618c026ea800a1480281fa148030a40185200c290050cb01192cc004c25404c31404dd5000c4c32404c31804dd5000c54cc3100524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016430c04619002619202619202618a026ea8c32004c32404c31404dd5001c288050c601186380800a18a0232330010010172259800800c52f5c11332259800991980080099198008009bab30cc0130cd0130c901375400844b30010018a5eb82264664464660020026eacc338040108966002003100389919869009ba7330d201375200a661a402619e02002661a40261a00200297ae03300300330d40100230d2010014340046eb8c32804004cc00c00cc33c04008c334040050cb01112cc00400629422b30013371e6eb8c33004dd61866008008074528c4cc008008c334040050c6012194028998648080119802002000c4cc0100100050c401186400800986480800a18c0284f80a1880230c501001430c04646600200203a44b30010018a5eb8226644b3001323300100132330010013756619402619602618e026ea8c32804c32c04c31c04dd5002112cc004006297ae0899199119198008009bab30cc010042259800800c400e264661a0026e9ccc34004dd480299868009866808009986800986700800a5eb80cc00c00cc34804008c340040050ce011bae30c8010013300300330cd0100230cb0100143240444b30010018a508acc004cdc79bae30ca01375861940200201914a313300200230cb0100143100486400a26618e0200466008008003133004004001430804618c02002618e0200286200a1380284000a13802861008dd6800c26c050c501186100800a1800230c20100284c80c264061320309901430c0461800200285f008dd7000985f8080121800230bd0100142ec046172026ea80061280285b00a128030940184a00c250050be01192cc004c22004c2e004dd5000c4c2f004c2e404dd5000c54cc2dc052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642d8046176026178026178026170026ea8c2ec04c2f004c2e004dd5000c248050b901185d00800a170023232330010010132259800800c52f5c11332259800acc004cdd7985f00985d809baa30be0130bf0130bb01375400400b1323300100132330010013756618002618202617a026ea8c30004c30404c2f404dd5002112cc004006297ae0899199119198008009bab30c2010042259800800c400e2646618c026e9ccc31804dd480299863009861808009986300986200800a5eb80cc00c00cc32004008c318040050c4011bae30be010013300300330c30100230c10100142fc0444b30010018a508acc004cdc79bae30c001375861800200201114a313300200230c10100142e80485f00a29410b80144cc2f404008cc01001000626600800800285c008c2f004004c2f4040050ba0118348008109b012136021808808a610a026ea812522259800982d800c4c9660020030608992cc0040062b3001308f010028cc0040060090614129061423005061830c1860c2848008c2340400508b011844809baa04c8acc004c168006264b300100183044c966002003061830c1860c31332259800800c18e264b3001001832419226644b300100183344c966002003067899912cc0040060d313259800800c56600261300200513303a006225980080144cc0f0014896600200519800802c0460dc809226464b300100183841c20e1070899912cc0040060e50728992cc0040060e713259800800c1d20e907483a44cc89660020030768992cc0040060ef07783bc1de264b300130a6010038980598530080641e10a3011bae001429804614602002850808dd700098510080121460230a0010014278046eb00060e50724284046eb8004c2680400909f01184c00800984d808012132028992cc0040060db06d836c1b626460066138020086eb800509c01184c80801212e02835212a0283541aa0d506a426404612c0200284a008dd5800984a80801419e0cf067425804612602002848808dd600098490080141920c8849808c2400400508e011bae001308f01002424004611a02002845808c22404dd5026456600260b000313259800800c182264b3001001830c1860c3061899912cc0040060c713259800800c1920c91332259800800c19a264b3001001833c4cc89660020030698992cc004006264b3001001835c4c966002003159800984d0080144cc0f0020896600200513303e007225980080146600200f132598009836800c4c9660020030728992cc0040062b300130a1010028cc00400602d073405d073427805073839c1ce0e6851008c27c0400509d01184d809baa0068acc004c1b00062b3001309b01375400d014838a13802838a130024260046132026ea80160e080a226464b300100183941ca0e5072899912cc0040060e90748992cc0040060eb13259800800c1da0ed07683b44cc89660020030788992cc0040060f307983cc1e6264b300130a8010038980598540080641e90a5011bae00142a004614a02002851808dd7000985200801214a0230a2010014280046eb00060e9074428c046eb8004c270040090a101184d00800984e808012136028992cc0040060df06f837c1be2646006613c020086eb800509e01184d80801213202836212e0283641b20d906c426c0461300200284b008c2600400a0d506a83541a909901184b00800a128023756002612a02005067833c19d09601184980800a1220237580026124020050648322126023090010014238046eb8004c23c0400909001184680800a11602308901375409905f4218048430090860120b905c82e417108b01088c8ca6002003480020068008888c8c9660020071489200000000000000000000000000000000000000000000000000000000000000000008992cc00400626464b3001305e0018994c0040126eb4c240040066eb8c24004c244040050051846009baa0028acc004c1740062646607a66e2cdd69848009846809baa001375c60b6611a026ea8004dd7182d1846809baa001308f01309001308c0137540051323303d33023375c6120020020106eb8c24004c24404004c24004c23004dd50012112024224046114026ea8004c2340401226464b3001305e0018994c0040126eb4c240040066eb8c24004c244040050051846009baa0028acc004c17400626465300100b804c007300100a800c01500a4c24404c2480400901018031bad309001001308c01375400513233223322980080740320039800806c006010806a60c266126026ea0cc0f8008030cc24c04dd4998138010009984980984a00984a8080225eb810131bae3092010023008001309101001375a6120020026118026ea800908901211202308a013754002611a02008845808c2340400d08a01111194c00402600f001cc0040220030044021002403c60080046e00c0cc008dca0011111991194c004006900040110011112cc0040062660726603e00a004009132332259800982f00144c8ca6002015007800e600201100198490080320109bae309101309201002404460046eb4c24004004c23004dd5001c56600260ba005132329800805401e0039800804400661240200c80426122026124020048080c008dd69848008009846009baa00389919914c004dd71849008014c01000661260200e9114c00403a017002cc00403200500140313062330940137506607e006607600466128026ea4cc0a000c008cc25004c25404c258040152f5c080a06122020026eb4c24004004c23004dd5001a112024224046112026ea8004dc0181b001984600800a1140237280066e500081164104820888c966002602e60886ea8006264b30010018acc004c060c114dd5000c4c9660020030208992cc004006043021810c08626644b3001001811c4c96600200302481240920491332259800800c09a264b30010018992cc00400605113259800800c0a6053029814c4cc896600200302b8992cc00400605902c81640b226644b300100181744c96600200313259800800c0c2264b3001001818c0c6063031899912cc00400606713259800800c4c9660020030358992cc00400606d03681b40da26644b300100181c44c96600200303981cc0e60731332259800800c0ee264b300100181e40f207903c899912cc00400607d13259800800c0fe07f03f81fc4c96600260d60071980080d46600202519800806c408a080813a080813a08081320808340dd7000a0d6306800141986eb8004c19c0090681832800a0c6375c00260c80048328c1880050601bae0013061002418860be00282e8c17c00a06903481a40d1060182e800a0b6375c00260b800482e8c168005058182d00140be05f02f817a0b6305800141586eb8004c15c009058182a800a0a6375c00260a800482a8c1480050501829001409e04f027813a0a6305000141386eb8004c13c0090501826800a096375c00260980048268c12800504818231baa00180fa08680fc07e03f01f412c6464b300130190018a99822a481274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0600062a6608a921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168982518239baa00241108220c114dd5000980918229baa3013304537546090608a6ea80062a660869201cd65787065637420536f6d65286465785f6f726465725f626f6f6b5f7265665f696e70757429203d0a20202020696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206465785f6f726465725f626f6f6b5f746f6b656e2c20222229203d3d20310a202020202020202020207d2c0a20202020202020202900164108660120044602c64b300130173045375400314800226eb4c124c118dd5000a0863259800980b98229baa0018a6103d87a8000899198008009bab304a3047375400444b30010018a6103d87a8000899192cc004c0780062b3001301d0018980d19826182500125eb82298103d87a8000411d133004004304e003411c6eb8c120004c12c00504920863300b37566026608a6ea8c04cc114dd500080118209baa0042223259800980b800c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009827001c66002009008803a016803a096375c0028270c12c0050491825801401200900480220983049001411c608a6ea80122b300130160018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b3001304e0038cc004012011007402d007412c6eb800504e1825800a092304b0028024012009004413060920028238c114dd50024566002602800313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002609c00719800802402200e805a00e8258dd7000a09c304b0014124609600500480240120088260c12400504718229baa004801208441088210c10cdd500188a4d15330294911856616c696461746f722072657475726e65642066616c7365001365640a01", + "hash": "34287f56be7722bfbca67475a01e7eec6e15a3dc668f7941430ac130" }, { "title": "hydra_account/core.hydra_account.else", @@ -776,8 +776,8 @@ } } ], - "compiledCode": "59801f010100229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0024888888888a60022a6600692012e6578706563742061737365745f6c6973743a204d56616c7565203d20646573657269616c697365645f76616c756500168a99801a4949657870656374206f75747075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a494665787065637420696e7075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a493e657870656374206f75747075745f646174756d3a20557365724163636f756e74203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a493b65787065637420696e7075745f646174756d3a20557365724163636f756e74203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492a657870656374206163636f756e743a20557365724163636f756e74203d206f75747075745f646174756d00168a99801a494a657870656374206f75747075745f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a497b657870656374204465784163636f756e7442616c616e6365446174756d207b0a202020206163636f756e745f62616c616e63655f6d65726b6c655f726f6f743a20696e7075745f6d65726b6c655f726f6f742c0a20207d3a204465784163636f756e7442616c616e6365446174756d203d20747265655f726f6f7400168a99801a495b657870656374205472616e73666572496e74656e74207b20746f2c20616d6f756e745f6c323a207472616e73666572616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a496a657870656374204d6173746572496e74656e74207b206163636f756e743a2066726f6d2c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495f6578706563742043616e63656c5769746864726177616c496e74656e74207b20616d6f756e745f6c313a207769746864726177616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a4941657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d206465785f6163636f756e745f62616c616e63655f6f75747075747300168a99801a493f657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d206465785f6163636f756e745f62616c616e63655f696e7075747300168a99801a49e7657870656374205b6665655f6f75747075745d203d0a202020202020202020206f746865725f6f7574707574730a2020202020202020202020207c3e206c6973742e66696c746572280a202020202020202020202020202020206372656174655f6163636f756e745f6f7574707574735f66696c746572280a2020202020202020202020202020202020206665655f6163636f756e742c0a20202020202020202020202020202020202068796472615f6163636f756e745f7363726970745f686173682c0a20202020202020202020202020202020292c0a20202020202020202020202020202900168a99801a498b657870656374205769746864726177616c496e74656e74207b0a20202020616d6f756e745f6c313a207769746864726177616c5f616d6f756e745f7261772c0a202020207769746864726177616c5f6665655f6c313a207769746864726177616c5f6665655f7261772c0a20207d3a2048796472614163636f756e74496e74656e74203d20696e74656e7400168a99801a4964657870656374204d6173746572496e74656e74207b206163636f756e742c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a498c657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c696379280a202020202020696e707574732c0a20202020202068796472615f757365725f696e74656e745f616464726573732c0a20202020202068796472615f757365725f696e74656e745f7363726970745f686173682c0a202020202900168a99801a494e657870656374206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a494365787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f6f75747075742e646174756d00168a99801a499d657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d0a202020206f7574707574735f61745f77697468280a2020202020206f7574707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a494c65787065637420696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f646174756d00168a99801a499a657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d0a20202020696e707574735f61745f77697468280a202020202020696e707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a4929657870656374206163636f756e743a20557365724163636f756e74203d20696e7075745f646174756d00168a99801a4958657870656374206465785f6f726465725f626f6f6b5f696e7075745f646174756d3a204465784f72646572426f6f6b446174756d203d0a202020206465785f6f726465725f626f6f6b5f7265665f696e7075745f6461746100168a99801a491e72656465656d65723a2048796472614163636f756e7452656465656d657200168a99801a491f72656465656d65723a2048796472614163636f756e744f7065726174696f6e0016488888888888888888888888889660033001301f375404b3722911009b8f4881009b87480026e1d20029ba5480026e1d2004918119812000c8c08cc090c0900066e9520024888888888a6002605a015302c00a91919800800801112cc004006297adef6c608994c004dd71816000cdd59816800cc0c4009222598009808001c566002601e00710018802a05a89981919bb037520066e98008cc01801800502d0c0bc00502d4888c966002601600313259800800c00e264b300100180240120090048992cc004c0d000e00d00540c46eb80050341818800a05e302d37540091598009805000c4c9660020030038992cc0040060090048024012264b3001303400380340150311bae00140d060620028178c0b4dd5002400902a2054302b37540072232330010010032259800800c5300103d87a8000899192cc004cdc8802800c56600266e3c0140062601666062605e00497ae08a60103d87a800040b1133004004303300340b06eb8c0b4004c0c000502e488c8cc00400400c896600200314c0103d87a80008992cc004c010006260146606000297ae089980180198190012056303000140b922259800801452844ca600264b3001300c302d37540031375a605c60626eacc0c4c0b8dd5000c5200040ac6060003375e6060606200337560069112cc0040062b30013002006899802801a400114a0816a264b30013375e60600029810140008acc004cc018010dd69818981a1bab3031001898019ba630350028a5040b91598009980300224001130030078a5040b88170c0cc0050310ca60020030049119818801198189ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0bc0066eacc0c000660680069112cc004c04c00e2b3001301200389980298079981a9ba60024bd70000c4cc01530103d87a800000640c119800803c006446600e0046606e66ec0dd48029ba6004001401c81806064004818229422942294103124444445300130330079819981a003c88966002602260646ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002607c00519800801c66002003009804201c804201c8042076804402201100840fc607800281d0c0f000a00d006803401903d181d000a070375c002607200481d0c0dc00503518199baa003800a0609112cc004c044c0c8dd5001c4c9660020030028992cc004006264b300100180244c966002003159800981d80146600200713259800980b000c4c9660020030078992cc0040062b3001303e0028992cc004c064006264b300100180544c966002003159800982080146600200300c805a022805a07c805c02e01700b4108607e00281e8c0ecdd50014566002603000313259800800c02a264b3001001805c02e0171332259800800c036264b3001001807403a01d1332259800800c042264b3001001808c046023132598009824001c04e0248228dd6800c0450481822800a086375a002608800500e411460840028200dd68009820801402d042181f800a07a303b375400500940e081c0c0e4dd5000c02103b4022011008804207e303c00140e860706ea800a2b300130150018acc004c0e0dd5001401e00c81ca00c81a9035181b1baa001802a016802a070802c01600b00540f0607200281b8c0e400a007003801c00d03a181b800a06a3033375400700140c091111919912cc004c0500062646644b300100a899912cc004c068006264b300100181044c9660026084005004810a07e304000140f860786ea80322b300130190018acc004c0f0dd5006400a03e81ea2b300130170018acc004c0f0dd5006400a03e81ea03e81c9039207213232332298009bab3041002982118211821182118211821182118211821000cdd71820800cc0f4dd500724444b300130200018acc004c8c8cc004004018896600200314a115980099baf003304430480018a518998010011824800a0844118603466088608a608c00697ae08a518a998202494e7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6f726465725f626f6f6b5f7363726970745f6861736829203f2046616c73650014a081fa2b3001301f0018acc004c8c8cc004004018896600200314a115980099baf003304430480018a518998010011824800a0844118603466088608a00697ae08a518a9982024814b7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6163636f756e745f7363726970745f6861736829203f2046616c73650014a081fa264b300130213042375400313259800acc00566003300130193756603c60886ea8c078c110dd5182398221baa002a60101a0009119b87002001405514a3153304249011369735f6e6f5f76616c7565203f2046616c73650014a0820a29462b300159800981118219baa00b8a508a51410514a315330424911369735f6e6f5f646174756d203f2046616c73650014a08209041454cc1092410f746f646f3a2072656d6f766520697400159800800c528c54cc1092411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a0820a294104119198008009bac3047304830480082259800800c528456600266e3cdd71824000802c528c4cc008008c124005042208c8a99820a4813465787065637420536f6d65286f776e5f696e70757429203d20696e70757473207c3e2066696e645f696e70757428696e7075742900164100660286eb0c1140208cdd7982318219baa00100b40fc81f86080608060806080608000260786ea8cc01cdd6181f80081c181f800981d1baa0103039375401501d80ec07603a81f8c0ec004c0ecc0f0004c0dcdd5003456600260240031325980080446600244646600200200644660060026004005370e90054888c966002603400313259800800c00e264b300100180240120091332259800800c01a264b3001001803c01e00f0078992cc004c11800e013008410c6eb80050461821800a082375a0026084005004410c608000281f0c0f0dd50024566002603200313259800800c00e264b300100180240120091332259800800c01a264b30010018acc004c11400a2b3001301f3040375400313259800800c022264b3001001804c0260131332259800800c02e264b3001001806403201900c899912cc00400601d13259800800c03e01f00f807c4c966002609c0070118082096375c0028270c12c0050491bae001304a002412c60900028230dd6800982380140250481822800a0863041375400300740f90074109007803c01e00e8230c10c0050411bad00130420028022086304000140f860786ea80122b300130170018992cc00400600713259800800c012009004899912cc00400600d13259800800c01e00f007803c4cc89660020030098992cc00400601500a805402a264b30013049003806402d0461bae0014124608c0028220dd70009822801208c304300141046eb4004c10800a0088218c10000503e181e1baa004801207240e481c8c0e8dd5001cc0dcdd500424444646644b3001301d0048992cc00400604513259800800c566002608a00519800800c00e046802a0468212047023811c08d0461821800a082303f375401f159800980e00244c9660020030228992cc0040062b300130450028cc00400600702340150234109023811c08e0468230c10c005041181f9baa00f8acc004c068012264b300100181144c9660020031598009822801466002003003811a01a811a084811c08e047023411860860028208c0fcdd5007c56600266e1d20060048acc004c0fcdd5007c00604282022b30013370e900400244c9660020030228992cc0040062b300130450028cc00400600702340110234109023811c08e0468230c10c005041181f9baa00f8acc004c018012264b300100181144c9660020031598009822801466002003003811a008811a084811c08e047023411860860028208c0fcdd5007c08503c207840f081e103c207822259800980f181f9baa0038992cc00400600513259800800c4c9660020030048992cc00400600b132598009824801c4cc8966002604a00313259800800c026264b30010018acc004c13400a26530010018014015001111192cc004c0ac006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c4c96600260ae00713301b0012259800801402a26464b300100180c40620311332259800800c6600202100189802982e803202080d406a03501a41786eb4004c15c00a03082e0c154004c16000905640510541bab001809c04e02682b8c1500050521bae0013053002415060a20028278c134dd5001c566002605400313259800800c03e264b30010018084042021010899912cc00400602513259800800c04e027013809c4cc89660020030158992cc00400602d01680b405a264b3001305a003805c05d0571bae001416860ae00282a8dd7000982b00120ae305400141486eb8004c14c0090541828800a09e304d375400700e41288250c12cdd5001402904a402a01500a805209c304b0014124608e6ea801a2b300130240018992cc00400601313259800800c02a015132598009827001c4cc04800489660020050078992cc00400633001001898011828801c039011403a01d00e80720a4304f002413500b412c6eb000601500a413860960028248c11cdd50034021044208813300d0012259800801402626464b3001001805402a01500a899912cc00400601900c8992cc00400601b13259800800c03a01d00e80744cc89660020030108992cc004006023011808c046264b3001305500389805982a80640490521bae001415460a40028280dd7000982880120a4304f00141346eb000601900c41406eb8004c12400904e1823800982500120903044375400900641186eac00600b005802a09230460014110608c005003801c00e0068238c11000504218201baa003800a07a19800912cc00400629344c966002003149a264b3001337206eb8c100c11000cdd71820000c4cc010010cc10c004c11400a2a6607e921326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f72646572001640f860860028208c10c00504048888c8cc0040040148966002003133045337606ea4014dd300225eb7bdb1822653001375c608600337566088003304800248896600266e4002400e26609266ec0dd48049ba60080058acc004cdc7804801c4c966002604c608e6ea800626609466ec0dd4805182598241baa0010028801208a9800804c022004803a26609266ec0dd48019ba60023300600600141108220608c00282224444646600200200a44b300100189982299bb0375200a6ea00112f5bded8c113298009bae30430019bad304400198240012444b300133720012007133049337606ea4024dd4004002c56600266e3c02400e264b300130263047375400313304a337606ea4028c12cc120dd5000801440090454c004026011002401d133049337606ea400cdd400119803003000a088411030460014111259800800c528c528207e91192cc004c074c0fcdd5000c52f5bded8c113756608660806ea800503d19809001000c888c8cc004004010896600200310048994c004dd71821000cdd69821800ccc00c00cc11c0090041822800a086912cc004006297ae0899820981f1821000998010011821800a080912cc004c070c0f8dd5000c4c8cc108cdd8182180098219822000a5eb7bdb180c10cc0fcdd5000c4c8cc004004c8cc004004dd59822182298209baa0032259800800c52f5c113304430423045001330020023046001410c44b30010018a5eb7bdb1822646644660040046600e00e00244b30010018801c4cc118c11c004cc008008c1200050451822801198010011822800a08440f12329800800c00a97ae04004444b30010028800c660020073045002998219822001000a0064109223304137520020052259800980e99b8600148012266e0ccdc700119b83001480112020899b863371c00466e0c00520044808103c48a6002003337026e34008006004b8c48896600266e2400920008800c6600200733708004900a4cdc599b803370a004900a240c0002801903d488dca19b8a0020019b804800a6e05200091111919800800802912cc004006200b13259800800c4cc010c11c00801a26600a608e004660060060028228c11c0050444dc0240032301a33040301633040375200297ae0330404c0103d87a80004bd704888c8cc004004010896600200310048998019822800998010011823000a0869112cc004c078c0fcdd5001c4c9660020030028992cc004006007003801c00e264b30013047003802c0110441bae001411c60880028210c100dd5001c00503d4dc02400737009003cdc02401f25980099b87371a0029020440062a6607892138657870656374206279746561727261792e6c656e67746828726f6f7429203d3d20626c616b6532625f3235365f6469676573745f73697a65001640ed303c375401b22225980099b88002480c22600200515980099b87002480c2266008900111801000c56600266e20009203889980199b8e488103020408003370000490189180119bca4a2003124bded8c10140000101200040f881f103e4dc3a41fc0722337600046ea0005222222222222222222222222222229800980e80ec888a6002009003801488a6002007001801200840813017017980b00b4c044046444b30010028cc00400e60300034bd7020068992cc004006264b30010038800c6600200b33019301a003001a5eb8100520c0375c60c2007198008024c18800666030004660286eb8c18400cdd71830800a008417c60c200482f244b3001303a3370c002900244cdc5a41fc066602800466e0c0052004899b8b48000cdc59980a8010009980a00119b833011001480110594888c8cc00400400c896600266e2400c0062910100899b8b3301800500133002002301400141712225980099b8900348002266026004003133013001002416922329800800c00e00480088896600200510018994c00401260c800798008014dd7182f800cdd59830000c888c966002604800314c0103d87a800089820198331ba60014bd7020c2329800800c00e00480088896600200510018994c00401260d600798008014dd71833000cdd69833800c888c966002609200314c103d87a800089823998369ba80014bd7020d0337000040028141004183480120ce40888020c18800906048c8cc004004008896600200314bd6f7b63044c8cc180cdd8182e8009ba63233001001375660be00444b30010018a5eb7bdb182264660c666ec0c180004dd4180a9bad3061001330030033065002306300141846600600660c400460c000282f2444b30013375e60c060ba6ea8c0dcc174dd5000980700144c96600200319800800c4cdd7800802415502a41560ab05582aa0c63259800981c982e9baa00189830982f1baa0018a9982e2493265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016416c60c060c260c260ba6ea8c180c184c174dd5000c52820b49112cc004cdd79830182e9baa001300e0028992cc00400633001001899baf00100482b205482b415a0ad056418c64b30013039305d375400313061305e3754003153305c49012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016416c60c060c260c260ba6ea8006294105a48966002003148002260226600400460c000282ea44444653001001801c0090011112cc004cdc480124001130014bd70448c8ca600200d30170059180299834001000cdd69832801200c30630019800804c022002803905f48888c8cc00400400888cc01920022598009804800c4c0092f5c1123232980080348c018cc19c0080066eb4c1900090061831000cc00402200f3017001401882f244453001004801c00a46600800246006002803922222222222222222980091112cc004c134006200919800802400e6464004602c002660e266ec0dd48011ba80014bd6f7b6304888c966002606600314c103d87a8000898279983a9ba60014bd7020e0980080140160092223259800982a000c530103d87a8000898291983c1ba80014bd7020e633700002004819901420d89806006488c8cc00400400c8966002609a0031337149110130000038acc004cdc4000a40011337149101012d0033002002302300189980899b8400148050cdc599b803370a002900a240c0006836106c488896600266e240112002899812cc00401200700140340051330250029800980e802400e002806906c488896600266e2001120048acc004cdc4001240091330259800802400e00280692201200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100899812cc0040120074892000000000000000000000000000000000000000000000000000000000000000000040353001301d002800d22120000000000000000000000000000000000000000000000000000000000000000000403483622b300133712900200144cc095221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f9761009800980e802400e002806a26604b3001002800d2212000000000000000000000000000000000000000000000000000000000000000000040353001301d004801d221200000000000000000000000000000000000000000000000000000000000000000004034836106c4c0100124466002444646466ec0c8dd39983a98390009983a9839800a5eb80cdd8183880118388009839000cc00401a44003004801cdd69838800a00c9800802c88006007002800a00a2233002480088c96600266e2400520048acc004c13c00633001004801c00a460326ea000501a4566002609c00319800802400e66e00009203f9180c9ba830243026001406915980099b87002482f80626466002002460346ea400488cc0192002259800980e000c4c0092201008cc00401e00d33700002903fc8cc0100108c010cdc5001000a01441c519800802400e66e00009207f9180c9ba9001401c837106e20dc8acc004cdc3800a401919800802400e66e0000920ff02919802a40044b30013370e004906600c492f7b63001014000010120008992cc004cdc38012417c0519800803c01a66012012440032301c3374a004002805a330010078034cdc0001241fe0329800804401e66014014440030019180e99ba5003001403480e90712cc004cdc4a41002800513370066e0000920ff134803a266e0000920f10141c0838101a456600266e1c00520088acc004cdc38012417c0519800802400e6600c00c4400323019374e002804233001004801ccdc0001241fe0329800802c0126600e00e440030019180d1ba7001402880d106e4566002607000315980099b87002483f80a2646466002002460366e9800488cc01d2002259800980e800c4c0092f5bded8c1123232980080348c018cc1ec0080066eb4c1e00090061919bb0307b001307b307c001375860ec00330010098044c0ac00500520e433006006220028cc00401200733700004905f8148c8ca60020030039180e1ba60014004444b300133712004900044c0052f5bded8c112323298008034c0ac0164600a660f8004003375a60f20048030c8cdd8183e000983e183e8009bac30770019800805402600280290731980380391001203441b9124bded8c010140000101200041b8837106e20dc33706002902048c8cc004004008896600200314bd6f7b63044ca60026eb8c1b80066eacc1bc0066600600660e60049112cc00400a2a660e092124657870656374205061697228702c205b5f2c202e2e5d206173207829203d20696e6e657200168cc004006007323200432330010010042259800800c5268992cc0040062b30013004375a60ec60f2005149a2a660e892011f76616c756520646f65736e2774207361746973667920707265646963617465001641cd133225980099b90375c60ee0046eb8c1dc0062b30013006375a60f00051330050053307a001307c0038a9983b2491f76616c756520646f65736e2774207361746973667920707265646963617465001641d51533076491276b65797320696e207061697273206172656e277420696e20617363656e64696e67206f72646572001641d460f200460f200283b8c1e400507614c004c14400694294507048894cc1cd2401234475706c696361746520706f6c69637920696e20746865206173736574206c6973742e0016405c839860e200283792222222298009114c004cc0d400c00a97adef6c60911192cc004c160c1e4dd5000c4ca6002007375c60fc003375c60fc60fe00300440406eb0c1f4c1e8dd5000c54cc1e124121546f6b656e2068617368206e6f7420666f756e6420696e20746f6b656e206d6170001641dc646600200200a44b30010018a60103d87a80008992cc004cdc78031bae307b0018982c1983f183e000a5eb8226600600661000200483c8c1f800507c2068911919800800980d001912cc004006297adef6c60899912cc004c8cc004004018896600200314a115980099b8f375c60fc00200914a3133002002307f00141e083e23300133038006002800c88a6002003005801c009011206e8800a0ec375c60f40026600400460f600283c244464b30010038991919911980700119b8a488101280059800800c4cdc52441035b5d2900006899b8a489035b5f20009800800ccdc52441025d2900006914c00402a00530070014029229800805400a002805102e20f85980099b880014803a266e0120f2010018acc004cdc4000a41000513370066e01208014001480362c83b10761bac3079002375a60ee0026466ec0dd4183b8009ba73078001375400713259800800c4cdc52441027b7d00003899b8a489037b5f20003232330010010032259800800c400e264b30010018994c00402a60f8003337149101023a200098008054c1f400600a805100a183f80144ca6002015307c00199b8a489023a200098008054c1f4006600e66008008004805100a183f80120fa307f00141f066e29220102207d0000341e46eac00e264b3001001899b8a489025b5d00003899b8a489035b5f20009800800ccdc52441015d00003914c00401e0053004001401d229800803c00a002803902b20f2375800713300a375a0060051323371491102682700329800800cc0acdc68014cdc52450127000044004444b300133710004900044006264664530010069818002ccdc599b800025980099b88002480522903045206e41ec66e2ccdc0000acc004cdc4000a40291481822903720f6004401866e0c00520203370c002901019b8e00400241e06eb800d07c1b8a4881022c2000911112cc004cdc4802a400d13302e9800802c012005001402800713302e00398009812802c012005001402883aa4444b3001337100089004456600266e200092008899816cc004012007002800a01048812085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100899816cc004012007489200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402530013024002800d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483a22b300133712900400144cc0b52212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b10098009812002400e6048005001402113302d980080140069101200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402530013024004801d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483a1074488c8cc00400400c896600200314bd6f7b63044c8ca60026eacc1e400a6600800860fa0072229800800c022b300159800982d80244c16c00e2941079452210089b943371400800683ca00480890371bae3077001307a00141e130020024888888a6002600a00b22222330359800802c012606200680f260026607000a60620079800a400148102002b8c66002902052040800ae319800a41000348102002b8c66002906000d2040800ae30911112cc004cdc4802a401d13303a9800802c01e007002800a01c00489981d0024c004c0c001600f003801400500e210202488888c96600330013370e0026eb4c20c04c20004dd5001528528a0fa89981b4c00401a00b3032004407c6644b3001337100069008456600266e20009201089981c4c00400e00b002800a016488120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0089981c4c00400e00b4892085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302e002800d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403083fa2b300133712900800144cc0e122120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0098009817001c016605c005001402d1330389800801400691012085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302e003802d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403083f907f1bad30830130800137540046606c6eb8c168c20004dd50011bae30593080013754005153307e49120657870656374206272616e636820213d206e65696768626f722e6e6962626c65001641f46607000a606200723259800982d183d9baa0018992cc0040060f113233046001225980080144c96600266e3cdd99ba60010078800c54cc1fd241306578706563742063626f722e73657269616c6973652876616c756529203d3d2073657269616c697365645f76616c7565001641f8601c0071323259800800c1f60fb07d83ec4cc896600200307f8998261bab001225980080144c01cc2280402226464b300100184180c20c061060308301899912cc00400610a030850184280c4c8c018c23c0401cdd6800c2140508f011bae001308801002423404610c0200261120200484380a0ff07f83fa11202375c002610402004843808c20004004c20c04009081011bab00183c41e20f0841008c1fcc1f0dd5000c54cc1e924014465787065637420536f6d6528646573657269616c697365645f76616c756529203d2063626f722e646573657269616c6973652873657269616c697365645f76616c756529001641e464b3001305a0018a6103d87a80008992cc006600260b66eb4c1f400694294507a4530103d87a80008982c9983f983e000a5eb8107a4c00488006444b3001337120029000452f7b63010140000101200089980119b8e0053370200800266e0400400d07c48896600266e2400520008a5ef6c601014000010120008998014c004cdc0802000c00e00ab8c19b8100100341f1001400c83c8dc6800a44453001223300122225980099b870024808220091325980098311842009baa0018cc00401e440053303f0054881200000000000000000000000000000000000000000000000000000000000000000008024c0e800e004803a26464b30013371000200b15330850149012e696e76616c696420747265652c206368696c6472656e206d75737420626520736f7274656420627920696e64657800168992cc004c198c21c04dd5000c56600266e1c01800a3300100a910014cc108022600201522001984400801ccdc5002cc00528d20028032f2480526eacc22c04c22004dd5000cc0f401a00a80523300100a910014cc108021220120000000000000000000000000000000000000000000000000000000000000000000803cc0f401a00a805108501454cc218052412a65787065637420536f6d65287461696c5f6e6f64657329203d206c6973742e7461696c286e6f646573290016421404b30010068a6103d87a80008983199844809ba6308b010064bd702110024210046eb4c21404004c8cdd81844808009844809845008009bac30880130850137540028410096600200714c103d87a8000898301984300991ba7330870130840100133087013085010014bd70184380801a5eb8108501210202225980098301840809baa002899191981d000992cc0040062a661060292012e696e76616c6964206368696c64206861736865732c206d7573742062652061206e6f6e2d656d707479206c69737400168acc004c2240400626eb8c2200400626603200297ae0421804843008c0fe600200d22002a5eb826eacc21c04c2200400a90004cdc5001800a00c375c610c020026104026ea800a264646644b3001980099b8f37280040034a14a284180a2a661080266e59241056b65793a20003732660186ea40092201001533084013372c920106706174683a20003732660186ea40052201001533084014912d696e76616c696420747265652c2070617468206973206e6f74207468652068617368206f6620746865206b65790016899192cc004cdc7800803c4cc0f8cc0a000c008dca1bae308b01308c010058a998430099b964910e706174685f6e6962626c65733a200037326601c6ea40052201001533086013372c9201107072656669785f6e6962626c65733a200037326601c6ea401d22010015330860149128696e76616c696420747265652c2070726566697820646f6573206e6f74206d61746368207061746800164214053001002a400100140986e34015083011bae308701001375c610e02004610e020026104026ea800907f488c8ca6002003480020068008888c8c96600200714881200000000000000000000000000000000000000000000000000000000000000000008992cc00400626464b300130670018994c0040126eb4c234040066eb8c23404c238040050051844809baa0028acc004c1980062646608066e2cdd69846809845009baa001375c60c86114026ea8004dd718319845009baa001308c01308d013089013754005132330403302a375c611a020020106eb8c23404c23804004c23404c22404dd5001210c02421804610e026ea8004c2280401226464b300130670018994c0040126eb4c234040066eb8c23404c238040050051844809baa0028acc004c19800626465300100b804c007300100a800c01500a4c23804c23c0400900f18031bad308d01001308901375400513233223322980080740320039800806c006010806a60d466120026ea0cc11c008030cc24004dd499817001000998480098488098490080225eb810121bae308f010023008001308e01001375a611a020026112026ea800908601210c023087013754002611402008844008c2280400d08701111194c00402600f001cc0040220030044021002403860080046e00c0e4008dca0014888cc88ca60020034800200880088896600200313303c3302600500200489919912cc004c19c00a26465300100a803c0073001008800cc23c040190084dd718470098478080120203002375a611a020026112026ea800e2b30013066002899194c00402a00f001cc004022003308f010064021308e01308f01002403c60046eb4c23404004c22404dd5001c4c8cc8a60026eb8c23c0400a6008003309001007488a600201d00b80166002019002800a018983599848809ba8330480033041002330910137526605e006004661220261240261260200a97ae0404c308e01001375a611a020026112026ea800d08601210c0230860137540026e00c0f000cc22404005087011b940033728004911194c004a600244003001a441004009222225980099b8f9800802400a006803801633001004800c00d007454cc2140524013465787065637420696e636c7564696e67286b65792c206f6c645f76616c75652c2070726f6f6629203d3d2073656c662e726f6f74001642100522225980099b8f330070030010048cc00400e0050014019153308401490129657870656374206578636c7564696e67286b65792c2070726f6f6629203d3d2073656c662e726f6f740016420c049112cc004c18c0be2646466453001308d01308d010029bac308c01002984680984680800cdd7184600800a444530013756612002009375861200261220261220261220261220200930910130910100298480080124444646530013097010019bae3096010019bac30960100e488a60026eb8c2640400e6eb8c26404c26804c2680400e64646600200200644b30010018a5eb8226644b30015980099baf309e01309b013754613c02613e026136026ea80080162646600200264660020026eacc28004c28404c27404dd5185000985080984e809baa0042259800800c52f5c113233223233001001375661440200844b30010018801c4c8cc29804dd399853009ba9005330a60130a301001330a60130a4010014bd7019801801985400801185300800a14802375c613c020026600600661460200461420200284f808896600200314a115980099b8f375c6140026eb0c28004004026294626600400461420200284d00909e01452821300289984e8080119802002000c4cc01001000509801184e00800984e80800a134023047002984c80984b009baa0669bae309901007984c80802a444444b300100484380c4c96600261420200b13259800800c56600260f6613a026ea8006264b300100184580c4c96600200313259800800c23406264b300130a6010028cc00400e2b30010018acc004c20004c28404dd5000c4c966002003090018992cc004006122031332259800800c24c06264b300100184a00c4c966002615802007133070004225980080144cc1c800c896600200519800981d002cc8c8cc004004064896600200314bd7081018000810180008101800044cc8966002600a0051330b301374e66166020046eb0c2d004004cc2cc04c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c1159800acc004cdd7985a009858809baa30b40130b50130b101375400402d1323300100132330010013756616c02616e026166026ea8c2d804c2dc04c2cc04dd5002112cc004006297ae0899199119198008009bab30b8010042259800800c400e26466178026e9ccc2f004dd48029985e00985c808009985e00985d00800a5eb80cc00c00cc2f804008c2f0040050ba011bae30b4010013300300330b90100230b70100142d40444b30010018a508acc004cdc79bae30b6013758616c0200203314a313300200230b70100142c00485a00a29410ae0144cc2cc04c2d004004cc2cc04dd399859808011bac30b40130b501001330b30130b40130b50130b5010014bd7044cc2cc04c2d004004cc2cc04c2d004c2d404004cc2cc04dd399859808011bac30b40130b50130b5010014bd70215c0242b80461640200266004004616602002858008cc11c03405a64646600200204844b30010018a5eb841018000810180008101800044cc8966002600a0051330b301374e66166020046eb0c2d004004cc2cc04c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c1159800acc004cdd7985a009858809baa0020168991980080099198008009bab30b60130b70130b301375400844b30010018a5eb82264664464660020026eacc2e004010896600200310038991985e009ba7330bc01375200a6617802617202002661780261740200297ae03300300330be0100230bc0100142e8046eb8c2d004004cc00c00cc2e404008c2dc040050b501112cc00400629422b30013371e6eb8c2d804dd6185b0080080cc528c4cc008008c2dc040050b0012168028a5042b8051330b30130b401001330b301374e66166020046eb0c2d004c2d404004cc2cc04c2d004c2d404c2d4040052f5c11330b30130b401001330b30130b40130b501001330b301374e66166020046eb0c2d004c2d404c2d4040052f5c08570090ae0118590080099801001185980800a160023304600d016488a600266098607a016609600730b3010029bac30b201002985980800cdd6185900800a4444530013758616e020053758616e0261700200530910130443758616e026170020093758616e020089111192cc00400a1500313259800985f00801c56600200d0aa018992cc004c2fc0401e264b3001598008034528c54cc2e8052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085c80a2b3001598008024528c54cc2e80524011e69735f7769746864726177616c5f6665655f70616964203f2046616c73650014a085c80a2b300159800992cc004006330010018992cc004006330010018cc004dd7186080985f009baa0029bae30c10130be013754003376603f30bd01375404a9111192cc004c2840400a266e3e60020030039bb3374c0293758618c026186026ea80a903f002456600261400200513232332259800acc0066002660c86094002031374c6094005223370e00400284c00a29462a6618a0292011a69735f62616c616e63655f75706461746564203f2046616c73650014a086200a2b30013371f3001005803cdd6186500986580801c006004822002229462a6618a029211e69735f6e65775f62616c616e63655f636f7272656374203f2046616c73650014a086200a29410c4011bae30c801001375c6190020046190020026186026ea80aa29410c001218002306d00442e00506d42e006170030b80185c00a186023259800984c80985e809baa0018986080985f009baa0018a9985e00a4812c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642ec04618002618202618202617a026ea800e16c02836216c030b60185b00c2d8050c201192cc004c26004c2f004dd5000c4c30004c2f404dd5000c54cc2ec0524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642e804617e026180026180026178026ea8c2fc04c30004c2f004dd5001c528c54cc2e80524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a085c80a2b30015980099baf374c612202660b2660b265300100180652f5bded8c080088896600200510018cc00400e618602005329800800c00a6eacc30c04c31004c30004dd51861809862009860009baa30c3010034004444b30010028800c4c8cc8a600200d30c9010059919800800802912cc0040062661920266ec0dd48021ba60034bd6f7b63044ca60026eb8c31c040066eacc320040066198020049112cc004cdc8004001c4cc33404cdd81ba9008374c00e00b15980099b8f0080038992cc004c2a804c32c04dd5000c4cc33804cdd81ba900930cf0130cc013754002005100243240464b300159800800c528c528219a028a60103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c001182c194c0040060114bd6f7b63020022225980080144006330010039861808014ca60020030029bab30c30130c40130c0013754618602006800888966002005100189919914c00401a61920200b32330010010052259800800c4cc32404cdd81ba9004374c00697adef6c608994c004dd7186380800cdd5986400800cc330040092225980099b900080038998668099bb037520106e9801c0162b30013371e010007132598009855009865809baa0018998670099bb03752012619e026198026ea800400a2004864808c966002b30010018a518a5043340514c103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c001182c194c0040060154bd6f7b63020022225980080144006330010039861808014ca60020030029bab30c30130c40130c0013754618602006800888966002005100189919914c00401a61920200b32330010010052259800800c4cc32404cdd81ba9004374c00697adef6c608994c004dd7186380800cdd5986400800cc330040092225980099b900080038998668099bb037520106e9801c0162b30013371e010007132598009855009865809baa0018998670099bb03752012619e026198026ea800400a2004864808c966002b30010018a518a5043340514c103d87a8000898540099867009ba60014bd70219202329800800c022006800888966002005100189919914c00401a61aa0200b32330010010052259800800c4cc35404cdd81ba9004375000697adef6c608994c004dd7186980800cdd6986a00800cc360040092225980099b9000800389986c8099bb037520106ea001c0162b30013371e01000713259800985b00986b809baa00189986d0099bb0375201261b60261b0026ea800400a200486a808c966002616c0200314c0103d87a80008985a009986d009ba80014bd7021aa023370000e0051330d901337606ea400cdd400119803003000a1a80243500430d6010014350048030dd71867008009bad30cf0100130d101002433c051330cd01337606ea400cdd300119803003000a1900243200430ca010014320048030dd71861008009bab30c30100130c501002430c0480190c0011ba60018a518a9985d00a4812569735f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a085c80a2b300159800cc0040be6e98c160cc164c24404dd5984b00985e009baa30960130bc013754040003223370e00400284680a29462a66174029211769735f746f6b656e735f6275726e74203f2046616c73650014a085c80a2b3001323300100102f2259800800c528456600266e3cdd71860808008194528c4cc008008c308040050bb01217e028a518a9985d00a492669735f68796472615f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a085c80a29410b90145282172028a5042e40514a085c80a29410b9011848009982180601242ac050bc01185e8080321760285480a1760230bc0100242e804b30010038a518acc004c2f00400e264b300100185380c4c966002617c020051980098478099821007011cdd31847809bab30940130ba013754003223370e00400284580a1500285d808c2f0040050ba01191919800800802912cc004006297ae0899912cc004c01400a26617e020046600800800313300400400142e804617c02002617e0200285e008cc1480a008a2a6616c02920118756e6578706563746564206f74686572206f7574707574730014a085c8090b9010899192cc0040061360309b0184d80c26c0626644b300100184e80c4cc1e0dd5800912cc00400a2600e616c020111323259800800c28406142030a10185080c4cc89660020030a30185180c28c06264600c61760200e6eb40061460285d808dd7000985a0080121720230b20100130b50100242cc0509d0184e80c274050b5011bae00130ae0100242cc04615802002615e0200485680a26464b300100184c80c264061320309901899912cc00400613603133076375600244b300100289803985a0080444c8c96600200309f0184f80c27c0613e031332259800800c28406142030a1018991803185c808039bad00185080a17202375c00261640200485b808c2c004004c2cc040090b101426c061360309b0142cc046eb8004c2b0040090b10118550080098568080121560284a80a1520237560030940184a00c250050ac01185480800a14e0237560026150020050910184880c244050a901185300800a1480230a201375400308f01427c0508f0184780c23c0611e0285380a11c02837211c02851808c290040050a2011852008014230061180308c0184600a14a0230a201001428004613c026ea80061140284d80a1140308a0184500c228050a301192cc004c1e4c27404dd5000c4c28404c27804dd5000c54cc270052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016426c04614002614202614202613a026ea8c28004c28404c27404dd5000c2200509e01184f80802213a020c25804c25804c25804004c25404008308b010013087013754660a46eb0c2280400420c04c22804004c21404dd502dc4ca600253001001a5eb7bdb182446604c0046eacc18cc22404dd518319844809baa001400929800800d2f5bded8c12233026002375660c66112026ea8005002488896600266e3e6002007002800a014004899805801800c54cc220052413065787065637420696e636c7564696e67286b65792c2076616c75652c2070726f6f6629203d3d2073656c662e726f6f740016421c049112cc004c1980ce26464664530013091013091010029bac309001002984880984880984880984880800cdd7184800800a4445300137566128020093758612802612a02612a02612a02612a020093095010029bae30940100248888ca6002613402003375c613202003375861320201a9114c004dd7184e00801cdd7184e00984e80984e80801cc8c8cc00400400c896600200314bd7044cc8966002b30013375e614202613c026ea8c28404c28804c27804dd5001002c4c8cc004004c8cc004004dd59851809852009850009baa30a30130a40130a001375400844b30010018a5eb82264664464660020026eacc294040108966002003100389919854809ba7330a901375200a6615202614c020026615202614e0200297ae03300300330ab0100230a901001429c046eb8c28404004cc00c00cc29804008c290040050a201112cc00400629422b30013371e6eb8c28c04dd6185180800804c528c4cc008008c2900400509d012142028a50426c051330a00100233004004001899802002000a13602309f0100130a0010014274046094005309c0130990137540d3309c0100648888966002007089018992cc004c28c04012264b30010018acc004c1f4c27c04dd5000c4c96600200308d018992cc004006264b300100184780c4c96600261500200519800801c5660020031598009840809851809baa0018992cc00400612c0313259800800c25c06264b300130ab01003899837800912cc00400a26645300130af010029bac30ae01002985780800cdd6185700800a444530013758616402005308c01303f3758616402616602009308d01303f3758616402616602005375861640200891112cc0040061440313259800985c00801456600200b0a4018992cc004c2e40401a264b3001598008034528c54cc2d005241176e6f5f6f746865725f696e70757473203f2046616c73650014a085980a2b300159800802c528c54cc2d0052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085980a2b30015980099912cc004006330010018992cc004006330010018cc004dd7185e00985c809baa0029bae30bc0130b9013754003376603130b801375403a9111192cc004c2640400a266e3e60020030039bb3374c0113758618202617c026ea8089036002456600261360200513232332259800cc004cc17cc114004c1780326e98c11400a4466e1c0080050930144cdc7cc00401600f3758618a02618c02007001801207e0088a5042fc046eb8c30c04004dd7186180801186180800985f009baa0228a5042ec0485d808c1a00110b30141a10b30185980c2cc061660285f008c9660026128026170026ea800626178026172026ea80062a6616e029212c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642d8046176026178026178026170026ea801216202833a162030b10185880c2c4050bd011822008192cc004c24804c2d804dd5000c4c2e804c2dc04dd5000c54cc2d4052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642d004617202617402617402616c026ea8c2e404c2e804c2d804dd5001c528c54cc2d00524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a085980a2b30015980099baf374c611602660a6605e01060a460600146e9800629462a66168029212c69735f63616e63656c5f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a085980a2b300159800cc0040966e98cc14cc148c22c04dd5984800985b009baa30900130b6013754030003223370e00400284380a29462a66168029211d69735f6d696e745f76616c75655f636f7272656374203f2046616c73650014a085980a2b300132330010010252259800800c528456600266e3cdd7185d808008144528c4cc008008c2f0040050b5012172028a518a9985a00a492d69735f68796472615f63616e63656c5f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a085980a29410b30145282166028a5042cc0514a085980a29410b3011981e982180780dc294050b601185b80802a16a0285180a16a0230b60100142d004194c00404a97ae10101800081018000810180004896600260060051330ae01374e6615c020046eb0c2bc04004cc2b804c21804004cc2b804c214040052f5c1159800acc004cdd79857809856009baa30860130ac01375400401f1323300100132330010013756611002615c026ea8c22004c2b804dd5002112cc004006297ae08991991199119801001000912cc0040062007132330b701374e6616e026ea4014cc2dc04c2d004004cc2dc04c2d4040052f5c066006006617202004616e0200285a808dd59859008019bae30af010013300300330b40100230b20100142c00444b30010018a508acc004cdc79bae30b101375861620200203514a313300200230b20100142ac0485780a29410a90144cc2b804c2bc04004cc2b804dd399857008011bac308601001330ae013085010014bd7044cc2b804c2bc04004cc2b804c21804004cc2b804dd399857008011bac3085010014bd7021520242a40482d0cc110020040c8c8cc004004074896600200314bd7081018000810180008101800044cc8966002600a0051330b001374e66160020046eb0c2c404004cc2c004c2c404c2c804004cc2c004c2c404c2c804c2c8040052f5c1159800acc004cdd79858809857009baa0020118991980080099198008009bab30b30130b40130b001375400844b30010018a5eb82264664464660020026eacc2d404010896600200310038991985c809ba7330b901375200a6617202616c020026617202616e0200297ae03300300330bb0100230b90100142dc046eb8c2c404004cc00c00cc2d804008c2d0040050b201112cc00400629422b30013371e6eb8c2cc04dd618598080080e4528c4cc008008c2d0040050ad012162028a5042ac051330b00130b101001330b001374e66160020046eb0c2c404c2c804004cc2c004c2c404c2c804c2c8040052f5c11330b00130b101001330b00130b10130b201001330b001374e66160020046eb0c2c404c2c804c2c8040052f5c08558090ab0118578080099801001185800800a15a0233043008010899192cc0040061380309c0184e00c2700626644b300100184f00c4cc1d4dd5800912cc00400a2600e6166020111323259800800c28806144030a20185100c4cc89660020030a40185200c29006264600c61700200e6eb40061480285c008dd7000985880801216c0230af0100130b20100242c00509e0184f00c278050b2011bae00130ab0100242c00461520200261580200485500a13002854008dd5800c25c0612e030970142ac04615002002853008c29004dd5000c254050a10142540612a030950184a80a1520284800a0e084800a14a0230a601001429004614c0200508e0184700c2380611c02853808c290040050a2011850009baa00184600a13a0284600c230061180308c0142940464b3001307b309f013754003130a30130a0013754003153309e014913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016427404614402614602614602613e026ea8c28804c28c04c27c04dd5000c228050a001185080801a13e020c26404c26404c26404008308f01001308b013754660ac6eb0c2380400421c04c23804004c22404dd502fc4c96600260ca069132323298009bae3090013091013091013091013091013091013091013091013091013091010019848009846809baa05d98488080124446644b3001598009804984a80984b008014528c54cc240052401176e6f5f6f746865725f696e70757473203f2046616c73650014a084780a2b3001598009804984a80984b00800c528c54cc240052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a084780a2b30015980099baf374c60ce6530010019bac309601003a5eb7bdb1810011112cc00400a200319800801cc2640400a6530010018014dd5984c80984d00984b009baa309901309a013096013754613202006800888966002005100189919914c00401a613e0200b32330010010052259800800c4cc27c04cdd81ba9004374c00697adef6c608994c004dd7184e80800cdd5984f00800cc288040092225980099b900080038998518099bb037520106e9801c0162b30013371e010007132598009840009850809baa0018998520099bb03752012614a026144026ea800400a200484f808c966002b30010018a518a50428c0514c0103d87a80008983f19852009ba60014bd70213e02329800800c022006800888966002005100189919914c00401a61560200b32330010010052259800800c4cc2ac04cdd81ba9004375000697adef6c608994c004dd7185480800cdd6985500800cc2b8040092225980099b900080038998578099bb037520106ea001c0162b30013371e010007132598009846009856809baa0018998580099bb03752012616202615c026ea800400a2004855808c96600261180200314c0103d87a8000898450099858009ba80014bd702156023370000e0051330af01337606ea400cdd400119803003000a1540242a80430ac0100142a8048030dd71852008009bad30a50100130a7010024294051330a301337606ea400cdd300119803003000a13c0242780430a0010014278048030dd7184c008009bab309901001309b010024264048019096011ba63067329800800cdd6184b0080152f5bded8c080088896600200510018cc00400e613202005329800800c00a6eacc26404c26804c25804dd5184c80801a002222598008014400626466453001006984f80802cc8cc004004014896600200313309f01337606ea4010dd3001a5eb7bdb1822653001375c613a020033756613c0200330a20100248896600266e4002000e2661460266ec0dd48041ba60070058acc004cdc7804001c4c9660026100026142026ea80062661480266ec0dd48049852809851009baa0010028801213e023259800acc004006294629410a3014530103d87a80008983f19852009ba60014bd70213e02329800800c022006800888966002005100189919914c00401a61560200b32330010010052259800800c4cc2ac04cdd81ba9004375000697adef6c608994c004dd7185480800cdd6985500800cc2b8040092225980099b900080038998578099bb037520106ea001c0162b30013371e010007132598009846009856809baa0018998580099bb03752012616202615c026ea800400a2004855808c96600261180200314c0103d87a8000898450099858009ba80014bd702156023370000e0051330af01337606ea400cdd400119803003000a1540242a80430ac0100142a8048030dd71852008009bad30a50100130a7010024294051330a301337606ea400cdd300119803003000a13c0242780430a0010014278048030dd7184c008009bab309901001309b010024264048019096014528c54cc2400524011e69735f6163636f756e745f76616c75655f657175616c203f2046616c73650014a084780a2b30013232330010013758612e0261300261300261300261300261300261300200a44b30010018a508acc004cdc79bae3098010010038a51899801001184c80800a124024258046eb8c2540401a29462a661200292012d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a084780a294108f014528211e028a50423c046466446600400400244b30010018a5eb8410180008101800044cc8966002600a00513309701374e6612e020046eb0c26004004cc25c04c26004c264040052f5c1133097013098010013309701374e6612e020046eb0c26004c264040052f5c0849008c25804004cc008008c25c04005094011bac3094010073302b002003323322330020020012259800800c52f5c210180008101800044cc8966002600a00513309701374e6612e020046eb0c26004004cc25c04c26004c264040052f5c1133097013098010013309701374e6612e020046eb0c26004c264040052f5c0849008c25804004cc008008c25c04005094011bac3094010023302a0020031846009baa330573758611e0200211002611e020026114026ea81822b30013370e900301a44c8c8cc8a600261240261240200537586122020053092013092013092013092013092013092013092013092010019bae3091010014888a60026eacc254040126eb0c25404c25804c25804c25804c258040126eb8c2540400a6eb8c25404c2580400a6eb0c25404021222223259800800c20c06264b3001309d010028992cc0040062b30013077309901375400313259800800c23406264b30010018992cc00400611e0313259800985100801466002007159800800c56600260f2613a026ea8006264b300100184900c4c96600200313259800800c25006264b300100184a80c4c966002614e020071980080244cc1ac00489660020051332233223259800acc004c21c04c0e8dd6185680985700801c528c54cc2a0052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085380a2b30015980098109856809857008014528c54cc2a0052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085380a2b300159800acc004cdd79ba6307f3304730243758615a0200a608c60466eb0c2b404010dd3000c4cdd79ba6001374c607001114a085380a29462a66150029211a69735f76616c7565735f6d61746368696e67203f2046616c73650014a085380a2b300159800991980080080c112cc00400629422b30013371e6eb8c2bc0400406e29462660040046160020028548090ad014528c54cc2a0052412d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085380a2b3001980080c4dd31823183f9bab30840130aa0137546108026154026ea804a4466e1c00800507b4528c54cc2a00524011d69735f696e74656e745f746f6b656e5f6275726e74203f2046616c73650014a085380a29410a7014528214e028a50429c0514a0853808c1f8cc118c088dd6185600800982298119bac30ac0100230ab0100230ab01001332232330010010122259800800c52f5c21018000810180008101800044cc8966002600c0051330ad01374e6615a020046eb0c2b804004cc2b404c2b804c2bc04004cc2b404c2b804c2bc04c2bc040052f5c1159800980280144cc2b404c2b804004cc2b404dd399856808011bac30ae0130af01001330ad0130ae0130af0130af010014bd7044cc2b404c2b804004cc2b404c2b804c2bc04004cc2b404dd399856808011bac30ae0130af0130af010014bd7021500242a00461580200266004004615a02002855008cc100028040cc100018040cc88c8cc004004064896600200314bd7081018000810180008101800044cc8966002600c0051330ad01374e6615a020046eb0c2b804004cc2b404c2b804c2bc04004cc2b404c2b804c2bc04c2bc040052f5c1159800980280144cc2b404c2b804004cc2b404dd399856808011bac30ae0130af01001330ad0130ae0130af0130af010014bd7044cc2b404c2b804004cc2b404c2b804c2bc04004cc2b404dd399856808011bac30ae0130af0130af010014bd7021500242a00461580200266004004615a02002855008cc0fc028040cc0fc01804226464b300100184d00c268061340309a01899912cc00400613803133071375600244b30010028980398578080444c8c9660020030a00185000c28006140031332259800800c28806144030a2018991803185a008039bad00185100a16802375c002615a02004859008c2ac04004c2b8040090ac014270061380309c0142b8046eb8004c29c040090ac01185280800985400801214c0284b00a0de84b00a1480237560030950184a80c254050a701185200800a1440230a40100284980c24c061260309301429404614402002850008c27804dd5000c2440509b01424406122030910184880a1460284800a0d484800a13e0230a00100142780461400200508e0184700c2380611c02850808c2780400509c01184d009baa00184600a12e0284600c230061180308c01427c0464b3001307530990137540031309d01309a01375400315330980149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016425c04613802613a02613a026132026ea8c27004c27404c26404dd5000c2100509a01184d80800a132023232330010010032259800800c52f5c11332259800acc004cdd7984f80984e009baa309f0130a001309c01375400400b1323300100132330010013756614202614402613c026ea8c28404c28804c27804dd5002112cc004006297ae0899199119198008009bab30a3010042259800800c400e2646614e026e9ccc29c04dd480299853809852008009985380985280800a5eb80cc00c00cc2a404008c29c040050a5011bae309f010013300300330a40100230a20100142800444b30010018a508acc004cdc79bae30a101375861420200201514a313300200230a201001426c0484f80a29410990144cc27804008cc01001000626600800800284c808c27404004c2780400509b01182400186120020026118026ea8cc15cdd6184780800844009847808009845009baa0608acc004c1440d233001308a013754611a026114026ea816a4444b30010018801c4c966002007153308d0149012a6e6f7420656e6f756768206b65792d76616c756520706169727320746f206d617463682070726f6f667300168992cc004c1acc23c04dd500146600200d9800802cdd7184780800cdd7184800800cdd61849809848009baa0024021309401004984a00801a00c8a9984700a4930657870656374204d504644656c657465207b2070726f6f663a2064656c6574655f70726f6f66207d203d2070726f6f660016423404612402006848008c2440400508f014c22804dd5030244530013002002984800801cdd5984800984880801cc2440400522223232329800984c00984c00984c00984c00800cc25c040066eb8c25c0400922298009bae309a01309b01309b0100398241bae309a0100399198008009bac309b0100c2259800800c52f5c11332259800acc004cdd7984f00984d809baa309e01309f01309b01375400400d130783259800983c984d809baa0018a40011375a613e026138026ea800509901192cc004c1e4c26c04dd5000c5300103d87a8000899198008009bab30a001309d01375400444b30010018a6103d87a8000899192cc004c200040062b3001307f0018983e198510098500080125eb82298103d87a800042740513300400430a4010034274046eb8c27804004c2840400509f0121320232330010013756613e026140026138026ea8c27c04c28004c27004dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c024006260f66614202613e0200497ae08a60103d87a800042700513300400430a3010034270046eb8c27404004c2800400509e01452821300289984e8080119802002000c4cc01001000509801184e00800984e80800a134029bac309a01309b010079bae309a0100648888966002007082018992cc004c28404012264b30013079309d01375400313259800800c56600260fa613c026ea8006264b300100184a00c4c9660020030950184a80c2540612a0313259800985300801c4c96600200308b018992cc004c2a00400a264b300130800130a401375400313259800800c660020031323259800acc004cdd79ba63303437566156026158026158026158026158026150026ea81f8cc2a804dd4808a5eb80c2ac04c2b00400a29462a6614c029211769735f76616c75655f6d696e746564203f2046616c73650014a085280a2b30015980099198008009bac30ac0130ad0130ad0130ad0130ad0130ad0130ad0130ad0130ad0130a90137540fe44b30010018a508acc004cdc79bae30ad0100100f8a51899801001185700800a14e0242ac0514a315330a60149011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085280a2b3001598009843009853809baa01a8992cc0056600266e3cc09c00402229462a6614e02920134636f6d707574655f747265655f68617368287472656529203d3d20696e7075745f6d65726b6c655f726f6f74203f2046616c73650014a085300a2b30015980099baf374c60980026e9800a29462a6614e029212f6b65795f76616c756573203d3d206f75747075745f6d65726b6c655f7265636f72645f6c697374203f2046616c73650014a085300a2b30013371e6eb8c2b004c2a404dd5002245200000000000000000000000000000000000000000000000000000000000000000008a518a9985380a494d6f75747075745f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085300a29410a6014528214c0230ab0130a801375403513371e60a66eb8c2ac04c2a004dd5001cc004c14c01e00337586156026150026ea806901b214a028a518a9985300a4811769735f747265655f75706461746564203f2046616c73650014a085280a29410a5014528214a0237566154020033001323300100100d2259800800c52f5c1133225980099baf30ad0130aa0137540040251330ac0100233004004001899802002000a14e0230ab0100130ac0100142a4054bd708101a0008101a000488c9660026108026150026ea800626644b30010018cc00400626615a026e98cc2b404cdd81ba937660026ea4dd99ba60023756615c020086615a026e98cc120dd59842808021981b9bab30850130ab01375400a6615a026ea40512f5c097ae085080a0ee85080c28406142030a10142c005300137566106026152026ea800e02501a40d86158026152026ea80062a6614e029212f65787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206f75747075742e646174756d00164298046102026150026ea8009056426c05055426c061360309b0184d80a1560230a80130a501375400308e0142880460fa6148026ea800611802852808c298040050a4011919800800804912cc004006297ae0899912cc0056600266ebcc2a404c29804dd5001008c4c20c04c966002610802614c026ea80062900044dd69855009853809baa00142900464b300130840130a601375400314c0103d87a8000899198008009bab30ab0130a801375400444b30010018a6103d87a8000899192cc004c22c040062b3001308a010018984380998568098558080125eb82298103d87a800042a00513300400430af0100342a0046eb8c2a404004c2b0040050aa0121480232330010013756615402615602614e026ea800c896600200314c103d87a8000899192cc004cdc880a000c56600266e3c0500062610c02661580261540200497ae08a60103d87a8000429c0513300400430ae01003429c046eb8c2a004004c2ac040050a90145282146028998540080119802002000c4cc0100100050a301185380800985400800a14a0284b00a14602375c002853008c28c040050a101184f809baa00184980a1380284980c24c061260309301429004614202613c026ea80062a661380292014665787065637420496e6c696e65446174756d28747265655f726f6f7429203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d0016426c0460ec613a026ea8c1dcc27404dd5000c20c0509e01184f80801a13a020c25c04004c25804c25804c25804c25804004c24404dd51982e1bac30940100108d01233001308a013754611a026114026ea816a4444b30010018801c4c966002007153308d01491256e6f7420656e6f756768206b65792d76616c75657320746f206d617463682070726f6f667300168992cc004c1b8c23c04dd500146600200d9800802cdd7184780800cdd7184800800cdd61849809848009baa0024031309401004984a00801a00c8a9984700a4930657870656374204d5046496e73657274207b2070726f6f663a20696e736572745f70726f6f66207d203d2070726f6f660016423404612402006848008c2440400508f014c22804dd5030244530013002002984800801cdd5984800984880801cc244040066eb0c240040052222233229800984c00984c008014dd6184b808014c26004c26004c26004c260040066eb8c25c04005222298009bab309b010049bac309b01309c01309c01309c01309c01004984e008014dd7184d80801244446644646530013756614602003375661460261480200332330010010102259800800c52f5c11332259800acc004cdd79853809852009baa30a70130a80130a401375400400f130810132598009841009852009baa0018a40011375a615002614a026ea80050a201192cc004c20804c29004dd5000c530103d87a8000899198008009bab30a90130a601375400444b30010018a6103d87a8000899192cc004c224040062b30013088010018984280998558098548080125eb82298103d87a800042980513300400430ad010034298046eb8c29c04004c2a8040050a80121440232330010013756615002615202614a026ea8c2a004c2a404c29404dd5001912cc004006298103d87a8000899192cc004cdc8806800c56600266e3c0340062610802661540261500200497ae08a60103d87a800042940513300400430ac010034294046eb8c29804004c2a4040050a70145282142028998530080119802002000c4cc0100100050a101185280800985300800a14602488966002003089018992cc004c2a00400a264b300130800130a401375400313259800800c6600200313259800800c23c06264b300130ac010028992cc004c21004c2a004dd5000c4c96600200319800800c566002b30013375e6e98048dd3004c528c54cc2a00524011669735f76616c75655f6275726e74203f2046616c73650014a085380a2b3001598009919800800809112cc00400629422b30013371e6eb8c2bc0400405629462660040046160020028548090ad014528c54cc2a0052411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085380a2b3001598009844009854809baa01c8992cc0056600266e3cdd71857009855809baa006489200000000000000000000000000000000000000000000000000000000000000000008a518a9985480a4950696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085400a2b30015980099b8f3029001375c615c026156026ea800a29462a66152029215f636f6d707574655f747265655f68617368287472656529203d3d206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203f2046616c73650014a085400a2b30013375e6e98c138004dd31919800800806112cc004006297adef6c60899191980080099802002185980801912cc0040062661640200697adef6c608992cc004cdd799912cc004cdc8001000c530103d87980008acc004cdc7801000c530103d87a80008a6103d87b800042c004858008dca1bae30b00100437286eb8c2c00400530103d87980008998598080200144cc2cc04004cc00c00cc2d4040090ae01185980800a1620230b00100142b80514a315330a9014913c657874726163745f6b65795f76616c756573287472656529203d3d20736f727465645f73657269616c697365645f696e70757473203f2046616c73650014a085400a29410a801452821500230ad0130aa01375403913371e60aa6eb8c2b404c2a804dd5000cc004c154dd71856809855009baa0058054dd61856809855009baa01c407485380a29462a661500292011769735f747265655f75706461746564203f2046616c73650014a085380a29410a7014528214e0284a00a0b284a00c25006128030940142bc046158026152026ea800612402853008c20404c2a004dd5000c240050a901185500800a1500232330010010122259800800c52f5c11332259800acc004cdd79856809855009baa00200d8984380992cc004c22004c2a804dd5000c5200089bad30ae0130ab013754002854008c9660026110026154026ea8006298103d87a8000899198008009bab30af0130ac01375400444b30010018a6103d87a8000899192cc004c23c040062b3001308e010018984580998588098578080125eb82298103d87a800042b00513300400430b30100342b0046eb8c2b404004c2c0040050ae0121500232330010013756615c02615e026156026ea800c896600200314c103d87a8000899192cc004cdc8809800c56600266e3c04c00626114026616002615c0200497ae08a60103d87a800042ac0513300400430b20100342ac046eb8c2b004004c2bc040050ad014528214e028998560080119802002000c4cc0100100050a701185580800985600800a1520284680a0aa84680c2340611a0308d0142ac04615002614a026ea80062a66146029214865787065637420496e6c696e65446174756d28696e7075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642880460fa6148026ea8c1f8c29004dd5000c228050a501185300800a148024c004c8c8cc004004040896600200314bd7044cc8966002600a0051330a60100233004004001899802002000a1420230a50100130a601001428c0446466ebcc29004c28404dd51852009852809850809baa0020013051375c6146020094bd70901a0008101a000488c96600260fa6142026ea800626644b30010018cc00400626614c026e98cc29804cdd81ba937660026ea4dd99ba60023756614e020086614c026e98cc104dd5983f0021820198181bab307e30a401375460fc6148026ea8014cc29804dd480325eb812f5c10890141c10890184480c224061120285480a60026eacc1f0c28804dd5183e1851009baa003802404d02f1852809851009baa0018a9985000a4813465787065637420496e6c696e65446174756d28696e7075745f646174756d29203d20696e7075742e6f75747075742e646174756d0016427c0460f46142026ea8c1ecc28404dd5001209e375c614202614402614402004614002614002614002614002004613e02004184b008011849009baa3305d3758612a0200411c02210e02421c04843808dd7a601018000421804222329800800c01200680088896600200510018cc00400e611e0200533004001308e01002400c846009082010c00c00c02223259800980f000c4c9660020030038992cc0040060090048992cc004c11c00e26601600244b300100280444c96600200319800800c4c008c12800e0108062011008804402104b1824001208c802a0883758003004802208e3044001410860806ea80122b3001301d0018992cc00400600713259800800c01200900480244cc89660020030068992cc00400600f007803c01e26644b3001001804c4c96600200300a80544c966002609a0071330110012259800801403a264b30010018cc0040062600460a000700e404900e807403a01c8288c13800904c402d04a1bac001805402904d1825000a090375c00260920048250c11c0050451bae0013046002411c60880028210c100dd50024566002603600313259800800c00e264b30010018024012264b30013047003899805800912cc00400a01113259800800c6600200313002304a00380420188044022011008412c6090004823200a8220dd6000c0120088238c11000504218201baa004801207a40f481e8c0f8dd5001a03501a80d406903d181d181b9baa0068b206840d04464b300130163037375400313259800800c566002602e60706ea8006264b300100180f44c96600200301f80fc07e03f1332259800800c086264b3001001811408a045022899912cc00400604913259800800c4c9660020030268992cc00400604f027813c09e26644b3001001814c4c96600200302a81540aa0551332259800800c0b2264b30010018992cc00400605d13259800800c0be05f02f817c4cc89660020030318992cc004006264b3001001819c4c96600200303481a40d20691332259800800c0da264b300100181bc0de06f037899912cc00400607313259800800c0ea07503a81d44cc896600200303c8992cc00400607b03d81ec0f6264b3001305e0038cc00406a330010128cc004036204503e409d03e409d03e409903e416c6eb800505e182d800a0b2375c00260b400482d8c1600050561bae0013057002416060aa0028298dd7000982a00120aa3052001414060a400503281940ca0648298c14000504e1bae001304f0024140609a0028258c13400a05b02d816c0b504e1825800a092375c00260940048258c1200050461bae00130470024120608a0028218c11400a04b025812c0950461821800a082375c00260840048218c10000503e1bae001303f0024100607a00281d8c0e4dd5000c075036407603b01d80ea07c323259800980c000c54cc0e12401274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c05c0062a66070921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168981e981d1baa00240dc81b8c0e0dd50009808981c1baa301230383754607660706ea80062a6606c9201cd65787065637420536f6d65286465785f6f726465725f626f6f6b5f7265665f696e70757429203d0a20202020696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206465785f6f726465725f626f6f6b5f746f6b656e2c20222229203d3d20310a202020202020202020207d2c0a202020202020202029001640d4660120044602a64b300130163038375400314800226eb4c0f0c0e4dd5000a06c3259800980b181c1baa0018a6103d87a8000899198008009bab303d303a375400444b30010018a6103d87a8000899192cc004c0740062b3001301c0018980c9981f981e80125eb82298103d87a800040e9133004004304100340e86eb8c0ec004c0f800503c206c3300b3756602460706ea8c048c0e0dd5000801181a1baa0042223259800980b000c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009820801c66002009008803a016803a07c375c0028208c0f800503c181f0014012009004802207e303c00140e860706ea80122b300130150018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b300130410038cc004012011007402d00740f86eb8005041181f000a078303e002802401200900440fc607800281d0c0e0dd50024566002602600313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002608200719800802402200e805a00e81f0dd7000a082303e00140f0607c005004802401200881f8c0f000503a181c1baa004801206a40d481a8c0d8dd500188a4d153301d4911856616c696461746f722072657475726e65642066616c7365001365640701", - "hash": "598070a13f97093036bc75e11891e9931a98f2e2e4da8225bb6a1eaa" + "compiledCode": "59d54d010100229800aba4aba2aba1aba0aab9faab9eaab9dab9cab9a9bae0024888888888a60022a66006920148657870656374204d657373616765207b207661756c745f6571756974792c207072696365732c207574786f5f726566207d3a204d657373616765203d207369676e65645f6461746100168a99801a492e6578706563742061737365745f6c6973743a204d56616c7565203d20646573657269616c697365645f76616c756500168a99801a4949657870656374206f75747075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a494665787065637420696e7075745f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492a657870656374206163636f756e743a20557365724163636f756e74203d206f75747075745f646174756d00168a99801a494a657870656374206f75747075745f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a497b657870656374204465784163636f756e7442616c616e6365446174756d207b0a202020206163636f756e745f62616c616e63655f6d65726b6c655f726f6f743a20696e7075745f6d65726b6c655f726f6f742c0a20207d3a204465784163636f756e7442616c616e6365446174756d203d20747265655f726f6f7400168a99801a495b657870656374205472616e73666572496e74656e74207b20746f2c20616d6f756e745f6c323a207472616e73666572616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a496a657870656374204d6173746572496e74656e74207b206163636f756e743a2066726f6d2c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495f6578706563742043616e63656c5769746864726177616c496e74656e74207b20616d6f756e745f6c313a207769746864726177616c5f616d6f756e74207d3a2048796472614163636f756e74496e74656e74203d0a20202020696e74656e7400168a99801a4941657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d206465785f6163636f756e745f62616c616e63655f6f75747075747300168a99801a493f657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d206465785f6163636f756e745f62616c616e63655f696e7075747300168a99801a49e7657870656374205b6665655f6f75747075745d203d0a202020202020202020206f746865725f6f7574707574730a2020202020202020202020207c3e206c6973742e66696c746572280a202020202020202020202020202020206372656174655f6163636f756e745f6f7574707574735f66696c746572280a2020202020202020202020202020202020206665655f6163636f756e742c0a20202020202020202020202020202020202068796472615f6163636f756e745f7363726970745f686173682c0a20202020202020202020202020202020292c0a20202020202020202020202020202900168a99801a498b657870656374205769746864726177616c496e74656e74207b0a20202020616d6f756e745f6c313a207769746864726177616c5f616d6f756e745f7261772c0a202020207769746864726177616c5f6665655f6c313a207769746864726177616c5f6665655f7261772c0a20207d3a2048796472614163636f756e74496e74656e74203d20696e74656e7400168a99801a4964657870656374204d6173746572496e74656e74207b206163636f756e742c20696e74656e74207d3a20487964726155736572496e74656e74446174756d203d0a20202020696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a498c657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c696379280a202020202020696e707574732c0a20202020202068796472615f757365725f696e74656e745f616464726573732c0a20202020202068796472615f757365725f696e74656e745f7363726970745f686173682c0a202020202900168a99801a494e657870656374206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d206f75747075745f646174756d00168a99801a494365787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f6f75747075742e646174756d00168a99801a499d657870656374205b6465785f6163636f756e745f62616c616e63655f6f75747075745d203d0a202020206f7574707574735f61745f77697468280a2020202020206f7574707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a494c65787065637420696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d3a204465784163636f756e7442616c616e6365446174756d203d20696e7075745f646174756d00168a99801a499a657870656374205b6465785f6163636f756e745f62616c616e63655f696e7075745d203d0a20202020696e707574735f61745f77697468280a202020202020696e707574732c0a2020202020206465785f6163636f756e745f62616c616e63655f616464726573732c0a2020202020206465785f6163636f756e745f62616c616e63655f746f6b656e2c0a20202020202022222c0a202020202900168a99801a4929657870656374206163636f756e743a20557365724163636f756e74203d20696e7075745f646174756d00168a99801a499d657870656374205661756c744465706f736974496e74656e74446174756d4c32207b0a202020207661756c745f6f7261636c655f6e66742c0a202020206465706f7369746f722c0a202020206465706f7369745f616d6f756e742c0a20207d3a205661756c744465706f736974496e74656e74446174756d4c32203d20696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a493e657870656374206f75747075745f646174756d3a20557365724163636f756e74203d206f75747075745f696e6c696e655f646174756d286f75747075742900168a99801a493b65787065637420696e7075745f646174756d3a20557365724163636f756e74203d20696e7075745f696e6c696e655f646174756d28696e7075742900168a99801a492e657870656374206f6c645f656e7472793a205368617265735265636f7264456e747279203d206f6c645f6461746100168a99801a492f657870656374206f6c645f656e7472793a205368617265735265636f7264456e747279203d2066726f6d5f6461746100168a99801a492f65787065637420536f6d652866726f6d5f6461746129203d2063626f722e646573657269616c6973652866726f6d2900168a99801a495b657870656374206f75747075745f6f7261636c655f646174756d3a205661756c744f7261636c65446174756d203d0a202020206f75747075745f696e6c696e655f646174756d287661756c745f6f7261636c655f6f75747075742900168a99801a495865787065637420696e7075745f6f7261636c655f646174756d3a205661756c744f7261636c65446174756d203d0a20202020696e7075745f696e6c696e655f646174756d287661756c745f6f7261636c655f696e7075742900168a99801a494d657870656374205b7661756c745f6f7261636c655f6f75747075745d203d206f7574707574735f776974685f706f6c696379286f7574707574732c207661756c745f6f7261636c655f6e66742900168a99801a494a657870656374205b7661756c745f6f7261636c655f696e7075745d203d20696e707574735f776974685f706f6c69637928696e707574732c207661756c745f6f7261636c655f6e66742900168a99801a49a6657870656374205661756c745769746864726177616c496e74656e74446174756d4c32207b0a202020207661756c745f6f7261636c655f6e66742c0a20202020776974686472617765722c0a202020207368617265735f746f5f72656465656d2c0a20207d3a205661756c745769746864726177616c496e74656e74446174756d4c32203d20696e7075745f696e6c696e655f646174756d28696e74656e745f696e7075742900168a99801a495b657870656374205b696e74656e745f696e7075745d203d0a20202020696e707574735f61745f776974685f706f6c69637928696e707574732c20696e74656e745f616464726573732c20696e74656e745f706f6c6963795f69642900168a99801a4958657870656374206465785f6f726465725f626f6f6b5f696e7075745f646174756d3a204465784f72646572426f6f6b446174756d203d0a202020206465785f6f726465725f626f6f6b5f7265665f696e7075745f6461746100168a99801a493465787065637420536f6d65286f776e5f696e70757429203d20696e70757473207c3e2066696e645f696e70757428696e7075742900168a99801a491e72656465656d65723a2048796472614163636f756e7452656465656d657200168a99801a493d657870656374206f7065726174696f6e3a2050726f6365737348796472614163636f756e744f7468657252656465656d6572203d2072656465656d65720016488888888888888888888888888888888888889660033001302b37540633722911009b8f4881009b87480026e1d20029ba5480026e1d2004918179818000c8c0bcc0c0c0c00066e1d20069ba548009222222222229800981d005cc0e402e4646600200200444b30010018a5eb7bdb1822653001375c607200337566074003303e00248896600260220071598009808001c4006200a81d226607e66ec0dd48019ba60023300600600140e8303c00140e922232598009806000c4c9660020030038992cc0040060090048024012264b30013041003803401503e1bae0014104607c00281e0c0e8dd50024566002601600313259800800c00e264b300100180240120090048992cc004c10400e00d00540f86eb8005041181f000a078303a375400900240dc81b8c0e0dd5001c88c8cc00400400c896600200314c103d87a8000899192cc004cdc8802800c56600266e3c014006260186607c607800497ae08a60103d87a800040e5133004004304000340e46eb8c0e8004c0f400503b488c8cc00400400c896600200314c0103d87a80008992cc004c010006260166607a00297ae0899801801981f8012070303d00140ed22259800801452844ca600264b3001300d303a37540031375a6076607c6eacc0f8c0ecdd5000c5200040e0607a003375e607a607c00337560069112cc0040062b30013002006899802801a400114a081d2264b30013375e607a0029810140008acc004cc018010dd6981f18209bab303e001898019ba630420028a5040ed1598009980300224001130030078a5040ec81d8c10000503e0ca6002003004911981f0011981f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0f00066eacc0f400660820069112cc004c05000e2b300130130038998029808198211ba60024bd70000c4cc01530103d87a800000640f519800803c006446600e0046608866ec0dd48029ba6004001401c81e8607e00481ea29422942294103e244444453001304000798201820803c889660026024607e6ea800e264b300100180144c966002003003801c00e0071332259800800c016264b30010018992cc00400600f13259800800c566002609600519800801c66002003009804201c804201c80420908044022011008413060920028238c12400a00d006803401904a1823800a08a375c002608c0048238c11000504218201baa003800a07a9112cc004c048c0fcdd5001c4c9660020030028992cc004006264b300100180244c966002003159800982400146600200713259800980b800c4c9660020030078992cc0040062b3001304b0028992cc004c068006264b300100180544c966002003159800982700146600200300c805a022805a096805c02e01700b413c60980028250c120dd50014566002603200313259800800c02a264b3001001805c02e0171332259800800c036264b3001001807403a01d1332259800800c042264b3001001808c04602313259800982a801c04e0248290dd6800c0450551829000a0a0375a00260a200500e4148609e0028268dd68009827001402d04f1826000a0943048375400500941148228c118dd5000c021048402201100880420983049001411c608a6ea800a2b300130160018acc004c114dd5001401e00c823200c821104218219baa001802a016802a08a802c01600b0054124608c0028220c11800a007003801c00d0471822000a0843040375400700140f491111919912cc004c0540062646644b300100a899912cc004c06c006264b3001001810c4c966002609e0050048112098304d001412c60926ea80322b3001301a0018acc004c124dd5006400a04082522b300130180018acc004c124dd5006400a04082522b300130150018acc004c124dd5006400a04082520408231046208c411826464664530013756609c0053758609c609e609e005304f304f304f304f304f304f304f304f304f0019bae304e00198251baa00e9119809001119baf3051304e37540020053758609c00891111112cc004c09000e2b30013232330010010092259800800c528456600266ebc00cc150c160006294626600400460b20028291056180e9982a182a982b002a5eb8229462a660a09214e7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6f726465725f626f6f6b5f7363726970745f6861736829203f2046616c73650014a0827a2b300130230038acc004c8c8cc004004024896600200314a115980099baf003305430580018a51899801001182c800a0a44158603a660a860aa00a97ae08a518a9982824814b7769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c2068796472615f6163636f756e745f7363726970745f6861736829203f2046616c73650014a0827a2b3001301e0038992cc004c094c148dd5000c4c966002604a60a66ea80062b300132323300100100b2259800800c528456600266ebc00cc158c168006294626600400460b600282a1058180f9982b182b982a1baa0014bd704528c54cc149241417769746864726177616c5f7363726970745f76616c696461746564287769746864726177616c732c206f776e5f7363726970745f6861736829203f2046616c73650014a0828a2a660a49215665787065637420536372697074286f776e5f7363726970745f6861736829203d0a202020202020202020206f776e5f696e7075742e6f75747075742e616464726573732e7061796d656e745f63726564656e7469616c0016414460ac60a66ea8c158c14cdd5181098299baa30563053375400302b41406600400201b13259800981298291baa0018acc00566002b30019800980d9bab302130533754604260a66ea8c158c14cdd5000d30101a0009119b87002001405d14a3153305149011369735f6e6f5f76616c7565203f2046616c73650014a0828229462b300159800981298291baa00d8a508a51414114a315330514911369735f6e6f5f646174756d203f2046616c73650014a082810504566002646600200201044b30010018a508acc004cdc79bae30580010078a51899801001182c800a0a4415914a315330514911f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a08282294105040ad05019801000806a09e413c8278609a609a609a609a609a00260926ea8cc01cdd61826000822982600098239baa0103046375401501e80f407a03c8260c120004c120c124004c110dd50034566002602600319800982398221baa006912cc00400629344c966002003149a264b3001337206eb8c11cc12c00cdd71823800c4cc010010cc128004c13000a2a6608c9201326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f726465720016411460940028240c12800504748888c8cc004004014896600200313304c337606ea4014dd300225eb7bdb1822653001375c609400337566096003304f00248896600266e4002400e2660a066ec0dd48049ba60080058acc004cdc7804801c4c9660026042609c6ea80062660a266ec0dd4805182918279baa001002880120989800804c022004803a2660a066ec0dd48019ba600233006006001412c8258609a002825a4444646600200200a44b300100189982619bb0375200a6ea00112f5bded8c113298009bae304a0019bad304b00198278012444b300133720012007133050337606ea4024dd4004002c56600266e3c02400e264b30013021304e3754003133051337606ea4028c148c13cdd50008014400904c4c004026011002401d133050337606ea400cdd400119803003000a096412c304d001412d259800800c528c528208c91192cc004c060c118dd5000c52f5bded8c1137566094608e6ea800504419806001000c888c8cc004004010896600200310048994c004dd71824800cdd69825000ccc00c00cc1380090041826000a094918241824982498249824800c8c120c124c124c124c124c124c124c124c1240064602a6608e60206608e6ea40052f5c06608e980103d87a80004bd704888ca6002003004801a00222259800801440063300100398270014cc010004c134009003209691919800800801112cc004006297ae08991991199119801001000912cc00400620071323304f374e6609e6ea4014cc13cc130004cc13cc1340052f5c06600600660a2004609e0028268dd598250019bae304700133003003304c002304a001412122372866e280080066e0120039b804801e44b300130183370c002900244cdc199b8e0023370600290022404113370c66e38008cdc1800a4008901020869b804800a45300100199b81371a0040030025c626e01200f9b80480064b30013370e6e3400520408800c54cc10d24138657870656374206279746561727261792e6c656e67746828726f6f7429203d3d20626c616b6532625f3235365f6469676573745f73697a650016410937029000488c8cc00400400c88cc00c004c00800a44464b3001301a0018992cc00400600713259800800c012009004899912cc00400600d13259800800c01e00f007803c4c96600260a4007009804209e375c0028290c13c00504d1bad001304e002802209e304c001412860906ea80122b300130190018992cc00400600713259800800c012009004899912cc00400600d13259800800c56600260a2005159800980f98261baa0018992cc00400601113259800800c026013009899912cc00400601713259800800c03201900c80644cc896600200300e8992cc00400601f00f807c03e264b3001305a003808c0410571bae001416860ae00282a8dd7000982b00120ae305400141486eb4004c14c00a01282a0c14400504f18269baa001803a094803a09c803c01e00f0074148609e0028268dd68009827001401104f1826000a09430483754009159800980b800c4c9660020030038992cc00400600900480244cc89660020030068992cc00400600f007803c01e26644b3001001804c4c96600200300a805402a01513259800982a801c0320168290dd7000a0aa305200141406eb8004c1440090521827800a09a375a002609c005004413c60980028250c120dd50024009045208a4114608c6ea800e444b3001337120049000440063300100399b840024805266e2ccdc019b85002480512060001400c82224444646600200200a44b30010018802c4c966002003133004304e002006899802982700119801801800a098304e001412d22225980099b88002480c22600200515980099b87002480c2266008900111801000c56600266e20009203889980199b8e488103020408003370000490189180119bca4a2003124bded8c101400001012000411482290454dc3a41fc0722337600046ea00066e1d200a9baf4c10180004888888888888888888888888888888a6002603c03d22229800802400e0052229800801c006004802102148896600266ebcc1a4c198dd5181a18331baa00130190028992cc00400633001001899baf001004825204c825412a09504a41b064b30013036306637540031306a3067375400315330654913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016419060d260d460d460cc6ea8c1a4c1a8c198dd5000c52820c69112cc004cdd7983498331baa00130190028992cc00400633001001899baf001004825a04c825c12e09704b41b064b30013036306637540031306a30673754003153306549012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016419060d260d460d460cc6ea80062941063488ca60020030038012002222598008014400626530010049836801e6002005375c60d0003375660d200322232598009812800c5300103d87a80008981e998379ba60014bd7020d4329800800c00e00480088896600200510018994c00401260e800798008014dd71837800cdd69838000c888c966002608c00314c103d87a8000898221983b1ba80014bd7020e2337000040028149004183900120e0408c8020c1ac00906948896600266e2400d200089980b001000c4cc0580040090634888c8cc00400400c896600266e2400c0062910100899b8b3301500500133002002301400141952259800981b99b8600148012266e2d20fe033301000233706002900244cdc5a400066e2ccc048008004cc040008cdc19808800a400883124646600200200444b30010018a5eb7bdb182264660d266ec0c198004dd319198008009bab30680022259800800c52f5bded8c11323306c3376060d20026ea0c044dd698350009980180198370011836000a0d433003003306b0023069001419d300700791111194c0040060070024004444b300133712004900044c0052f5c112323298008034c05c0164600a660e2004003375a60dc0048030c1b00066002013008800a00e41a1222232330010010022233006480089660026016003130024bd70448c8ca600200d23006330700020019bad306d002401860d60033001008803cc05c00500620ce91114c00401200700291980200091801800a0124888888888888a60024444b300130460018802466002009003991900118090009983b19bb037520046ea00052f5bded8c122232598009818000c530103d87a8000898241983d1ba60014bd7020ea9800801401600922232598009826800c530103d87a8000898259983e9ba80014bd7020f033700002004818101020e294c00400697adef6c6091198060011bab304130733754608260e66ea80050234a60020034bd6f7b630488cc030008dd5982098399baa001408d22225980099b890044800a2660493001004801c00500c00144cc09000a60026046009003800a01841c522225980099b88004480122b300133710004900244cc0926002009003800a0184881200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f9761008998124c00401200748920000000000000000000000000000000000000000000000000000000000000000000403130013023002800d221200000000000000000000000000000000000000000000000000000000000000000004030838a2b300133712900200144cc091221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f97610098009811802400e00280622660493001002800d22120000000000000000000000000000000000000000000000000000000000000000000403130013023004801d2212000000000000000000000000000000000000000000000000000000000000000000040308389071488c8cc00400400c8966002608c0031337149110130000038acc004cdc4000a40011337149101012d0033002002301b00189980419b8400148050cdc599b803370a002900a240c00068389071488cc004888c8c8cdd8191ba73307a30770013307a30780014bd7019bb030760023076001307700198008034880060090039bad30760014019300100591000c00e0050014014446600490011192cc004cdc4800a40091598009824000c6600200900380148c05cdd4000a0308acc004c11c00633001004801ccdc00012407f2301737506040603c00280c22b30013370e004905f00c4c8cc0040048c060dd48009119803240044b3001301a00189801245008cc00401e00d33700002903fc8cc0100108c010cdc5001000a01441d919800802400e66e00009207f9180b9ba9001401c839907320e68acc004cdc3800a401919800802400e66e0000920ff02919802a40044b30013370e004906600c492f7b63001014000010120008992cc004cdc38012417c0519800803c01a66012012440032301a3374a004002805a330010078034cdc0001241fe0329800804401e66014014440030019180d99ba5003001403480d90762cc004cdc4a41002800513370066e0000920ff134803a266e0000920f10141d483a9018456600266e1c00520088acc004cdc38012417c0519800802400e6600c00c4400323017374e002804233001004801ccdc0001241fe0329800802c0126600e00e440030019180c1ba7001402880c10734566002602a00315980099b87002483f80a2646466002002460326e9800488cc01d2002259800980d800c4c0092f5bded8c1123232980080348c018cc200040080066eb4c1f40090061919bb0308001001308001308101001375860f600330010098044c09c00500520ee33006006220028cc00401200733700004905f8148c8ca60020030039180d1ba60014004444b300133712004900044c0052f5bded8c112323298008034c09c0164600a6610202004003375a60fc0048030c8cdd81840808009840809841008009bac307c0019800805402600280290781980380391001203041cd124bded8c010140000101200041cc839907320e633706002902048c8cc004004008896600200314bd6f7b63044ca60026eb8c1cc0066eacc1d00066600600660f00049112cc00400a2a660ea92124657870656374205061697228702c205b5f2c202e2e5d206173207829203d20696e6e657200168cc004006007323200432330010010042259800800c5268992cc0040062b30013004375a60f660fc005149a2a660f292011f76616c756520646f65736e2774207361746973667920707265646963617465001641e1133225980099b90375c60f80046eb8c1f00062b30013006375a60fa0051330050053307f0013081010038a9983da491f76616c756520646f65736e2774207361746973667920707265646963617465001641e9153307b491276b65797320696e207061697273206172656e277420696e20617363656e64696e67206f72646572001641e860fc00460fc00283e0c1f800507b14c004c12800694294507548894cc1e12401234475706c696361746520706f6c69637920696e20746865206173736574206c6973742e0016404c83c060ec00283a12222222298009114c004cc0c800c00a97adef6c60911192cc004c144c1f8dd5000c4ca6002007375c610602003375c61060261080200300440406eb0c20804c1fcdd5000c54cc1f524121546f6b656e2068617368206e6f7420666f756e6420696e20746f6b656e206d6170001641f0646600200200a44b30010018a60103d87a80008992cc004cdc78031bae308001001898289984180984080800a5eb82266006006610a0200483f0c20c04005081012062911112cc004cdc4802a400d13302d9800802c012005001402800713302d00398009815802c012005001402883d24444b3001337100089004456600266e2000920088998164c004012007002800a01048812085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b1008998164c004012007489200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040253001302a002800d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483ca2b300133712900400144cc0b12212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b10098009815002400e6054005001402113302c980080140069101200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040253001302a004801d221200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000402483c90794888c9660020071323233223300b0023371491101280059800800c4cdc52441035b5d2900006899b8a489035b5f20009800800ccdc52441025d2900006914c00402a00530070014029229800805400a00280510232102025980099b880014803a266e0120f2010018acc004cdc4000a41000513370066e01208014001480362c83d907b1bac307e002375a60f80026466ec0dd4183e0009ba7307d001375400713259800800c4cdc52441027b7d00003899b8a489037b5f20003232330010010032259800800c400e264b30010018994c00402a610202003337149101023a200098008054c2080400600a805100a18420080144ca600201530810100199b8a489023a200098008054c20804006600e66008008004805100a18420080121040230840100142040466e29220102207d0000341f86eac00e264b3001001899b8a489025b5d00003899b8a489035b5f20009800800ccdc52441015d00003914c00401e0053004001401d229800803c00a002803902020fc3758007133007375a0060051323371491102682700329800800cc09cdc68014cdc52450127000044004444b300133710004900044006264664530010069816002ccdc599b800025980099b88002480522903045206e42000466e2ccdc0000acc004cdc4000a402914818229037210002004401866e0c00520203370c002901019b8e00400241f46eb800d081011b8a4881022c20009801001244445300122222330329800802c012605600680ca60026605e00a60560079800a400148102002b8c66002902052040800ae319800a41000348102002b8c66002906000d2040800ae30911112cc004cdc4802a401d1330379800802c01e007002800a01c00489981b8024c004c0c401600f003801400500e210802488888c96600330013370e0026eb4c21804c20c04dd5001528528a10002899819cc00401a00b302c00440686644b3001337100069008456600266e20009201089981acc00400e00b002800a01648920b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0089981acc00400e00b4892085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302f002800d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a44120000000000000000000000000000000000000000000000000000000000000000000403084100a2b300133712900800144cc0d522120b22df1a126b5ba4e33c16fd6157507610e55ffce20dae7ac44cae168a463612a0098009817801c016605e005001402d1330359800801400691012085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a4412000000000000000000000000000000000000000000000000000000000000000000040313001302f003802d2212085c09af929492a871e4fae32d9d5c36e352471cd659bcdb61de08f1722acc3b100a441200eb923b0cbd24df54401d998531feead35a47a99f4deed205de4af81120f976100a441200000000000000000000000000000000000000000000000000000000000000000004030841009082011bad3086013083013754004660666eb8c144c20c04dd50011bae3050308301375400515330810149120657870656374206272616e636820213d206e65696768626f722e6e6962626c6500164200046605e00a605600730020029192cc004c144006298103d87a80008992cc006600260a46eb4c2000400694294507d4530103d87a8000898281984100983f800a5eb8107d4c00488006444b3001337120029000452f7b63010140000101200089980119b8e0053370200800266e0400400d07f48896600266e2400520008a5ef6c601014000010120008998014c004cdc0802000c00e00ab8c19b8100100341fd001400c83e0dc6800a44446645300122225980099b8f330060030010048cc00400e0050014015153308501490129657870656374206578636c7564696e67286b65792c2070726f6f6629203d3d2073656c662e726f6f740016421005222225980099b8f9800802400a006803001633001004800c00d006454cc2180524013465787065637420696e636c7564696e67286b65792c206f6c645f76616c75652c2070726f6f6629203d3d2073656c662e726f6f74001642140522225980099b8f9800801c00a002802801226600c00600315330850149013065787065637420696e636c7564696e67286b65792c2076616c75652c2070726f6f6629203d3d2073656c662e726f6f740016421004911192cc00412a265300122259800982e9845009baa0038992cc00400600513259800800c4c9660020030048992cc00400600b13259800984a00801c4cc896600260c800313259800800c026264b30010018acc004c2600400a26530010018014015001111192cc004c1a8006264b3001001807c4c96600200301080840420211332259800800c04a264b3001001809c4c9660026144020071330440012259800801402a26464b300100180c40620311332259800800c6600202100189802985400803202080d406a03501a42a4046eb4004c2880400a030853808c28004004c28c040090a101405109f011bab001809c04e026851008c27c0400509d011bae001309e01002427c0461380200284d008c26004dd5001c56600260d200313259800800c03e264b30010018084042021010899912cc00400602513259800800c04e027013809c4cc89660020030158992cc00400602d01680b405a264b300130a501003805c05d0a2011bae001429404614402002850008dd7000985080801214402309f010014274046eb8004c2780400909f01184e00800a13402309801375400700e42540484a808c25804dd5001402909501402a01500a8052132023096010014250046124026ea801a2b300130630018992cc00400601313259800800c02a01513259800984c80801c4cc0ec00489660020050078992cc0040063300100189801184e00801c039011403a01d00e807213a02309a0100242600500b4258046eb000601500a426404612c0200284a008c24804dd5003402108f01211e021330360012259800801402626464b3001001805402a01500a899912cc00400601900c8992cc00400601b13259800800c03a01d00e80744cc89660020030108992cc004006023011808c046264b300130a00100389805985000806404909d011bae001428004613a0200284d808dd7000984e00801213a02309a010014260046eb000601900c426c046eb8004c2500400909901184900800984a80801212602308f0137540090064244046eac00600b005802a12802309101001423c04612202005003801c00e006849008c23c0400508d011845809baa003800a110029843809baa04b8cc004896600200314bd7044cc23004c22404c23404004cc008008c2380400508b014896600260b66112026ea80062646611a0266ec0c23804004c23804c23c040052f5bded8c0611c026114026ea80062646600200264660020026eacc23c04c24004c23004dd5001912cc004006297ae08998478098468098480080099801001184880800a11c022259800800c52f5bded8c1132332233002002330070070012259800800c400e2661220261240200266004004612602002848008c24004008cc008008c2400400508d01210e029194c0040060054bd7020022225980080144006330010039848008014cc23804c23c04008005003211a029119846009ba90010029111919800800802112cc00400620091330033090010013300200230910100142380522259800982e9845009baa0038992cc00400600513259800800c00e007003801c4c966002612402007005802211e02375c002849008c23c0400508d011845809baa003800a110029843809baa04b912cc0040062900044c0d8cc008008c2380400508b01488c8cc00400400c896600200314bd6f7b63044c8ca60026eacc2380400a660080086124020072229800800c022b300159800983200244c19000e294108e014522010089b943371400800684700a00481090441bae308c01001308f0100142340523259800982e1844809baa0018992cc00400610a0313233032001225980080144c96600266e3cdd99ba60010078800c54cc234052401306578706563742063626f722e73657269616c6973652876616c756529203d3d2073657269616c697365645f76616c75650016423004602e0071323259800800c228061140308a0184500c4cc896600200308c0189981c1bab001225980080144c01cc2600402226464b300100184800c240061200309001899912cc004006124030920184900c4c8c018c2740401cdd6800c2480509d011bae001309601002426c04612802002612e0200484a80a1180308c0184600a12e02375c00261200200484a808c23804004c2440400908f011bab00184280c2140610a02848008c23404c22804dd5000c54cc2200524014465787065637420536f6d6528646573657269616c697365645f76616c756529203d2063626f722e646573657269616c6973652873657269616c697365645f76616c7565290016421c04601200291111111114c004c02802a601201322259800801466002007300b001a5eb8100344c96600200313259800801c400633001005998061806801800d2f5c08029098011bae3099010038cc0040126134020033300b00233046375c6132020066eb8c26404005004212e02309901002425805300300348888c8c8c8cc896600260da01b13232332298009851809851808014dd61851008014c28c04c28c040066eb8c28804005222298009bab30a6010049bac30a60130a70130a70130a70130a7010049853809853808014c29804009222232329800985680800cdd7185600800cdd618560080724453001375c615e02007375c615e026160026160020073232330010010032259800800c52f5c11332259800acc004cdd7985a009858809baa30b40130b50130b101375400400b1323300100132330010013756616c02616e026166026ea8c2d804c2dc04c2cc04dd5002112cc004006297ae0899199119198008009bab30b8010042259800800c400e26466178026e9ccc2f004dd48029985e00985c808009985e00985d00800a5eb80cc00c00cc2f804008c2f0040050ba011bae30b4010013300300330b90100230b70100142d40444b30010018a508acc004cdc79bae30b6013758616c0200201314a313300200230b70100142c00485a00a29410ae0144cc2cc04008cc010010006266008008002857008c2c804004c2cc040050b001182f8014c2bc04c2b004dd5037cdd7185780803cc2bc0401522222259800802427806264b300130b7010058992cc0040062b300130850130b301375400313259800800c28806264b30010018992cc0040061480313259800985e00801466002007159800800c566002611402616e026ea8006264b300100185380c4c9660020030a801899912cc0040061540313259800800c2ac06264b300130c201003899832002112cc00400a2660cc00644b30010028cc004c12c01664646600200203244b30010018a5eb841018000810180008101800044cc8966002600a0051330c901374e66192020046eb0c32804004cc32404c32804c32c04004cc32404c32804c32c04c32c040052f5c1159800acc004cdd79865009863809baa30ca0130cb0130c701375400402d1323300100132330010013756619802619a026192026ea8c33004c33404c32404dd5002112cc004006297ae0899199119198008009bab30ce010042259800800c400e264661a4026e9ccc34804dd480299869009867808009986900986800800a5eb80cc00c00cc35004008c348040050d0011bae30ca010013300300330cf0100230cd01001432c0444b30010018a508acc004cdc79bae30cc01375861980200203314a313300200230cd0100143180486500a29410c40144cc32404c32804004cc32404dd399864808011bac30ca0130cb01001330c90130ca0130cb0130cb010014bd7044cc32404c32804004cc32404c32804c32c04004cc32404dd399864808011bac30ca0130cb0130cb010014bd7021880243100461900200266004004619202002863008cc17403405a64646600200204844b30010018a5eb841018000810180008101800044cc8966002600a0051330c901374e66192020046eb0c32804004cc32404c32804c32c04004cc32404c32804c32c04c32c040052f5c1159800acc004cdd79865009863809baa0020168991980080099198008009bab30cc0130cd0130c901375400844b30010018a5eb82264664464660020026eacc338040108966002003100389919869009ba7330d201375200a661a402619e02002661a40261a00200297ae03300300330d40100230d2010014340046eb8c32804004cc00c00cc33c04008c334040050cb01112cc00400629422b30013371e6eb8c33004dd618660080080cc528c4cc008008c334040050c6012194028a504310051330c90130ca01001330c901374e66192020046eb0c32804c32c04004cc32404c32804c32c04c32c040052f5c11330c90130ca01001330c90130ca0130cb01001330c901374e66192020046eb0c32804c32c04c32c040052f5c08620090c40118640080099801001186480800a18c023305c00d016488a6002660bc609c01660b400730c9010029bac30c801002986480800cdd6186400800a4444530013758619a020053758619a02619c02005309b0130353758619a02619c020093758619a020089111192cc00400a17e0313259800986a00801c56600200d0c1018992cc004c3540401e264b3001598008034528c54cc340052401176e6f5f6f746865725f696e70757473203f2046616c73650014a086780a2b3001598008024528c54cc3400524011e69735f7769746864726177616c5f6665655f70616964203f2046616c73650014a086780a2b300159800992cc004006330010018992cc004006330010018cc004dd7186b80986a009baa0029bae30d70130d4013754003376603f30d301375404a9111192cc004c2ac0400a266e3e60020030039bb3374c029375861b80261b2026ea80a9056002456600261540200513232332259800acc0066002660ec6098002031374c6098005223370e00400285080a29462a661b60292011a69735f62616c616e63655f75706461746564203f2046616c73650014a086d00a2b30013371f3001005803cdd6187000987080801c00600482c802229462a661b6029211e69735f6e65775f62616c616e63655f636f7272656374203f2046616c73650014a086d00a29410da011bae30de01001375c61bc0200461bc0200261b2026ea80aa29410d60121ac0230800100443340504743340619a030cd0186680a1b20232598009851809869809baa0018986b80986a009baa0018a9986900a4812c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001643440461ac0261ae0261ae0261a6026ea800e196028232196030cb0186580c32c050d801192cc004c28804c34804dd5000c4c35804c34c04dd5000c54cc3440524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001643400461aa0261ac0261ac0261a4026ea8c35404c35804c34804dd5001c528c54cc3400524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a086780a2b30015980099baf374c613402660d6660d665300100180652f5bded8c080088896600200510018cc00400e61b202005329800800c00a6eacc36404c36804c35804dd5186c80986d00986b009baa30d9010034004444b30010028800c4c8cc8a600200d30df010059919800800802912cc0040062661be0266ec0dd48021ba60034bd6f7b63044ca60026eb8c374040066eacc3780400661c4020049112cc004cdc8004001c4cc38c04cdd81ba9008374c00e00b15980099b8f0080038992cc004c2d004c38404dd5000c4cc39004cdd81ba900930e50130e20137540020051002437c0464b300159800800c528c52821c6028a60103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011833994c0040060114bd6f7b6302002222598008014400633001003986c808014ca60020030029bab30d90130da0130d601375461b202006800888966002005100189919914c00401a61be0200b32330010010052259800800c4cc37c04cdd81ba9004374c00697adef6c608994c004dd7186e80800cdd5986f00800cc388040092225980099b900080038998718099bb037520106e9801c0162b30013371e01000713259800985a009870809baa0018998720099bb0375201261ca0261c4026ea800400a200486f808c966002b30010018a518a50438c0514c103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011833994c0040060154bd6f7b6302002222598008014400633001003986c808014ca60020030029bab30d90130da0130d601375461b202006800888966002005100189919914c00401a61be0200b32330010010052259800800c4cc37c04cdd81ba9004374c00697adef6c608994c004dd7186e80800cdd5986f00800cc388040092225980099b900080038998718099bb037520106e9801c0162b30013371e01000713259800985a009870809baa0018998720099bb0375201261ca0261c4026ea800400a200486f808c966002b30010018a518a50438c0514c103d87a8000898590099872009ba60014bd7021be02329800800c022006800888966002005100189919914c00401a61d60200b32330010010052259800800c4cc3ac04cdd81ba9004375000697adef6c608994c004dd7187480800cdd6987500800cc3b8040092225980099b900080038998778099bb037520106ea001c0162b30013371e010007132598009860009876809baa0018998780099bb0375201261e20261dc026ea800400a2004875808c96600261800200314c0103d87a80008985f0099878009ba80014bd7021d6023370000e0051330ef01337606ea400cdd400119803003000a1d40243a80430ec0100143a8048030dd71872008009bad30e50100130e7010024394051330e301337606ea400cdd300119803003000a1bc0243780430e0010014378048030dd7186c008009bab30d90100130db0100243640480190d6011ba60018a518a9986800a4812569735f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a086780a2b300159800cc0040be6e98c19ccc1acc26804dd59850009869009baa30a00130d2013754040003223370e00400284b00a29462a661a0029211769735f746f6b656e735f6275726e74203f2046616c73650014a086780a2b3001323300100102f2259800800c528456600266e3cdd7186b808008194528c4cc008008c360040050d10121aa028a518a9986800a492669735f68796472615f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a086780a29410cf014528219e028a50433c0514a086780a29410cf01184c80998208060124308050d20118698080321a20286000a1a20230d201002434004b30010038a518acc004c3480400e264b300100185f00c4c96600261a80200519800984c0099820007011cdd3184c009bab309e0130d0013754003223370e00400284a00a17e02868808c348040050d001191919800800802912cc004006297ae0899912cc004c01400a2661aa020046600800800313300400400143400461a80200261aa02002869008cc1a00a008a2a6619802920118756e6578706563746564206f74686572206f7574707574730014a08678090cf010899192cc004006164030b20185900c2c80626644b300100185a00c4cc1b0dd5800912cc00400a2600e6198020111323259800800c2e006170030b80185c00c4cc89660020030ba0185d00c2e806264600c61a20200e6eb400617402868808dd7000986500801219e0230c80100130cb010024324050b40185a00c2d0050cb011bae00130c401002432404618402002618a0200486180a26464b300100185800c2c006160030b001899912cc0040061640313306a375600244b30010028980398650080444c8c9660020030b60185b00c2d80616c031332259800800c2e006170030b80189918031867808039bad00185c00a19e02375c002619002004866808c31804004c324040090c70142c806164030b2014324046eb8004c308040090c70118600080098618080121820285600a17e0237560030ab0185580c2ac050c201185f80800a17a023756002617c020050a80185400c2a0050bf01185e00800a1740230b80137540030a60142d4050a60185300c2980614c0285e80a14a0283ba14a0285c808c2e8040050b801185d00801428c06146030a30185180a1760230b80100142d8046168026ea80061420285880a142030a10185080c284050b901192cc004c20c04c2cc04dd5000c4c2dc04c2d004dd5000c54cc2c8052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642c404616c02616e02616e026166026ea8c2d804c2dc04c2cc04dd5000c27c050b401185a808022166020c2b004c2b004c2b004004c2ac0400830a101001309d013754660b66eb0c2800400426404c28004004c26c04dd5032456600260d801b13232332298009851809851808014dd61851008014c28c04c28c04c28c04c28c040066eb8c28804005222298009bab30a6010049bac30a60130a70130a70130a70130a7010049853808014dd71853008012444465300130ac010019bae30ab010019bac30ab0100d488a60026eb8c2b80400e6eb8c2b804c2bc04c2bc0400e64646600200200644b30010018a5eb8226644b30015980099baf30b30130b00137546166026168026160026ea80080162646600200264660020026eacc2d404c2d804c2c804dd5185a80985b009859009baa0042259800800c52f5c1132332232330010013756616e0200844b30010018801c4c8cc2ec04dd39985d809ba9005330bb0130b801001330bb0130b9010014bd7019801801985e80801185d80800a17202375c61660200266006006617002004616c0200285a008896600200314a115980099b8f375c616a026eb0c2d4040040262946266004004616c020028578090b3014528215a028998590080119802002000c4cc0100100050ad01185880800985900800a15e02305e0029857009855809baa06e985700803244444b300100384e00c4c966002616a0200913259800800c5660026106026162026ea8006264b300100185000c4c96600200313259800800c28806264b300130ba010028cc00400e2b30010018acc004c21c04c2d404dd5000c4c9660020030a9018992cc0040061540313259800985e80801c4cc17c00489660020051332298009860808014dd61860008014c304040066eb0c30004005222298009bac30c40100298490098161bac30c40130c50100498498098161bac30c40130c5010029bac30c40100448889660020030b5018992cc004c3280400a2b300100585b80c4c96600261960200d13259800acc00401a29462a6618c02921176e6f5f6f746865725f696e70757473203f2046616c73650014a086280a2b300159800802c528c54cc318052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a086280a2b30015980099912cc004006330010018992cc004006330010018cc004dd71867009865809baa0029bae30ce0130cb013754003376603130ca01375403a9111192cc004c27c0400a266e3e60020030039bb3374c011375861a60261a0026ea808904b002456600261420200513232332259800cc004cc1b4c10c004c1a40326e98c10c00a4466e1c0080050980144cdc7cc00401600f375861ae0261b00200700180120a00088a504344046eb8c35404004dd7186a80801186a808009868009baa0228a50433404866808c1dc0110c40140f90c40186200c3100618802868008c9660026134026194026ea80062619c026196026ea80062a66192029212c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016432004619a02619c02619c026194026ea80121840281ea184030c20186100c308050cf011828808192cc004c26004c32004dd5000c4c33004c32404dd5000c54cc31c052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d00164318046196026198026198026190026ea8c32c04c33004c32004dd5001c528c54cc3180524012669735f6465785f6163636f756e745f62616c616e63655f75706461746564203f2046616c73650014a086280a2b30015980099baf374c612002660c260ac01060ba60ae0146e9800629462a6618c029212c69735f63616e63656c5f7769746864726177616c5f616d6f756e745f6d61746368696e67203f2046616c73650014a086280a2b300159800cc0040966e98cc184c174c24004dd5984b009864009baa30960130c8013754030003223370e00400284600a29462a6618c029211d69735f6d696e745f76616c75655f636f7272656374203f2046616c73650014a086280a2b300132330010010252259800800c528456600266e3cdd71866808008144528c4cc008008c338040050c7012196028a518a9986300a492d69735f68796472615f63616e63656c5f7769746864726177616c5f617574686f72697a6564203f2046616c73650014a086280a29410c5014528218a028a5043140514a086280a29410c5011981b982800780dc2e0050c801186480802a18e0285b00a18e0230c801001431804194c00404a97ae10101800081018000810180004896600260060051330c001374e66180020046eb0c30404004cc30004c23004004cc30004c22c040052f5c1159800acc004cdd7986080985f009baa308c0130be01375400401f1323300100130703756611a02617e026ea8c23404c2fc04dd5001912cc00400629422b30013371e6eb8c30c04dd618618080080d4528c4cc008008c310040050bd012182028a5042ec051330c00130c101001330c001374e66180020046eb0c23004004cc30004c22c040052f5c11330c00130c101001330c001308c01001330c001374e66180020046eb0c22c040052f5c085d8090bb0120603305600801032323300100101d2259800800c52f5c21018000810180008101800044cc8966002600a0051330c201374e66184020046eb0c30c04004cc30804c30c04c31004004cc30804c30c04c31004c310040052f5c1159800acc004cdd79861809860009baa0020118991980080099198008009bab30c50130c60130c201375400844b30010018a5eb82264664464660020026eacc31c040108966002003100389919865809ba7330cb01375200a6619602619002002661960261920200297ae03300300330cd0100230cb010014324046eb8c30c04004cc00c00cc32004008c318040050c401112cc00400629422b30013371e6eb8c31404dd618628080080e4528c4cc008008c318040050bf012186028a5042f4051330c20130c301001330c201374e66184020046eb0c30c04c31004004cc30804c30c04c31004c310040052f5c11330c20130c301001330c20130c30130c401001330c201374e66184020046eb0c30c04c31004c310040052f5c085e8090bd0118608080099801001186100800a17e0233055008010899192cc00400615e030af0185780c2bc0626644b300100185880c4cc194dd5800912cc00400a2600e618a020111323259800800c2d40616a030b50185a80c4cc89660020030b70185b80c2dc06264600c61940200e6eb400616e02865008dd700098618080121900230c10100130c4010024308050b10185880c2c4050c4011bae00130bd01002430804617602002617c0200485e00a1560285d008dd5800c2a806154030aa0142f40461740200285c008c2d804dd5000c2a0050b30142a006150030a80185400a1760285180a0ea85180a16e0230b80100142d8046170020050a10185080c284061420285c808c2d8040050b4011859009baa00184f80a15e0284f80c27c0613e0309f0142dc0464b300130810130b1013754003130b50130b201375400315330b0014913265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642bc04616802616a02616a026162026ea8c2d004c2d404c2c404dd5000c274050b201185980801a162020c2ac04c2ac04c2ac0400830a101001309d013754660b66eb0c2800400426404c28004004c26c04dd5032456600260d401b132323298009bae30a10130a20130a20130a20130a20130a20130a20130a20130a20130a201001985080984f009baa06198510080124446644b30015980098209853009853808014528c54cc284052401176e6f5f6f746865725f696e70757473203f2046616c73650014a085000a2b3001598009820985300985380800c528c54cc284052401186e6f5f6f746865725f6f757470757473203f2046616c73650014a085000a2b30015980099baf374c60d66530010019bac30a701003a5eb7bdb1810011112cc00400a200319800801cc2a80400a6530010018014dd59855009855809853809baa30aa0130ab0130a7013754615402006800888966002005100189919914c00401a61600200b32330010010052259800800c4cc2c004cdd81ba9004374c00697adef6c608994c004dd7185700800cdd5985780800cc2cc040092225980099b9000800389985a0099bb037520106e9801c0162b30013371e010007132598009842809859009baa00189985a8099bb03752012616c026166026ea800400a2004858008c966002b30010018a518a5042d00514c0103d87a800089841809985a809ba60014bd70216002329800800c022006800888966002005100189919914c00401a61780200b32330010010052259800800c4cc2f004cdd81ba9004375000697adef6c608994c004dd7185d00800cdd6985d80800cc2fc040092225980099b900080038998600099bb037520106ea001c0162b30013371e01000713259800984880985f009baa0018998608099bb03752012618402617e026ea800400a200485e008c96600261220200314c0103d87a8000898478099860809ba80014bd702178023370000e0051330c001337606ea400cdd400119803003000a1760242ec0430bd0100142ec048030dd7185a808009bad30b60100130b80100242d8051330b401337606ea400cdd300119803003000a15e0242bc0430b10100142bc048030dd71854808009bab30aa0100130ac0100242a80480190a7011ba6306b329800800cdd618538080152f5bded8c080088896600200510018cc00400e615402005329800800c00a6eacc2a804c2ac04c29c04dd5185500801a002222598008014400626466453001006985800802cc8cc00400401489660020031330b001337606ea4010dd3001a5eb7bdb1822653001375c615c020033756615e0200330b30100248896600266e4002000e2661680266ec0dd48041ba60070058acc004cdc7804001c4c966002610a026164026ea800626616a0266ec0dd4804985b009859809baa00100288012160023259800acc004006294629410b4014530103d87a800089841809985a809ba60014bd70216002329800800c022006800888966002005100189919914c00401a61780200b32330010010052259800800c4cc2f004cdd81ba9004375000697adef6c608994c004dd7185d00800cdd6985d80800cc2fc040092225980099b900080038998600099bb037520106ea001c0162b30013371e01000713259800984880985f009baa0018998608099bb03752012618402617e026ea800400a200485e008c96600261220200314c0103d87a8000898478099860809ba80014bd702178023370000e0051330c001337606ea400cdd400119803003000a1760242ec0430bd0100142ec048030dd7185a808009bad30b60100130b80100242d8051330b401337606ea400cdd300119803003000a15e0242bc0430b10100142bc048030dd71854808009bab30aa0100130ac0100242a80480190a7014528c54cc2840524011e69735f6163636f756e745f76616c75655f657175616c203f2046616c73650014a085000a2b3001323233001001375861500261520261520261520261520261520261520200a44b30010018a508acc004cdc79bae30a9010010038a51899801001185500800a14602429c046eb8c2980401a29462a661420292012d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085000a29410a00145282140028a504280046466446600400400244b30010018a5eb8410180008101800044cc8966002600a0051330a801374e66150020046eb0c2a404004cc2a004c2a404c2a8040052f5c11330a80130a901001330a801374e66150020046eb0c2a404c2a8040052f5c0851808c29c04004cc008008c2a0040050a5011bac30a5010073303c002003323322330020020012259800800c52f5c210180008101800044cc8966002600a0051330a801374e66150020046eb0c2a404004cc2a004c2a404c2a8040052f5c11330a80130a901001330a801374e66150020046eb0c2a404c2a8040052f5c0851808c29c04004cc008008c2a0040050a5011bac30a5010023303b002003184e809baa3305b3758614002002132026140020026136026ea81922b3001306700d8991919914c004c28c04c28c0400a6eb0c2880400a614602614602614602614602614602614602614602614602003375c61440200291114c004dd59853008024dd61853009853809853809853809853808024dd71853008014dd71853009853808014dd618530080424444464b300100184a80c4c966002615c0200513259800800c56600260f86154026ea8006264b300100184f80c4c96600200313259800800c28406264b300130b3010028cc00400e2b30010018acc004c1f8c2b804dd5000c4c9660020030a4018992cc004006264b300100185300c4c9660020030a7018992cc004c2e00400e3300100489982d000912cc00400a2664466446644b300159800982d1ba73233001001375861800261820200a44b30010018a5eb8226644b30013375e6186026180026ea8c30c04c31004c30004dd5001002c4cc30804008cc01001000626600800800285e808c30404004c308040050bf014528c54cc2e80524011f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a085c80a2b300159800982d1ba73233001001375861800261820200844b30010018a5eb8226644b30013375e6186026180026ea8008016266184020046600800800313300400400142f40461820200261840200285f80a29462a6617402921206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a085c80a2b300159800acc004cdd79ba630840133055304b3758617e0200c60a260946eb0c2fc04014dd300144cdd79ba6002374c608a01314a085c80a29462a66174029211a69735f76616c7565735f6d61746368696e67203f2046616c73650014a085c80a2b300159800991980080080c912cc00400629422b30013371e6eb8c30404004072294626600400461840200285d8090bf014528c54cc2e8052412d69735f68796472615f696e7465726e616c5f7472616e736665725f617574686f72697a6564203f2046616c73650014a085c80a2b3001980080ccdd318289842009bab308a0130bc0137546114026178026ea804e4466e1c008005080014528c54cc2e80524011d69735f696e74656e745f746f6b656e5f6275726e74203f2046616c73650014a085c80a29410b90145282172028a5042e40514a085c808c20804cc14cc120dd6185e80800982798249bac30bd01002306d01430bc0100230bc01001332232330010010122259800800c52f5c3018000810180008101800044cc8966002600c0051330be01374e6617c020046eb0c2fc04004cc2f804c2fc04c30004004cc2f804c2fc04c30004c300040052f5c1159800980280144cc2f804c2fc04004cc2f804dd39985f008011bac30bf0130c001001330be0130bf0130c00130c0010014bd7044cc2f804c2fc04004cc2f804c2fc04c30004004cc2f804dd39985f008011bac30bf0130c00130c0010014bd7021720242e404617a0200266004004617c0200285d808cc144028040cc144018040cc88c8cc004004064896600200314bd7081018000810180008101800044cc8966002600c0051330be01374e6617c020046eb0c2fc04004cc2f804c2fc04c30004004cc2f804c2fc04c30004c300040052f5c1159800980280144cc2f804c2fc04004cc2f804dd39985f008011bac30bf0130c001001330be0130bf0130c00130c0010014bd7044cc2f804c2fc04004cc2f804c2fc04c30004004cc2f804dd39985f008011bac30bf0130c00130c0010014bd7021720242e404617a0200266004004617c0200285d808cc140028040cc14001804226464b300100185600c2b006158030ac01899912cc00400615c03133060375600244b30010028980398600080444c8c9660020030b20185900c2c806164031332259800800c2d006168030b40189918031862808039bad00185a00a18a02375c002617c02004861808c2f004004c2fc040090bd0142b80615c030ae0142fc046eb8004c2e0040090bd01185b00800985c80801216e0285400a0e685400a16a0237560030a70185380c29c050b801185a80800a1660230b50100285280c2940614a030a50142d804616602002858808c2bc04dd5000c28c050ac01428c06146030a30185180a1680285100a0dc85100a1600230b10100142bc046162020050a00185000c2800614002859008c2bc040050ad011855809baa00184f00a1500284f00c2780613c0309e0142c00464b3001307a30aa013754003130ae0130ab01375400315330a90149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642a004615a02615c02615c026154026ea8c2b404c2b804c2a804dd5000c258050ab01185600800a154023232330010010032259800800c52f5c11332259800acc004cdd79858009856809baa30b00130b10130ad01375400400b1323300100132330010013756616402616602615e026ea8c2c804c2cc04c2bc04dd5002112cc004006297ae0899199119198008009bab30b4010042259800800c400e26466170026e9ccc2e004dd48029985c00985a808009985c00985b00800a5eb80cc00c00cc2e804008c2e0040050b6011bae30b0010013300300330b50100230b30100142c40444b30010018a508acc004cdc79bae30b201375861640200201514a313300200230b30100142b00485800a29410aa0144cc2bc04008cc010010006266008008002855008c2b804004c2bc040050ac01182d8018614202002613a026ea8cc16cdd618500080084c80985000800984d809baa0648acc004c0e803633001309b013754613c026136026ea817a4444b30010018801c4c966002007153309e0149012a6e6f7420656e6f756768206b65792d76616c756520706169727320746f206d617463682070726f6f667300168992cc004c1c0c28004dd500146600200d9800802cdd7185000800cdd7185080800cdd61852009850809baa002407130a501004985280801a00c8a9984f80a4930657870656374204d504644656c657465207b2070726f6f663a2064656c6574655f70726f6f66207d203d2070726f6f660016427804614602006850808c288040050a0014c26c04dd5032244530013002002985080801cdd5985080985100801cc2880400522223232329800985480985480985480985480800cc2a0040066eb8c2a00400922298009bae30ab0130ac0130ac01003982d9bae30ab0100399198008009bac30ac0100c2259800800c52f5c11332259800acc004cdd79857809856009baa30af0130b00130ac01375400400d1307d3259800983f1856009baa0018a40011375a616002615a026ea80050aa01192cc004c1f8c2b004dd5000c5300103d87a8000899198008009bab30b10130ae01375400444b30010018a6103d87a8000899192cc004c214040062b30013084010018984080998598098588080125eb82298103d87a800042b80513300400430b50100342b8046eb8c2bc04004c2c8040050b00121540232330010013756616002616202615a026ea8c2c004c2c404c2b404dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062610002661640261600200497ae08a60103d87a800042b40513300400430b40100342b4046eb8c2b804004c2c4040050af0145282152028998570080119802002000c4cc0100100050a901185680800985700800a156029bac30ab0130ac010079bae30ab0100648888966002007094018992cc004c2c804012264b3001307e30ae01375400313259800800c566002610402615e026ea8006264b300100185300c4c9660020030a70185380c29c0614e0313259800985b80801c4c96600200309d018992cc004c2e40400a264b300130850130b501375400313259800800c660020031323259800acc004cdd79ba63301f375660dc6172026ea820804cc2ec04dd4808a5eb80c2f004c2f40400a29462a6616e029211769735f76616c75655f6d696e746564203f2046616c73650014a085b00a2b30015980099198008009bac306e30ba0137541060244b30010018a508acc004cdc79bae30be0100100f8a51899801001185f80800a1700242f00514a315330b70149011f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085b00a2b300159800984580985c009baa01a8992cc0056600266e3cc08400402229462a6617002920134636f6d707574655f747265655f68617368287472656529203d3d20696e7075745f6d65726b6c655f726f6f74203f2046616c73650014a085b80a2b30015980099baf374c604e0026e9800a29462a66170029212f6b65795f76616c756573203d3d206f75747075745f6d65726b6c655f7265636f72645f6c697374203f2046616c73650014a085b80a2b30013371e6eb8c2f404c2e804dd5002245200000000000000000000000000000000000000000000000000000000000000000008a518a9985c00a494d6f75747075745f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085b80a29410b7014528216e0230bc0130b901375403513371e60c26eb8c2f004c2e404dd5001cc004c18401e00337586178026172026ea806901b216c028a518a9985b80a4811769735f747265655f75706461746564203f2046616c73650014a085b00a29410b6014528216c0237566176020033001323300100100d2259800800c52f5c1133225980099baf30be0130bb0137540040251330bd0100233004004001899802002000a1700230bc0100130bd0100142e8054bd708101a0008101a000488c9660026112026172026ea800626644b30010018cc00400626617c026e98cc2f804cdd81ba937660026ea4dd99ba60023756617e020086617c026e98cc154dd5984500802198111bab308a0130bc01375400a6617c026ea40512f5c097ae085980a0f685980c2cc06166030b301430405300137566110026174026ea800e02501a4108617a026174026ea80062a66170029212f65787065637420496e6c696e65446174756d286f75747075745f646174756d29203d206f75747075742e646174756d001642dc04610c026172026ea800902b42b40502a42b40615a030ad0185680a1780230b90130b60137540030a00142cc04610402616a026ea800613c0285b008c2dc040050b5011919800800804912cc004006297ae0899912cc0056600266ebcc2e804c2dc04dd5001008c4c22004c966002611202616e026ea80062900044dd6985d80985c009baa00142d40464b300130890130b701375400314c0103d87a8000899198008009bab30bc0130b901375400444b30010018a6103d87a8000899192cc004c240040062b3001308f0100189846009985f00985e0080125eb82298103d87a800042e40513300400430c00100342e4046eb8c2e804004c2f4040050bb01216a02323300100137566176026178026170026ea800c896600200314c103d87a8000899192cc004cdc880a000c56600266e3c05000626116026617a0261760200497ae08a60103d87a800042e00513300400430bf0100342e0046eb8c2e404004c2f0040050ba01452821680289985c8080119802002000c4cc0100100050b401185c00800985c80800a16c0285400a16802375c00285b808c2d0040050b2011858009baa00185280a15a0285280c2940614a030a50142d404616402615e026ea80062a6615a0292014665787065637420496e6c696e65446174756d28747265655f726f6f7429203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642b00460f6615c026ea8c1f0c2b804dd5000c254050af01185800801a15c020c2a004004c29c04c29c04c29c04c29c04004c28804dd5198301bac30a50100109e01233001309b013754613c026136026ea817a4444b30010018801c4c966002007153309e01491256e6f7420656e6f756768206b65792d76616c75657320746f206d617463682070726f6f667300168992cc004c1ccc28004dd500146600200d9800802cdd7185000800cdd7185080800cdd61852009850809baa002407930a501004985280801a00c8a9984f80a4930657870656374204d5046496e73657274207b2070726f6f663a20696e736572745f70726f6f66207d203d2070726f6f660016427804614602006850808c288040050a0014c26c04dd5032244530013002002985080801cdd5985080985100801cc288040066eb0c2840400522222332298009854809854808014dd61854008014c2a404c2a404c2a404c2a4040066eb8c2a004005222298009bab30ac010049bac30ac0130ad0130ad0130ad0130ad010049856808014dd71856008012444466446465300137566168020033756616802616a0200332330010010102259800800c52f5c11332259800acc004cdd7985c00985a809baa30b80130b90130b501375400400f13086013259800984380985a809baa0018a40011375a617202616c026ea80050b301192cc004c21c04c2d404dd5000c530103d87a8000899198008009bab30ba0130b701375400444b30010018a6103d87a8000899192cc004c238040062b3001308d0100189845009985e00985d0080125eb82298103d87a800042dc0513300400430be0100342dc046eb8c2e004004c2ec040050b90121660232330010013756617202617402616c026ea8c2e404c2e804c2d804dd5001912cc004006298103d87a8000899192cc004cdc8806800c56600266e3c0340062611202661760261720200497ae08a60103d87a800042d80513300400430bd0100342d8046eb8c2dc04004c2e8040050b801452821640289985b8080119802002000c4cc0100100050b201185b00800985b80800a1680248896600200309b018992cc004c2e40400a264b300130850130b501375400313259800800c6600200313259800800c28406264b300130bd010028992cc004c22404c2e404dd5000c4c96600200319800800c566002b30013375e6e98048dd3004c528c54cc2e40524011669735f76616c75655f6275726e74203f2046616c73650014a085c00a2b3001598009919800800809112cc00400629422b30013371e6eb8c30004004056294626600400461820200285d0090be014528c54cc2e4052411f69735f6f7065726174696f6e5f6b65795f7369676e6564203f2046616c73650014a085c00a2b300159800984680985d009baa01c8992cc0056600266e3cdd7185f80985e009baa006489200000000000000000000000000000000000000000000000000000000000000000008a518a9985d00a4950696e7075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203d3d206e756c6c5f68617368203f2046616c73650014a085c80a2b30015980099b8f3023001375c617e026178026ea800a29462a66174029215f636f6d707574655f747265655f68617368287472656529203d3d206f75747075745f6465785f6163636f756e745f62616c616e63655f646174756d2e6163636f756e745f62616c616e63655f6d65726b6c655f726f6f74203f2046616c73650014a085c80a2b30013375e6e98c0a4004dd31919800800806112cc004006297adef6c60899191980080099802002186200801912cc0040062661860200697adef6c608992cc004cdd799912cc004cdc8001000c530103d87980008acc004cdc7801000c530103d87a80008a6103d87b8000430404860808dca1bae30c10100437286eb8c3040400530103d87980008998620080200144cc31004004cc00c00cc318040090bf01186200800a1840230c10100142fc0514a315330ba014913c657874726163745f6b65795f76616c756573287472656529203d3d20736f727465645f73657269616c697365645f696e70757473203f2046616c73650014a085c80a29410b901452821720230be0130bb01375403913371e60c66eb8c2f804c2ec04dd5000cc004c18cdd7185f00985d809baa0058054dd6185f00985d809baa01c407485c00a29462a661720292011769735f747265655f75706461746564203f2046616c73650014a085c00a29410b801452821700285300a05c85300c2980614c030a601430004617a026174026ea80061480285b808c21804c2e404dd5000c288050ba01185d80800a1720232330010010122259800800c52f5c11332259800acc004cdd7985f00985d809baa00200d8984600992cc004c23404c2ec04dd5000c5200089bad30bf0130bc01375400285c808c966002611a026176026ea8006298103d87a8000899198008009bab30c00130bd01375400444b30010018a6103d87a8000899192cc004c250040062b30013093010018984800998610098600080125eb82298103d87a800042f40513300400430c40100342f4046eb8c2f804004c304040050bf0121720232330010013756617e026180026178026ea800c896600200314c103d87a8000899192cc004cdc8809800c56600266e3c04c0062611e026618202617e0200497ae08a60103d87a800042f00513300400430c30100342f0046eb8c2f404004c300040050be01452821700289985e8080119802002000c4cc0100100050b801185e00800985e80800a1740284f80a05484f80c27c0613e0309f0142f004617202616c026ea80062a66168029214865787065637420496e6c696e65446174756d28696e7075745f646174756d29203d206465785f6163636f756e745f62616c616e63655f696e7075742e6f75747075742e646174756d001642cc04610402616a026ea8c20c04c2d404dd5000c270050b601185b80800a16a024c004c8c8cc004004040896600200314bd7044cc8966002600a0051330b70100233004004001899802002000a1640230b60100130b70100142d00446466ebcc2d404c2c804dd5185a80985b009859009baa0020013064375c6168020094bd70901a0008101a000488c9660026104026164026ea800626644b30010018cc00400626616e026e98cc2dc04cdd81ba937660026ea4dd99ba600237566170020086616e026e98cc138dd598418080218251980d9bab30830130b5013754610602616a026ea8014cc2dc04dd480325eb812f5c109b0141d109b0184d80c26c061360285d00a60026eacc20404c2cc04dd51840809859809baa003802404d03b185b009859809baa0018a9985880a4813465787065637420496e6c696e65446174756d28696e7075745f646174756d29203d20696e7075742e6f75747075742e646174756d001642c00460fe6164026ea8c20004c2c804dd50012048375c6164026166026166020046162026162026162026162020046160020041853808011851809baa330613758614c0200413e0221300242600484c009098012130022980091000c0069101004008446466002002601400644b30010018a5eb7bdb18226644b300132330010010062259800800c528456600266e3cdd71852008008024528c4cc008008c2940400509e012144028cc004cc15801800a0032229800800c01600700240c882aa200284e008dd718500080099801001185080800a13c023001001223300122225980099b87002480822009132598009837984e809baa0018cc00401e4400533013005489200000000000000000000000000000000000000000000000000000000000000000008024c12800e004803a26464b30013371000200b153309e0149012e696e76616c696420747265652c206368696c6472656e206d75737420626520736f7274656420627920696e64657800168992cc004c1ccc28004dd5000c56600266e1c01800a3300100a910014cc058022600201522001985080801ccdc5002cc00528d20028032f2480526eacc29004c28404dd5000cc13401a00a80523300100a910014cc058021220120000000000000000000000000000000000000000000000000000000000000000000803cc13401a00a805109e01454cc27c052412a65787065637420536f6d65287461696c5f6e6f64657329203d206c6973742e7461696c286e6f646573290016427804b30010068a6103d87a80008983819851009ba630a4010064bd702142024274046eb4c27804004c8cdd81851008009851009851808009bac30a101309e01375400284d8096600200714c103d87a8000898369984f80991ba7330a001309d01001330a001309e010014bd70185000801a5eb8109e0121340222598009836984d009baa0028991919826800992cc0040062a661380292012e696e76616c6964206368696c64206861736865732c206d7573742062652061206e6f6e2d656d707479206c69737400168acc004c2880400626eb8c2840400626601000297ae0427c0484f808c04e600200d22002a5eb826eacc28004c2840400a90004cdc5001800a00c375c613e020026136026ea800a264646644b3001980099b8f37280040034a14a284e00a2a6613a0266e59241056b65793a20003732660406ea4009220100153309d013372c920106706174683a20003732660406ea4005220100153309d014912d696e76616c696420747265652c2070617468206973206e6f74207468652068617368206f6620746865206b65790016899192cc004cdc7800803c4cc144cc0dc00c008dca1bae30a40130a5010058a9984f8099b964910e706174685f6e6962626c65733a20003732660446ea4005220100153309f013372c9201107072656669785f6e6962626c65733a20003732660446ea401d220100153309f0149128696e76616c696420747265652c2070726566697820646f6573206e6f74206d61746368207061746800164278053001002a400100140dc6e3401509c011bae30a001001375c6140020046140020026136026ea800909801180100109112cc004c17400a264b300100180344c966002003159800984880801466002003003803a00c803a11c02803c01e00f007424804611e02002846808c22c04dd5027456600260b800513259800800c01a264b30010018acc004c2440400a33001001801c01d006401d08e01401e00f007803a12402308f010014234046116026ea813a2b3001305a0028992cc00400600d13259800800c56600261220200519800800c00e00e826200e84700a00f007803c01d09201184780800a11a02308b01375409d159800982b80145660026116026ea813a00300542300515980099b874802000a264b300100180344c966002003159800984880801466002003003803a00a803a11c02803c01e00f007424804611e02002846808c22c04dd50274566002605400513259800800c01a264b30010018acc004c2440400a33001001801c01d005401d08e01401e00f007803a12402308f010014234046116026ea813a00a84400908801211002422004844009088010888c96600260ba00313259800800c00e264b30010018024012264b300130920100389981a000912cc00400a01113259800800c6600200313002309501003804206c804402201100842580461260200484880a00a847808dd6000c012008849008c23c0400508d011845809baa0048acc004c170006264b3001001801c4c96600200300480240120091332259800800c01a264b3001001803c01e00f007899912cc00400601313259800800c02a01513259800984c00801c4cc0e8004896600200500e8992cc0040063300100189801184d80801c03903c403a01d00e807213802309901002425c0500b4254046eb000601500a426004612a02002849808dd7000984a00801212a023092010014240046eb8004c2440400909201184780800a11a02308b013754009159800982d000c4c9660020030038992cc0040060090048992cc004c2480400e26606800244b300100280444c96600200319800800c4c008c2540400e01081b2011008804402109601184980801212202802a11e023758003004802212402308f010014234046116026ea8012004844009088012110023089013754007001800c00600284600856600209319800911192cc004c170006264b3001001801c4c96600200300480244c96600261220200713303300122598008014022264b30010018cc0040062600461280200700840d5008804402201084a808c2480400909001401508e011bac001802401109101184700800a11802308a013754009159800982d800c4c9660020030038992cc004006009004802401226644b300100180344c966002003007803c4c9660026128020071330360012259800801402e264b30010018cc00400626004612e0200700b40e100b805c02e01684c008c25404009093014021091011bac001803c01d09401184880800a11e02375c002612002004848808c2380400508c011845009baa0048acc004c164006264b3001001801c4c96600200300480244cc89660020030068992cc00400600f007803c01e264b300130940100389981b002112cc00400a01713259800800c6600200313002309701003805a070805c02e01700b426004612a0200484980a010848808dd7000a12802309101001423c046eb0004c2400400a009004424404611c02002846008c22804dd5002400908701210e02421c046110026ea800e3300123259800982d1843809baa0018992cc004cdc39bad308c01308d01308d010014800626eb8c230040062a6610e0292115657870656374207175616e74697479203d3d202d3100164218046eb0c22c04c22004dd5000c54cc2180524019d65787065637420536f6d652828706f6c6963795f69642c205f61737365745f6e616d652c207175616e746974792929203d0a202020206c6973742e66696e64280a2020202020206d696e742c0a202020202020666e28656e74727929207b0a20202020202020206c657420285f2c205f2c2071747929203d20656e7472790a2020202020202020717479203c20300a2020202020207d2c0a20202020290016421404646600200200444b30010018a60103d87a80008992cc004cdc41bad308d01308e01308e0100148002260b466118026e9c0052f5c1133003003308e01002421c046eb0c2300400508a0148896600260b66110026ea800e264b300100180144c966002003003801c00e0071332259800800c016264b3001001803401a00d006899912cc00400601113259800800c026013009804c4cc896600200300b8992cc00400601900c806403226644b300100180744c96600200300f807c03e01f1332259800800c046264b3001001809404a025012899912cc00400602913259800800c05602b01580ac4cc89660020030178992cc00400603101880c406226644b300100180d44c96600200313259800800c072264b300100180ec07603b1332259800800c07e264b300100181040820411332259800800c08a264b3001001811c08e26644b3001001812c4c96600200313259800985780800c56600266e25200430ae01001813c4cc89660020030298992cc00400605502a81544cc896600200302c8992cc00400605b02d816c4cc896600200302f8992cc00400606103081844cc89660020030328992cc004006067033819c0ce26644b300100181ac4c96600200303681b40da264b300130c3010038cc0040762660ca02844b300100281d44c96600200303a81d40ea075132300330c701004375c002863808c310040090c20140dd07e40dd0c0011bad00181b21860230c00100142f8046eb8004c2fc040090c001185e80800a17602375a00261780200503042f40461740200285c008dd6800985c8080140b50ba01185b80800a16a02375a002616c0200502a42dc04616802002859008c20004c2b804004c2cc0400d0ac01409d0b0011baa001813409a04d02642cc04616002002857008dd6000985780801408e046858008c2b4040050ab011bad00130ac01002810215a0230aa0100142a0046eb4004c2a40400a03a855008c29c040050a501185380801406e03701b80da1500230a501001428c046eb8004c290040090a501185100800a14002375c002614202004851008c27c0400509d011bae001309e01002427c0461380200284d008dd7000984d80801213802309901001425c046eb8004c2600400909901184b00800a12802375c002612a0200484b008c24c04005091011bae001309201002424c04612002002847008dd7000984780801212002308d01001422c046112026ea800e00284300a444464b3001305d308a01375400313259800800c56600260bc6116026ea8006264b300100184400c4c9660020030890184480c2240626644b300100184580c4c96600200308c01899912cc00400611c0313259800800c56600261300200513303a0032259800801456600260d0612a026ea800e264b300100184900c4c9660020030930184980c24c06126031332259800800c25406264b300100184b00c2580612c0313259800985000801c4cc27804dd40071984f009ba600b3309e019800acc00566002646600200202c44b30010018a508acc004cdd7985080984f009baa30a10100100b8a51899801001185100800a13602427c0514a3153309a014911869735f7574786f5f636f6e73756d6564203f2046616c73650014a084c80a2b3001329800800c05602880088896600200514a3159800800c54cc27405240120657870656374205b7369672c202e2e726573745f736967735d203d207369677300168acc00660026eb8c2880400a033375c614402002b95456600330010039851808014c28c040050034528c54cc27405241347665726966795f7369676e61747572657328726573745f6b6579732c206d73672c20726573745f7369677329203f2046616c73650014a084e00a294109c0121400242800514a3153309a014901187369676e6174757265735f636865636b203f2046616c73650014a084c80a2941099015300103d87a8000a60103d879800042640497ae084b80a13a02375a00309601428004613a0200284d808dd7000984e00801213a02309a01001426004612c026ea800e1220284980a26464b300100184980c24c0626644b300100184a80c25406264b300100384b00c4c9660020030970184b80c25c0612e031332259800800c26406264b300100184d00c268061340309a018992cc004c2900400e2b300100684d80c4c96600200309c0184e00c2700626644b300100184f00c4c96600200309f0184f80c27c06264b300130a90100389808185480808c280050a6011bad00184f80a1520230a6010014290046eb4004c2940401e13802853008c28c040190a101426c050a1011bae00142900461420200284f808dd7000985000802214202309e010034270046eb000612a0309501427c046eb0004c2600400a1260309301427404612c0200261320200484b80a11e0284a80a11e0308f0184780c23c0509901184b00800a128023756002612a0200508c0184600c2300509601184980800a12202375a00261240200508901424c04612002002847008c23004dd5000c21c0508901421c0610e030870184380a12202308e01308b0137540031533089014913b65787065637420536f6d65287369676e65645f6461746129203d2063626f722e646573657269616c697365287072696365735f6d65737361676529001642200460140092225980099b880014800229000456600260b600314800a264b3001305c3370c0049002466002009300100399b830024801100444c0066002009300100399b83303300248011004210e0237040048430090860148c96600260b40031305630880137546116026110026ea800a2b300130590018982b1844009baa308b0130880137540051305630880137546116026110026ea800908501210a0230860137540032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b010019184500984580984580984580984580984580984580984580984580984580984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116026116026116026116026116026116026116026116026116026116020032308a01308b01308b01308b010019184500984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116020032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b010019184500984580984580984580984580984580984580984580984580984580984580800c8c22804c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c04c22c0400646114026116026116026116026116026116026116026116026116026116026116026116026116020032308a01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b01308b010019112cc004c16cc22004dd5001c4c9660020030028992cc004006007003801c4cc89660020030058992cc00400600d00680344c966002612602007008803a12002375a003006424c04612002002847008dd6800984780801400d09001184680800a116023089013754007001421805308501375409291111111111111111111194c00488c8cc00400400c8966002003148002264664466446600400400244b30010018801c4c8c96600260f0614a026ea800626466e00cc014014c2ac04010cdc199b82375a614e020066eb4c2a804004cc0352014375a6154026156020026eb0c2a404c29804dd5000c54cc290052415865787065637420536f6d65282870726963652c207363616c652929203d0a2020202020202020707269636573207c3e2070616972732e6765745f66697273742828706f6c6963795f69642c2061737365745f6e616d6529290016428c0464646600200201644b30010018a60103d87a80008992cc004cdd79ba700430a8010018983c9985580985480800a5eb82266006006615a02004853008c2ac040050a90119853809ba9005330a70130a4010014bd70185380800a14a0237566144020066eb8c27c04004cc00c00cc29004008c288040050a00148896600266ebcc28404c27804dd5000982880144c96600200319800800c4cdd7980a800802420c0505e420c06106030830184180a1480232598009837184f009baa0018985100984f809baa0018a9984e80a492c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016427004614202614402614402613c026ea8006294109b0148896600266ebcc28404c27804dd51836184f009baa00130510028992cc00400633001001899baf301500100484100a0bc84100c20806104030820142900464b3001306e309e013754003130a201309f013754003153309d0149013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016427004614202614402614402613c026ea8c28404c28804c27804dd5000c52821360248896600260e000b13232329800985280985280985280985280985280985280985280985280985280800c88c8cc00400400c896600200314a31598009801985400800c4cc008008c2a40400629410a201214c029852009850809baa0649bac30a401003985280801244444b3001307730a50137540c513298009919800800802112cc004006297ae110180008101800044cc8966002b30013375e615c026156026ea8c1e4c2ac04dd5001002c4c96600200319800800c4cdd7800804c23c0506b423c0611e0308f0184780a162023259800983d9855809baa00189857809856009baa0018a9985500a493265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642a404615c02615e02615e026156026ea8c2b804c2bc04c2ac04dd50014528215002899856809ba7330ad010023758615c020026615a02615c02615e0200297ae08998568098570080099856809ba7330ad010023758615c02615e0200297ae042a00461580200266004004615a0200285500a6644b3001307b0018983c99855809856009854809baa006330ab01375200497ae08acc004c1e8006260e866156026158026152026ea8018cc2ac04dd480125eb82266e952004330ab0130ac0130a901375400c66156026ea40092f5c08530090a6011bae30aa0130ab0100630a6013754009305a375c61540200c9112cc00566002660106eb0c2b404c2b80400ca600266ebcc2b804c2ac04dd5183c9855809baa001005a50a5142a00514a315330a801491226e6f5f6f746865725f6f6c645f7363726970745f696e70757473203f2046616c73650014a085380a2b3001598009980400314c004cdd79857009855809baa307930ab0137540020054a14a285400a29462a661500292011c6e6f5f6e65775f7363726970745f696e70757473203f2046616c73650014a085380a2b30015980099baf374c60e460726eb0c2b40400cdd31839181c1bac30ad0132330010013758615c0200c44b30010018a5eb850180008101800044cc8966002b30013375e616202615c026ea8008016264b30010018cc004006266ebc00401e126028372126030930184980c24c050b401192cc004c1f8c2b804dd5000c4c2c804c2bc04dd5000c54cc2b40524012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d001642b004616202616402616402615c026ea800a29410ab0144cc2c004dd399858008011bac30b101001330b00130b10130b2010014bd7044cc2c004c2c404004cc2c004dd399858008011bac30b10130b2010014bd7021560230af010013300200230b00100142b40514a315330a8014911a69735f76616c75655f707265736572766564203f2046616c73650014a085380a2b30013232330010013758615e0261600261600261600261600261600261600200e44b30010018a508acc004cdc79bae30b0010010038a51899801001185880800a1540242b8046eb8c2b40402a29462a661500292011569735f617574686f72697a6564203f2046616c73650014a085380a29410a7014528214e028a50429c043059375c615202614c026ea818a2a66148029212b65787065637420536372697074286f6c645f7363726970745f6861736829203d2063726564656e7469616c0016428c0430a0013754660bc6eb0c28c0400427004c28c04004c27804dd5033c56600260de00b1332298009852008014dd71851808014c290040066eb0c28c04005222298009854008024dd61853808024c2a00400a6148026ea8cc188dd618538080105000a44453001375661560200930ab0130ac010049856009856008014dd61855808014c2b004c2b004c2b004c2b004c2b004c2b004c2b004c2b004c2b0040066eb8c2ac0400522222298009bac30b10130b20130b20130b20130b2010049bae30b1010029bae30b10130b20130b2010029814182f9bab30b10100448888c96600200308d018992cc004c2e00400a264b30010018acc004c21c04c2d004dd5000c4c96600200309b018992cc0040061380309c0184e00c2700626644b300100184f00c4c96600200313259800800c28006264b300100185080c4c9660026182020071980080244cc18c004896600200513259800800c27006264b300130c5010028992cc00400613e031325980098638080144c96600200319800800c4c96600200319800800c4c8cc8a60026198026198026198026198020053371e02e6eb8c32c0400a6644646600200205044b30010018a5eb841018000810180008101800044cc8966002600c0051330d001374e661a0020046eb0c34404004cc34004c34404c34804004cc34004c34404c34804c348040052f5c1159800980280144cc34004c34404004cc34004dd399868008011bac30d10130d201001330d00130d10130d20130d2010014bd7044cc34004c34404004cc34004c34404c34804004cc34004dd399868008011bac30d10130d20130d2010014bd70219602432c04619e020026600400461a002002866808cc18c03c064cc0ac0040666644646600200204044b30010018a5eb841018000810180008101800044cc8966002600c0051330d001374e661a0020046eb0c34404004cc34004c34404c34804004cc34004c34404c34804c348040052f5c1159800980280144cc34004c34404004cc34004dd399868008011bac30d10130d201001330d00130d10130d20130d2010014bd7044cc34004c34404004cc34004c34404c34804004cc34004dd399868008011bac30d10130d20130d2010014bd70219602432c04619e020026600400461a002002866808cc18803c064cc0b0004065222298009868009868009868008024c33c0401261a00200530d001001983f80ea44445300130d50130d501005cc0040c205d375861a80200b02c4125306f374e64660020026eb0c35404c35804010896600200314bd7044cc896600266ebcc36004c35404dd5186c00986c80986a809baa00200589986b8080119802002000c4cc0100100050d201186b00800986b80800a1a80298379ba73233001001375861aa0261ac0200644b30010018a5eb8226644b30013375e61b00261aa026ea80080162661ae020046600800800313300400400143480461ac0200261ae0200286a00a613202660d46530010019bac30d501003a5eb7bdb1810011112cc00400a200319800801cc3600400a6530010018014dd5986c00986c80986a809baa30d8010034004444b30010028800c4c8cc8a600200d30de010059919800800802912cc0040062661bc0266ec0dd48021ba60034bd6f7b63044ca60026eb8c370040066eacc3740400661c2020049112cc004cdc8004001c4cc38804cdd81ba9008374c00e00b15980099b8f0080038992cc004c2cc04c38004dd5000c4cc38c04cdd81ba900930e40130e1013754002005100243780464b300159800800c528c52821c4028a6103d87a8000898588099871809ba60014bd7021bc02329800800c022006800888966002005100189919914c00401a61d40200b32330010010052259800800c4cc3a804cdd81ba9004375000697adef6c608994c004dd7187400800cdd6987480800cc3b4040092225980099b900080038998770099bb037520106ea001c0162b30013371e01000713259800985f809876009baa0018998778099bb0375201261e00261da026ea800400a2004875008c966002617e0200314c0103d87a80008985e8099877809ba80014bd7021d4023370000e0051330ee01337606ea400cdd400119803003000a1d20243a40430eb0100143a4048030dd71871808009bad30e40100130e6010024390051330e201337606ea400cdd300119803003000a1ba0243740430df010014374048030dd7186b808009bab30d80100130da0100243600480190d5011833194c0040066eb0c3540401297adef6c604004444b30010028800c6600200730d801002994c004006005375661b00261b20261aa026ea8c36004c36404c35404dd5186c00801a002222598008014400626466453001006986f00802cc8cc00400401489660020031330de01337606ea4010dd3001a5eb7bdb1822653001375c61b802003375661ba0200330e10100248896600266e4002000e2661c40266ec0dd48041ba60070058acc004cdc7804001c4c96600261660261c0026ea80062661c60266ec0dd48049872009870809baa001002880121bc023259800acc004006294629410e2014530103d87a8000898588099871809ba60014bd7021bc02329800800c022006800888966002005100189919914c00401a61d40200b32330010010052259800800c4cc3a804cdd81ba9004375000697adef6c608994c004dd7187400800cdd6987480800cc3b4040092225980099b900080038998770099bb037520106ea001c0162b30013371e01000713259800985f809876009baa0018998778099bb0375201261e00261da026ea800400a2004875008c966002617e0200314c0103d87a80008985e8099877809ba80014bd7021d4023370000e0051330ee01337606ea400cdd400119803003000a1d20243a40430eb0100143a4048030dd71871808009bad30e40100130e6010024390051330e201337606ea400cdd300119803003000a1ba0243740430df010014374048030dd7186b808009bab30d80100130da0100243600480190d501244445300130da010059bad30d901005986d0080256600266ebcdd3184f0099837994c0040066eb0c3680403697adef6c604004444b30010028800c6600200730dd01002994c004006005375661ba0261bc0261b4026ea8c37404c37804c36804dd5186e80801a002222598008014400626466453001006987180802cc8cc00400401489660020031330e301337606ea4010dd3001a5eb7bdb1822653001375c61c202003375661c40200330e60100248896600266e4002000e2661ce0266ec0dd48041ba60070058acc004cdc7804001c4c96600261700261ca026ea80062661d00266ec0dd48049874809873009baa001002880121c6023259800acc004006294629410e7014530103d87a80008985b0099874009ba60014bd7021c602329800800c022006800888966002005100189919914c00401a61de0200b32330010010052259800800c4cc3bc04cdd81ba9004375000697adef6c608994c004dd7187680800cdd6987700800cc3c8040092225980099b900080038998798099bb037520106ea001c0162b30013371e010007132598009862009878809baa00189987a0099bb0375201261ea0261e4026ea800400a2004877808c96600261880200314c0103d87a800089861009987a009ba80014bd7021de023370000e0051330f301337606ea400cdd400119803003000a1dc0243b80430f00100143b8048030dd71874008009bad30e90100130eb0100243a4051330e701337606ea400cdd300119803003000a1c40243880430e4010014388048030dd7186e008009bab30dd0100130df0100243740480190da011835994c0040066eb0c3680403297adef6c604004444b30010028800c6600200730dd01002994c004006005375661ba0261bc0261b4026ea8c3740400d0011112cc00400a2003132332298008034c38c04016646600200200a44b30010018998718099bb037520086e9800d2f5bded8c113298009bae30e1010019bab30e2010019873008012444b3001337200100071330e701337606ea4020dd3003802c56600266e3c02000e264b300130b80130e50137540031330e801337606ea4024c3a404c39804dd5000801440090e301192cc0056600200314a314a087380a298103d87a80008985b0099874009ba60014bd7021c602329800800c022006800888966002005100189919914c00401a61de0200b32330010010052259800800c4cc3bc04cdd81ba9004375000697adef6c608994c004dd7187680800cdd6987700800cc3c8040092225980099b900080038998798099bb037520106ea001c0162b30013371e010007132598009862009878809baa00189987a0099bb0375201261ea0261e4026ea800400a2004877808c96600261880200314c0103d87a800089861009987a009ba80014bd7021de023370000e0051330f301337606ea400cdd400119803003000a1dc0243b80430f00100143b8048030dd71874008009bad30e90100130eb0100243a4051330e701337606ea400cdd300119803003000a1c40243880430e4010014388048030dd7186e008009bab30dd0100130df0100243740480190da011ba6001899baf374c0026e98c27804c17c06a29410d30124445300130de010049bad30dd01004985580986c809baa30dd0130de010029981fcc004c18c07a05503241886eacc37404009222298009bad30e1010049bae30e10130e201004acc004c2c00401e2003159800985800803c4006266e0ccdc10008039bad30e10100c436c0486d80a6ecc09522225330e0013372c9201096d70665f6b65793a20003732660c66ea4005220100159800acc00406629462a661c00292011769735f696e74656e745f76616c6964203f2046616c73650014a086f80a2b3001598008034528c54cc3800524011a69735f7072696365735f7665726966696564203f2046616c73650014a086f80a2b300159800807c528c54cc3800524011f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a086f80a2b3001598008074528c54cc380052401206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a086f80a2b300159800804c528c54cc3800524012169735f76616c75655f7472616e736665725f636f7272656374203f2046616c73650014a086f80a2b300159800acc0056600266e1cdd6982b9871009baa01e3370001600514a315330e0014911f69735f746f74616c5f7368617265735f636f7272656374203f2046616c73650014a086f80a2b30015980099b87375a60ac61c4026ea80796600266ebc0a4056266e0001c00a200e86f80a29462a661c00292012269735f6f70657261746f725f7368617265735f636f7272656374203f2046616c73650014a086f80a2b30015980099b87375a60aa61c4026ea8078cdc0002002c528c54cc380052412269735f746f74616c5f6465706f73697465645f636f7272656374203f2046616c73650014a086f80a2b30015980099b8f375c60a861c4026ea8078c966002616a02003133225330e3013372c9210b6e65775f76616c75653a20003732660cc6ea400522010019800984680803401200300241886eb0c39804c38c04dd501d1bb330b301330e5013750006661ca026ea00192f5c1159800985a00800c4c8c8cc896600261720261cc026ea800a264b30010018cc00400633001309001009803c00a0093766617002661d4026ea0cdc01bad30eb0130e8013754002010661d4026ea0cdc01bad30b60130e801375400201697ae041910c90141410c90186480c3240619202876808c3a804c39c04dd5001431c050e40118328009bac30e80130e901002375c61ce0200261c6026ea80ea2a661c2029211e496e76616c6964204d504620616374696f6e20666f72206465706f7369740016438004870008c38404dd501cc528c54cc3800524011e69735f6d65726b6c655f726f6f745f636f7272656374203f2046616c73650014a086f80a2b30015980099b8f375c61ca0261c4026ea8078dd71872809871009baa01f8acc004cdc79bae30b00130e201375403c6eb8c2c004c38804dd500fc56600266e3cdd71857809871009baa01e375c615e0261c4026ea807e2b30013371e6eb8c14cc38804dd500f1bae305330e201375403f15980099b8f375c612e0261c4026ea8078dd7184b809871009baa01f8acc004cdc79bae305230e201375403c6eb8c148c38804dd500fc56600266e3cdd718289871009baa01e375c60a261c4026ea807e2b30013371e6eb8c140c38804dd500f1bae305030e201375403f15980099baf30960130e201375403c612c0261c4026ea807e2b30013370e6eb4c13cc38804dd500f1bad304f30e201375403f15980099b87375a609c61c4026ea8078dd698271871009baa01f8acc004cdd798269871009baa01e304d30e201375403f159800acc004c2cc04c38404dd518261871009baa01e89859809870809baa304c30e201375403f198009859809870809baa304c30e201375403f4a14a286f8090df0144cdc39bad304b30e201375403c6eb4c12cc38804dd500fc52821be028a50437c0514a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be028a518a9987000a492169735f6f746865725f6669656c64735f756e6368616e676564203f2046616c73650014a086f80a29410df01452821be028a50437c0514a086f80a29462a661c00292011f69735f6f7261636c655f646174756d5f75706461746564203f2046616c73650014a086f80a2b300132330010010352259800800c528456600266e3cdd718738080081bc528c4cc008008c3a0040050e10121ca028a518a9987000a491169735f7369676e6564203f2046616c73650014a086f80a29410df01452821be028a50437c0514a086f80a29410df01452821be0200c32804c32804c32804004c24404cc32004c324040052f5c0619202618a026ea800a1480281f2148030a40185200c290050ca01192cc004c25004c31004dd5000c4c32004c31404dd5000c54cc30c0524012c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016430804618e026190026190026188026ea800a1440281ea144030a20185100c288050c901192cc004c24c04c30c04dd5000c4c31c04c31004dd5000c54cc3080524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016430404618c02618e02618e026186026ea8c31804c31c04c30c04dd5001c280050c401186280800a1860232330010010172259800800c52f5c11332259800991980080099198008009bab30ca0130cb0130c701375400844b30010018a5eb82264664464660020026eacc330040108966002003100389919868009ba7330d001375200a661a002619a02002661a002619c0200297ae03300300330d20100230d0010014338046eb8c32004004cc00c00cc33404008c32c040050c901112cc00400629422b30013371e6eb8c32804dd61865008008084528c4cc008008c32c040050c4012190028998638080119802002000c4cc0100100050c201186300800986380800a1880284e80a1840230c301001430404646600200203a44b30010018a5eb8226644b3001323300100132330010013756619002619202618a026ea8c32004c32404c31404dd5002112cc004006297ae0899199119198008009bab30ca010042259800800c400e2646619c026e9ccc33804dd480299867009865808009986700986600800a5eb80cc00c00cc34004008c338040050cc011bae30c6010013300300330cb0100230c901001431c0444b30010018a508acc004cdc79bae30c801375861900200201d14a313300200230c90100143080486300a26618a0200466008008003133004004001430004618802002618a0200286100a26464b300100185300c2980614c030a601899912cc00400615003133069375600244b30010028980398648080444c8c9660020030ac0185600c2b006158031332259800800c2b80615c030ae0189918031867008039bad00185700a19c02375c002618e02004866008c31404004c320040090c60142a006150030a8014320046eb8004c304040090c601185f8080098610080121800285100a0f885100a17c0237560030a10185080c284050c101185f00800a1780230be0100284f80c27c0613e0309f0142fc0461780200285d008dd7000985d8080121780230b90100142dc04616a026ea80061340285900a1340309a0184d00c268050ba01192cc004c21004c2d004dd5000c4c2e004c2d404dd5000c54cc2cc0524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642c804616e026170026170026168026ea8c2dc04c2e004c2d004dd5000c238050b501185b00800a168023232330010010112259800800c52f5c11332259800acc004cdd7985d00985b809baa30ba0130bb0130b701375400400b1323300100132330010013756617802617a026172026ea8c2f004c2f404c2e404dd5002112cc004006297ae0899199119198008009bab30be010042259800800c400e26466184026e9ccc30804dd48029986100985f808009986100986000800a5eb80cc00c00cc31004008c308040050c0011bae30ba010013300300330bf0100230bd0100142ec0444b30010018a508acc004cdc79bae30bc01375861780200201114a313300200230bd0100142d80485d00a29410b40144cc2e404008cc01001000626600800800285a008c2e004004c2e4040050b60118328008184f009baa061309e0137540cf19800984f009baa0619119b83304933700004002003309e0137540ce9114c004c2940400e6eb8c2900400e44464b300133712002900045200089980319b8200100248320050a20119b81003002985280800cdd6185200800a44445300130aa010059bac30a9010059855008014c29804dd5198321bac30a9010020a2014888a6002615c020093756615a0200930ae0130ae010029bac30ad01002985700985700985700985700985700985700985700985700985700800cdd7185680800a444445300130b301006985980985a008034dd6185980985a00985a00985a00985a008024dd71859808014dd7185980985a00985a008014c0a8c184dd5985980802244444464b300100184880c4c96600261780200513259800800c5660026116026170026ea8006264b300100184a80c4c9660020030960184b00c2580612c031332259800800c26006264b30010018992cc0040061340313259800800c26c061360309b018992cc004c3140400e330010048992cc00400613c031325980098638080144c9660020030a1018992cc004c3240400a264b30010018cc004006264b30010018cc0040062646645300130ce0130ce0130ce0100299911919800800814112cc004006297ae11018000810180008101800044cc8966002600c0051330d201374e661a4020046eb0c34c04004cc34804c34c04c35004004cc34804c34c04c35004c350040052f5c1159800980280144cc34804c34c04004cc34804dd399869008011bac30d30130d401001330d20130d30130d40130d4010014bd7044cc34804c34c04004cc34804c34c04c35004004cc34804dd399869008011bac30d30130d40130d4010014bd70219a0243340461a2020026600400461a402002867808cc0b400405ccc19403405e6644646600200204044b30010018a5eb841018000810180008101800044cc8966002600c0051330d201374e661a4020046eb0c34c04004cc34804c34c04c35004004cc34804c34c04c35004c350040052f5c1159800980280144cc34804c34c04004cc34804dd399869008011bac30d30130d401001330d20130d30130d40130d4010014bd7044cc34804c34c04004cc34804c34c04c35004004cc34804dd399869008011bac30d30130d40130d4010014bd70219a0243340461a2020026600400461a402002867808cc0b800405ccc19003405d2229800986880801cc3400400e61a20200530d10100148888c8c8cc8a600261b202005375a61b00200530d9010019bad30d8010014888a600261ba02009375a61b802009375661b8020053370666e0806400400d22223233223298009bad30e40100199baf0240139bad30e4010144888ca6002b3001003899b8100b025899b8000b0014388053370066e0403c094006613002065375c61d00261d20200b59800801c4026266e0402660020130048012084438804911112cc0056600266e3c0d4dd71876808114528c54cc3a00524011769735f696e74656e745f76616c6964203f2046616c73650014a087380a2b300159800985d809874809baa30ed0130ee010138a518a9987400a491a69735f7072696365735f7665726966696564203f2046616c73650014a087380a2b3001598009844009ba73233001001375861dc0261de0203844b30010018a5eb8226644b30013375e61e20261dc026ea8c3c404c3c804c3b804dd5001003c4cc3c004008cc010010006266008008002875808c3bc04004c3c0040050ed014528c54cc3a0052411f6e6f5f6f746865725f6163636f756e745f696e70757473203f2046616c73650014a087380a2b3001598009844009ba73233001001375861dc0261de0203644b30010018a5eb8226644b30013375e61e20261dc026ea800801e2661e0020046600800800313300400400143ac0461de0200261e00200287680a29462a661d002921206e6f5f6f746865725f6163636f756e745f6f757470757473203f2046616c73650014a087380a2b300159800acc004cdc399827cc004cc20c04ca6002003375861dc020414bd6f7b63020022225980080144006330010039878808014ca60020030029bab30f10130f20130ee01375461e20261e40261dc026ea8c3c40400d0011112cc00400a2003132332298008034c3dc04016646600200200a44b300100189987b8099bb037520086e9800d2f5bded8c113298009bae30f5010019bab30f601001987d008012444b3001337200100071330fb01337606ea4020dd3003802c56600266e3c02000e264b300130cc0130f90137540031330fc01337606ea4024c3f404c3e804dd5000801440090f701192cc0056600200314a314a087d80a2980103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee01183f994c0040066eb0c3b80407e97adef6c604004444b30010028800c6600200730f101002994c004006005375661e20261e40261dc026ea8c3c40400d0011112cc00400a2003132332298008034c3dc04016646600200200a44b300100189987b8099bb037520086e9800d2f5bded8c113298009bae30f5010019bab30f601001987d008012444b3001337200100071330fb01337606ea4020dd3003802c56600266e3c02000e264b300130cc0130f90137540031330fc01337606ea4024c3f404c3e804dd5000801440090f701192cc0056600200314a314a087d80a298103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee0140da07e839003c006266e1ccc13e600266106026530010019bac30ee0101ba5eb7bdb1810011112cc00400a200319800801cc3c40400a6530010018014dd59878809879009877009baa30f1010034004444b30010028800c4c8cc8a600200d30f7010059919800800802912cc0040062661ee0266ec0dd48021ba60034bd6f7b63044ca60026eb8c3d4040066eacc3d80400661f4020049112cc004cdc8004001c4cc3ec04cdd81ba9008374c00e00b15980099b8f0080038992cc004c33004c3e404dd5000c4cc3f004cdd81ba900930fd0130fa013754002005100243dc0464b300159800800c528c52821f6028a6103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee01183f994c0040066eb0c3b80407297adef6c604004444b30010028800c6600200730f101002994c004006005375661e20261e40261dc026ea8c3c404c3c804c3b804dd5187880801a002222598008014400626466453001006987b80802cc8cc00400401489660020031330f701337606ea4010dd3001a5eb7bdb1822653001375c61ea02003375661ec0200330fa0100248896600266e4002000e2661f60266ec0dd48041ba60070058acc004cdc7804001c4c96600261980261f2026ea80062661f80266ec0dd4804987e80987d009baa001002880121ee023259800acc004006294629410fb014530103d87a800089865009987e009ba60014bd7021ee02329800800c022006800888966002005100189919914c00401a61060400b32330010010052259800800c4cc20c08cdd81ba9004375000697adef6c608994c004dd7184081000cdd6984101000cc218080092225980099b900080038998438119bb037520106ea001c0162b30013371e01000713259800986c009842811baa0018998440119bb03752012611204610c046ea800400a2004841810c96600261b00200314c0103d87a80008986b0099844011ba80014bd702106043370000e00513308702337606ea400cdd400119803003000a104044208083084020014208088030dd7187e008009bad30fd0100130ff0100243f4051330fb01337606ea400cdd300119803003000a1ec0243d80430f80100143d8048030dd71878008009bab30f10100130f30100243c40480190ee0140da07e839003c00629410e7014528c54cc3a00524012169735f76616c75655f7472616e736665725f636f7272656374203f2046616c73650014a087380a2b300159800acc004022266e24cdc11bad30ed010190043370400a906400c528a1ce028a518a9987400a492d69735f6f70657261746f725f6d696e5f70657263656e746167655f6d61696e7461696e6564203f2046616c73650014a087380a2b300159800acc0056600266e1cdd6982f9875009baa0240048a518a9987400a491f69735f746f74616c5f7368617265735f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60bc61d4026ea809001629462a661d0029212269735f6f70657261746f725f7368617265735f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60ba61d4026ea8090cdc09bad30ed010110098a518a9987400a4812269735f746f74616c5f6465706f73697465645f636f7272656374203f2046616c73650014a087380a2b30015980099b87375a60a661d4026ea8090cdc01bad30ed0130ee0100d0068a518a9987400a4812c69735f746f74616c5f6665655f73686172655f636f6c6c65637465645f636f7272656374203f2046616c73650014a087380a2b30015980099b8f375c60b861d4026ea80916600266e2120000068acc004c2f004c3a404dd501cc4c96600266e2401d20008801c4cc8966002617e0200319800984a80802c00a6eccc2f404cc3bc04dd40049987780a6010100004bd704dd61878009876809baa00341a9159800985f00800c4c8c8cc896600261860261e0026ea800a264b30010018cc00400633001309a0100a803c00a0093766618402661e8026ea0cdc01bad30f50130f201375400201c661e80261800261e4026ea80052f5c083721a60282d21a6030d30186980c34c050f701187a009878809baa00286880a1dc02306f001375861e40261e6020046eb8c3c404004c3b404dd5001c54cc3ac0524129496e76616c6964204d504620616374696f6e20666f72206f70657261746f7220666565207368617265001643a804875008dd980e9875009baa00143a00461da0261d4026ea80e62a661d0029212965787065637420536f6d6528616374696f6e29203d206f70657261746f725f6d70665f616374696f6e0016439c051002439c0514a315330e8014911e69735f6d65726b6c655f726f6f745f636f7272656374203f2046616c73650014a087380a2b30015980099b8f375c61da0261d4026ea8090dd71876809875009baa0258acc004cdc79bae30b80130ea0137540486eb8c2e004c3a804dd5012c56600266e3cdd7185b809875009baa024375c616e0261d4026ea80962b30013371e6eb8c16cc3a804dd50121bae305b30ea01375404b15980099b8f375c613e0261d4026ea8090dd7184f809875009baa0258acc004cdc79bae305a30ea0137540486eb8c168c3a804dd5012c56600266e3cdd7182c9875009baa024375c60b261d4026ea80962b30013371e6eb8c160c3a804dd50121bae305830ea01375404b15980099baf309e0130ea013754048613c0261d4026ea80962b30013370e6eb4c15cc3a804dd50121bad305730ea01375404b15980099b87375a60ac61d4026ea8090dd6982b1875009baa0258acc004cdd7982a9875009baa024305530ea01375404b159800985d809874809baa305430ea013754049130bb0130e901375460a861d4026ea80963300130bb0130e901375460a861d4026ea80969429450e70121ce028a50439c0514a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a518a9987400a492169735f6f746865725f6669656c64735f756e6368616e676564203f2046616c73650014a087380a29410e701452821ce028a50439c0514a087380a29410e7014528c54cc3a00524011f69735f6f7261636c655f646174756d5f75706461746564203f2046616c73650014a087380a2b300159800991980080081c912cc00400629422b30013371e6eb8c3bc040040f6294626600400461e0020028748090ed014528c4c966002617a0261d4026ea8006264646600200207644b30010018a508acc004cdc79bae30f1010010038a51899801001187900800a1d60243bc046eb8c3b804c3ac04dd5000c52821d002306001c439c0514a315330e80149011169735f7369676e6564203f2046616c73650014a087380a29410e701452821ce028a50439c0514a087380a29410e701452821ce028a50439c045980080145200089982299b829800804400e00282080380310e1010c96600261600200313232332259800985b809872009baa0028992cc004006330010018acc004cdc38131bad30e90130e60137540031330e80130b40130e6013754002661d0026ea66002611c02011007802400906125eb822a661c80292012b657870656374207368617265735f746f5f72656465656d203d3d206f6c645f656e7472792e7368617265730016438c050c80141390c80186400c3200619002875808c3a004c39404dd5001454cc38c0524013365787065637420536f6d65286f6c645f6461746129203d2063626f722e646573657269616c697365286f6c645f76616c756529001643880460c60026eb0c39804008dd71872809873008009870809baa0318acc004c2c804006264646644b300130b70130e401375400513259800800c6600200315980099b89026375a61d20261cc026ea8006264661d2026ea0004cc3a404dd4cc004c23c04026011003802cdd9985b8099874809ba8337026eb4c3a804c39c04dd500101399874809ba8337026eb4c2d404c39c04dd5001000a5eb8106325eb80cdc199b82375a61680261cc026ea8004098dd69874809873009baa0018a9987200a4812b657870656374206f6c645f656e7472792e736861726573203e3d207368617265735f746f5f72656465656d0016438c050c70141390c70186380c31c0618e02875808c3a004c39404dd50014314050e20118318009bac30e60130e701002375c61ca0200261c2026ea80c62a661be02920121496e76616c6964204d504620616374696f6e20666f72207769746864726177616c001643780486f008c37c04dd50181bae30e101001376604261c202008186b80986b80800cc0040c605d375861ac0200302c412c61ac0200261aa020081866009866009866009866008009849809986500986580800a5eb80c32c04c31c04dd500142980504042980614c030a60185300a198023259800984b009863009baa00189865009863809baa0018a9986280a492c65787065637420496e6c696e65446174756d287261775f646174756d29203d206f75747075742e646174756d0016431004619202619402619402618c026ea800a1480281fa148030a40185200c290050cb01192cc004c25404c31404dd5000c4c32404c31804dd5000c54cc3100524013265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d0016430c04619002619202619202618a026ea8c32004c32404c31404dd5001c288050c601186380800a18a0232330010010172259800800c52f5c11332259800991980080099198008009bab30cc0130cd0130c901375400844b30010018a5eb82264664464660020026eacc338040108966002003100389919869009ba7330d201375200a661a402619e02002661a40261a00200297ae03300300330d40100230d2010014340046eb8c32804004cc00c00cc33c04008c334040050cb01112cc00400629422b30013371e6eb8c33004dd61866008008074528c4cc008008c334040050c6012194028998648080119802002000c4cc0100100050c401186400800986480800a18c0284f80a1880230c501001430c04646600200203a44b30010018a5eb8226644b3001323300100132330010013756619402619602618e026ea8c32804c32c04c31c04dd5002112cc004006297ae0899199119198008009bab30cc010042259800800c400e264661a0026e9ccc34004dd480299868009866808009986800986700800a5eb80cc00c00cc34804008c340040050ce011bae30c8010013300300330cd0100230cb0100143240444b30010018a508acc004cdc79bae30ca01375861940200201914a313300200230cb0100143100486400a26618e0200466008008003133004004001430804618c02002618e0200286200a1380284000a13802861008dd6800c26c050c501186100800a1800230c20100284c80c264061320309901430c0461800200285f008dd7000985f8080121800230bd0100142ec046172026ea80061280285b00a128030940184a00c250050be01192cc004c22004c2e004dd5000c4c2f004c2e404dd5000c54cc2dc052413265787065637420496e6c696e65446174756d287261775f646174756d29203d20696e7075742e6f75747075742e646174756d001642d8046176026178026178026170026ea8c2ec04c2f004c2e004dd5000c248050b901185d00800a170023232330010010132259800800c52f5c11332259800acc004cdd7985f00985d809baa30be0130bf0130bb01375400400b1323300100132330010013756618002618202617a026ea8c30004c30404c2f404dd5002112cc004006297ae0899199119198008009bab30c2010042259800800c400e2646618c026e9ccc31804dd480299863009861808009986300986200800a5eb80cc00c00cc32004008c318040050c4011bae30be010013300300330c30100230c10100142fc0444b30010018a508acc004cdc79bae30c001375861800200201114a313300200230c10100142e80485f00a29410b80144cc2f404008cc01001000626600800800285c008c2f004004c2f4040050ba0118348008109b012136021808808a610a026ea812522259800982d800c4c9660020030608992cc0040062b3001308f010028cc0040060090614129061423005061830c1860c2848008c2340400508b011844809baa04c8acc004c168006264b300100183044c966002003061830c1860c31332259800800c18e264b3001001832419226644b300100183344c966002003067899912cc0040060d313259800800c56600261300200513303a006225980080144cc0f0014896600200519800802c0460dc809226464b300100183841c20e1070899912cc0040060e50728992cc0040060e713259800800c1d20e907483a44cc89660020030768992cc0040060ef07783bc1de264b300130a6010038980598530080641e10a3011bae001429804614602002850808dd700098510080121460230a0010014278046eb00060e50724284046eb8004c2680400909f01184c00800984d808012132028992cc0040060db06d836c1b626460066138020086eb800509c01184c80801212e02835212a0283541aa0d506a426404612c0200284a008dd5800984a80801419e0cf067425804612602002848808dd600098490080141920c8849808c2400400508e011bae001308f01002424004611a02002845808c22404dd5026456600260b000313259800800c182264b3001001830c1860c3061899912cc0040060c713259800800c1920c91332259800800c19a264b3001001833c4cc89660020030698992cc004006264b3001001835c4c966002003159800984d0080144cc0f0020896600200513303e007225980080146600200f132598009836800c4c9660020030728992cc0040062b300130a1010028cc00400602d073405d073427805073839c1ce0e6851008c27c0400509d01184d809baa0068acc004c1b00062b3001309b01375400d014838a13802838a130024260046132026ea80160e080a226464b300100183941ca0e5072899912cc0040060e90748992cc0040060eb13259800800c1da0ed07683b44cc89660020030788992cc0040060f307983cc1e6264b300130a8010038980598540080641e90a5011bae00142a004614a02002851808dd7000985200801214a0230a2010014280046eb00060e9074428c046eb8004c270040090a101184d00800984e808012136028992cc0040060df06f837c1be2646006613c020086eb800509e01184d80801213202836212e0283641b20d906c426c0461300200284b008c2600400a0d506a83541a909901184b00800a128023756002612a02005067833c19d09601184980800a1220237580026124020050648322126023090010014238046eb8004c23c0400909001184680800a11602308901375409905f4218048430090860120b905c82e417108b01088c8ca6002003480020068008888c8c9660020071489200000000000000000000000000000000000000000000000000000000000000000008992cc00400626464b3001305e0018994c0040126eb4c240040066eb8c24004c244040050051846009baa0028acc004c1740062646607a66e2cdd69848009846809baa001375c60b6611a026ea8004dd7182d1846809baa001308f01309001308c0137540051323303d33023375c6120020020106eb8c24004c24404004c24004c23004dd50012112024224046114026ea8004c2340401226464b3001305e0018994c0040126eb4c240040066eb8c24004c244040050051846009baa0028acc004c17400626465300100b804c007300100a800c01500a4c24404c2480400901018031bad309001001308c01375400513233223322980080740320039800806c006010806a60c266126026ea0cc0f8008030cc24c04dd4998138010009984980984a00984a8080225eb810131bae3092010023008001309101001375a6120020026118026ea800908901211202308a013754002611a02008845808c2340400d08a01111194c00402600f001cc0040220030044021002403c60080046e00c0cc008dca0011111991194c004006900040110011112cc0040062660726603e00a004009132332259800982f00144c8ca6002015007800e600201100198490080320109bae309101309201002404460046eb4c24004004c23004dd5001c56600260ba005132329800805401e0039800804400661240200c80426122026124020048080c008dd69848008009846009baa00389919914c004dd71849008014c01000661260200e9114c00403a017002cc00403200500140313062330940137506607e006607600466128026ea4cc0a000c008cc25004c25404c258040152f5c080a06122020026eb4c24004004c23004dd5001a112024224046112026ea8004dc0181b001984600800a1140237280066e500081164104820888c966002602e60886ea8006264b30010018acc004c060c114dd5000c4c9660020030208992cc004006043021810c08626644b3001001811c4c96600200302481240920491332259800800c09a264b30010018992cc00400605113259800800c0a6053029814c4cc896600200302b8992cc00400605902c81640b226644b300100181744c96600200313259800800c0c2264b3001001818c0c6063031899912cc00400606713259800800c4c9660020030358992cc00400606d03681b40da26644b300100181c44c96600200303981cc0e60731332259800800c0ee264b300100181e40f207903c899912cc00400607d13259800800c0fe07f03f81fc4c96600260d60071980080d46600202519800806c408a080813a080813a08081320808340dd7000a0d6306800141986eb8004c19c0090681832800a0c6375c00260c80048328c1880050601bae0013061002418860be00282e8c17c00a06903481a40d1060182e800a0b6375c00260b800482e8c168005058182d00140be05f02f817a0b6305800141586eb8004c15c009058182a800a0a6375c00260a800482a8c1480050501829001409e04f027813a0a6305000141386eb8004c13c0090501826800a096375c00260980048268c12800504818231baa00180fa08680fc07e03f01f412c6464b300130190018a99822a481274f7261636c6520696e70757420646f6573206e6f7420636f6e7461696e20616e7920646174756d00168acc004c0600062a6608a921224f7261636c6520696e70757420646174756d206d75737420626520696e6c696e656400168982518239baa00241108220c114dd5000980918229baa3013304537546090608a6ea80062a660869201cd65787065637420536f6d65286465785f6f726465725f626f6f6b5f7265665f696e70757429203d0a20202020696e707574730a2020202020207c3e206c6973742e66696e64280a20202020202020202020666e287265665f696e7075743a20496e70757429207b0a2020202020202020202020207175616e746974795f6f66287265665f696e7075742e6f75747075742e76616c75652c206465785f6f726465725f626f6f6b5f746f6b656e2c20222229203d3d20310a202020202020202020207d2c0a20202020202020202900164108660120044602c64b300130173045375400314800226eb4c124c118dd5000a0863259800980b98229baa0018a6103d87a8000899198008009bab304a3047375400444b30010018a6103d87a8000899192cc004c0780062b3001301d0018980d19826182500125eb82298103d87a8000411d133004004304e003411c6eb8c120004c12c00504920863300b37566026608a6ea8c04cc114dd500080118209baa0042223259800980b800c4c9660020030038992cc004006264b3001001802c4c966002003006803401a00d132598009827001c66002009008803a016803a096375c0028270c12c0050491825801401200900480220983049001411c608a6ea80122b300130160018992cc00400600713259800800c4c9660020030058992cc00400600d006803401a264b3001304e0038cc004012011007402d007412c6eb800504e1825800a092304b0028024012009004413060920028238c114dd50024566002602800313259800800c00e264b30010018992cc00400600b13259800800c01a00d00680344c966002609c00719800802402200e805a00e8258dd7000a09c304b0014124609600500480240120088260c12400504718229baa004801208441088210c10cdd500188a4d15330294911856616c696461746f722072657475726e65642066616c7365001365640a01", + "hash": "34287f56be7722bfbca67475a01e7eec6e15a3dc668f7941430ac130" }, { "title": "hydra_order_book/core.hydra_order_book.spend", @@ -1884,72 +1884,6 @@ } ] }, - "hydra_dex/types/HydraAccountOperation": { - "title": "HydraAccountOperation", - "anyOf": [ - { - "title": "ProcessWithdrawal", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "mpf_action", - "$ref": "#/definitions/hydra_dex~1types~1MPFProof" - } - ] - }, - { - "title": "ProcessCancelWithdrawal", - "dataType": "constructor", - "index": 1, - "fields": [ - { - "title": "mpf_action", - "$ref": "#/definitions/hydra_dex~1types~1MPFProof" - } - ] - }, - { - "title": "ProcessSameAccountTransferal", - "dataType": "constructor", - "index": 2, - "fields": [ - { - "title": "account", - "$ref": "#/definitions/hydra_dex~1types~1UserAccount" - } - ] - }, - { - "title": "ProcessTransferal", - "dataType": "constructor", - "index": 3, - "fields": [] - }, - { - "title": "ProcessCombineUtxosAtClose", - "dataType": "constructor", - "index": 4, - "fields": [ - { - "title": "tree_or_proofs_with_token_map", - "$ref": "#/definitions/hydra_dex~1types~1TreeOrProofsWithTokenMap" - } - ] - }, - { - "title": "ProcessSplitUtxosAtOpen", - "dataType": "constructor", - "index": 5, - "fields": [ - { - "title": "tree_or_proofs_with_token_map", - "$ref": "#/definitions/hydra_dex~1types~1TreeOrProofsWithTokenMap" - } - ] - } - ] - }, "hydra_dex/types/HydraAccountRedeemer": { "title": "HydraAccountRedeemer", "anyOf": [ @@ -1975,6 +1909,12 @@ "dataType": "constructor", "index": 2, "fields": [] + }, + { + "title": "HydraAccountMigrate", + "dataType": "constructor", + "index": 3, + "fields": [] } ] }, diff --git a/validators/hydra_account/core.ak b/validators/hydra_account/core.ak index 6ce8439..b14e758 100644 --- a/validators/hydra_account/core.ak +++ b/validators/hydra_account/core.ak @@ -76,7 +76,6 @@ validator hydra_account(dex_oracle_nft: PolicyId) { is_no_value?, is_no_datum?, }, - trace @"todo: remove it" is_operation_key_signed?, } }