From 6239e7e6fd7e8db98e8334d29e798a3a0e348f10 Mon Sep 17 00:00:00 2001 From: Richard Nguyen Date: Tue, 16 Apr 2024 08:33:34 +0700 Subject: [PATCH] Minswap Optimization & new Features after Certik Audit (#35) * move Liquidity Pool logic to Pool batching Withdrawal contract (#31) * move Liquidity Pool logic to Pool batching Withdrawal contract * use inline datum for contracts except order * refactor code * add dynamic fee support * fix test * feat: support bidirectional fee (#32) * allow order can decide its amount by specific amount or relying on amount in its value and update spec doc (#37) * allow order can decide its amount by specific amount or relying on amount in its value and update spec doc * strict datum type of sender and receiver * add offchain testing (#40) * add offchain testing * remove unused file * pump aiken ci * support donation order [MIN-532] (#42) * support donation order * update spec * change test admin policy id * use 10000 as default fee denominator (#43) * use 10000 as default fee denominator * fix docs and comment * handle global setting to store authorizer that can interact with pool contract (#45) * fix initialization transaction * Optimization from Anastasia Labs (#46) * Optimization from Anastasia Labs * adhoc compare swap value (#47) * adhoc compare swap value * add more comments * resolve audit finding (#48) * remove redundant code * verify only pool script & author script (if have) is allowed on some pool's redeemers * Test for math functions (#49) * increase Pool Minimum ADA from 3 ADA to 4.5 ADA to buffer for ledger change and inline datum (#50) * increase Pool Minimum ADA from 3 ADA to 4.5 ADA to buffer for ledger change and inline datum * update script --------- Co-authored-by: Minggggg <80378612+haminh02@users.noreply.github.com> --- .eslintrc.cjs | 36 + .github/workflows/tests.yml | 2 +- .gitignore | 5 + .nvmrc | 1 + .prettierignore | 1 + .prettierrc | 4 + amm-v2-docs/amm-v2-specs.md | 462 +- amm-v2-docs/formula.md | 2 +- amm-v2-docs/pics/architecture.png | Bin 203046 -> 257384 bytes jest.config.js | 206 + jest.setup.js | 3 + lib/amm_dex_v2/math.ak | 430 +- lib/amm_dex_v2/order_validation.ak | 1130 +++-- lib/amm_dex_v2/pool_validation.ak | 825 ++-- lib/amm_dex_v2/types.ak | 161 +- lib/amm_dex_v2/utils.ak | 328 +- package-lock.json | 6981 +++++++++++++++++++++++++++ package.json | 70 + plutus.json | 394 +- rollup.config.js | 28 + src/batcher-sample.ts | 619 +++ src/hash.ts | 7 + src/provider.ts | 57 + src/script.ts | 297 ++ src/types/address.ts | 151 + src/types/asset.ts | 32 + src/types/global-setting.ts | 25 + src/types/network.ts | 5 + src/types/order.ts | 167 + src/types/pool.ts | 44 + src/types/redeemer.ts | 45 + src/types/tx.ts | 27 + tsconfig.json | 19 + validators/always_success.ak | 8 + validators/authen_minting_policy.ak | 149 +- validators/factory_validator.ak | 80 +- validators/order_validator.ak | 150 +- validators/pool_validator.ak | 425 +- validators/sample_multi_sign.ak | 63 +- 39 files changed, 11694 insertions(+), 1745 deletions(-) create mode 100644 .eslintrc.cjs create mode 100644 .nvmrc create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 jest.config.js create mode 100644 jest.setup.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 rollup.config.js create mode 100644 src/batcher-sample.ts create mode 100644 src/hash.ts create mode 100644 src/provider.ts create mode 100644 src/script.ts create mode 100644 src/types/address.ts create mode 100644 src/types/asset.ts create mode 100644 src/types/global-setting.ts create mode 100644 src/types/network.ts create mode 100644 src/types/order.ts create mode 100644 src/types/pool.ts create mode 100644 src/types/redeemer.ts create mode 100644 src/types/tx.ts create mode 100644 tsconfig.json create mode 100644 validators/always_success.ak diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..90a31b8 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,36 @@ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + parserOptions: { + project: ["./tsconfig.json"], + }, + plugins: [ + "@typescript-eslint", + "simple-import-sort", + "unused-imports", + "unicorn", + ], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + rules: { + eqeqeq: "error", + "simple-import-sort/imports": "error", + "simple-import-sort/exports": "error", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/explicit-function-return-type": "error", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-floating-promises": "error", + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "error", + { + vars: "all", + varsIgnorePattern: "^_", + args: "all", + argsIgnorePattern: "^_", + }, + ], + "no-console": "warn", + "unicorn/no-array-for-each": "error", + "unicorn/prefer-regexp-test": "error", + }, +}; diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 60a734b..68374dc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: - uses: aiken-lang/setup-aiken@v0.1.0 with: - version: v1.0.21-alpha + version: v1.0.24-alpha - run: aiken fmt --check - run: aiken check diff --git a/.gitignore b/.gitignore index ff7811b..6466144 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,8 @@ artifacts/ build/ # Aiken's default documentation export docs/ +node_modules +build +build-tsc +coverage +.idea \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..0828ab7 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v18 \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +build diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7197da8 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": false, + "trailingComma": "es5" +} diff --git a/amm-v2-docs/amm-v2-specs.md b/amm-v2-docs/amm-v2-specs.md index fa521dc..5579a5d 100644 --- a/amm-v2-docs/amm-v2-specs.md +++ b/amm-v2-docs/amm-v2-specs.md @@ -5,7 +5,7 @@ - Minswap AMM V2 uses Constant Product Formula (x * y = k). This formula, most simply expressed as x * y = k, states that trades must not change the product (k) of a pair’s reserve balances (x and y). Because k remains unchanged from the reference frame of a trade, it is often referred to as the invariant. This formula has the desirable property that larger trades (relative to reserves) execute at exponentially worse rates than smaller ones. -- The AMM V2 uses Batching architecture to solve concurrency on Cardano. Each user action will create an "Order" and "Batcher" will look through them and apply them into a "Liquidity Pool". A valid "Batcher" is a wallet which contains Minswap's License Token. Batching transaction is permissioned and only is triggered by "Batcher". +- The AMM V2 uses Batching architecture to solve concurrency on Cardano. Each user action will create an "Order" and "Batcher" will look through them and apply them into a "Liquidity Pool". A valid "Batcher" is a wallet which is whitelisted. Batching transaction is permissioned and only is triggered by "Batcher". ## 2. Architecture @@ -28,9 +28,14 @@ There're 5 contracts in the AMM V2 system: - User: An entity who wants to interact with Liquidity Pool to deposit/withdraw liquidity or swap. The only requirement of users is that they must not be the same as batcher (because of how we filter UTxOs) -- Batcher: An entity who aggregate order UTxOs from users and match them with liquidity pool UTxO. A batcher must hold a batcher's license token. The license token must not be expired and the expired time must be between current time and Maximum Deadline (to prevent minting license with infinity deadline). -- Admin (aka Minswap team): An entity who has permission to update Liquidity Pool's fee, withdraw fee sharing and change the pool's stake address. An Admin must hold an admin's license token. +- Batcher: An entity who aggregate order UTxOs from users and match them with liquidity pool UTxO. A batcher must be whitelisted in the Global Setting +- Pool Fee updater: An entity who has permission to create a Liquidity Pool's base fee and fee sharing to any value within allowed range (0.05% to 20% for base fee and 16.66% to 50% for fee sharing). The actor must be whitelisted in the Global Setting +- Fee Sharing taker: An entity who has permission to withdraw Liquidity Pool's fee sharing. The actor must be whitelisted in the Global Setting +- Pool Stake Key Updater: An entity who has permission to update Liquidity Pool's stake credential. The actor must be whitelisted in the Global Setting +- Pool Dynamic Fee updater: An entity who has permission to enable or disable Liquidity Pool's dynamic fee. The actor must be whitelisted in the Global Setting +- Admin: The actor who can update the Global Setting. This admin can be transferred to another wallet and should be stored in the most secure location. +Except for the *User* role, the aforementioned actors must adhere to the rules set by the `authorize_license_holder` function and be whitelisted in the Global Setting. ### 3.2 Tokens @@ -41,52 +46,41 @@ There're 5 contracts in the AMM V2 system: - Pool NFT token: the Pool legitimate Token, can be only minted in Pool Creation Transaction and cannot be outside Pool Contract. The minting must be followed by rule of `Authen Minting Policy` - CurrencySymbol: Authen Minting Policy - TokenName: Defined in `Authen Minting Policy` parameters (e.g. "MSP") +- Global Setting NFT token: the Global Setting legitimate Token, can be only minted in DEX Initialization Transaction and cannot be outside Global Setting UTxO. The minting must be followed by rule of `Authen Minting Policy` + - CurrencySymbol: Authen Minting Policy + - TokenName: Defined in `Authen Minting Policy` parameters (e.g. "GT") - LP token: Represents Liquidity Provider's share of pool. Each pool has a different LP token. - CurrencySymbol: Authen Minting Policy - TokenName: Hash of Pool's Asset A and Asset B (`SHA_256(SHA_256(AssetA), SHA_256(AssetB))`) - Batcher license token: Permit batcher to apply pool - - CurrencySymbol: Defined in Pool parameters. The policy is managed by team (e.g. multisig policy) - - TokenName: POSIX timestamp represents license deadline -- Admin license token: - - CurrencySymbol: Defined in Pool parameters. The policy is managed by team (e.g. multisig policy) + - CurrencySymbol: Defined in the constant `batcher_license_policy_id`. The policy is managed by team (e.g. multisig policy) - TokenName: POSIX timestamp represents license deadline - - Admin License is used on Factory and Pool Validator via `is_admin_existence` function and can be in a PubKey or Script wallet ### 3.3 Smart Contract -#### 3.3.1 Order Spending Validator - +#### 3.3.1 Expired Order Cancellation Validator -Order Spending validator is a Withdrawal Script and takes the responsibility to validate two Order contract's redeemer *ApplyOrder* and *CancelExpiredOrderByAnyone*. -To avoid overlapping validation in each utxo, we forward these conditions to this script and the Order script will rely on it +Expired Order Cancellation validator is a Withdrawal Script and takes the responsibility to validate expired orders have been cancelled in the correct way by anyone. Funds must be returned to sender #### 3.3.1.1 Parameter - -- _pool_hash_: the hash of Liquidity Pool Script +None #### 3.3.1.2 Redeemer - -- **OrderSpendingRedeemer**: - - _pool_input_index_: Index of Pool UTxO in Transaction Inputs. +Anything #### 3.3.1.3 Validation - -- **OrderBatchingRedeemer**: The redeemer contains `pool_input_index`, it's used for finding Pool Input faster - - In case the inputs at *pool_input_index* is Pool Input (Address's Payment Credential matching with `pool_hash`), the contract is passed and forward the validation to Pool Contract - - Otherwise, it trigger validation for cancelling expired order: - - this flow will assume all script inputs are orders and must have the Order datum structure - - each input must be matched with an output in the same index - - validate the transaction must be created after expired time - - validate ADA in the order might be deducted for tipping a canceller. The tip must not exceed the maximum tip and other tokens must be returned to sender - - If sender is script address, the output have to attach the defined datum - +- this flow will assume all script inputs are orders and must have the Order datum structure +- each input must be matched with an output in the same index +- validate the transaction must be created after expired time +- validate ADA in the order might be deducted for tipping a canceller. The tip must not exceed the maximum tip and other tokens must be returned to sender +- If sender is script address, the output have to attach the defined datum #### 3.3.2 Order Validator @@ -97,7 +91,8 @@ Order validator is responsible for holding "User Requests" funds and details abo #### 3.3.2.1 Parameter -- _stake_credential_: the Stake Credential of `Order Spending Validator` +- _pool_batching_credential_: the Stake Credential of `Pool Batching Validator` +- _expired_order_cancel_credential_: the Stake Credential of `Expired Order Cancellation Validator` #### 3.3.2.2 Datum @@ -108,38 +103,37 @@ There are 10 order types: - **SwapExactIn**: is used for exchanging specific amount of single asset in the liquidity pool, the order will be executed if the received amount is greater than or equal to `minimum_receive` which is defined below - _a_to_b_direction_: The AToB direction of swap request. True for A -> B and False for B -> A - - _swap_amount_: Amount of Asset In which users want to exchange + - _swap_amount_option_: Amount of Asset In which users want to exchange, [References](../lib/amm_dex_v2/types.ak#L72) - _minimum_receive_: Minimum amount of Asset Out which users want to receive after exchanging - _killable_: Decide the Order behavior in case Order is not meet the slippage tolerance - **StopLoss**: is used for exchanging specific amount of single asset in the liquidity pool, the order will be executed if the received amount is less than or equal to `stop_loss_receive` which is defined below - _a_to_b_direction_: The AToB direction of swap request. True for A -> B and False for B -> A - - _swap_amount_: Amount of Asset In which users want to exchange + - _swap_amount_option_: Amount of Asset In which users want to exchange, [References](../lib/amm_dex_v2/types.ak#L72) - _stop_loss_receive_: Maximum amount of Asset Out which users want to receive after exchanging - _killable_: Decide the Order behavior in case Order is not meet the slippage tolerance - **OCO**: is used for exchanging specific amount of single asset in the liquidity pool, the order will be executed if the received amount is less than or equal to `stop_loss_receive` and greater than or equal to `minimum_receive` which are defined below - _a_to_b_direction_: The AToB direction of swap request. True for A -> B and False for B -> A - - _swap_amount_: Amount of Asset In which users want to exchange + - _swap_amount_option_: Amount of Asset In which users want to exchange, [References](../lib/amm_dex_v2/types.ak#L72) - _minimum_receive_: Minimum amount of Asset Out which users want to receive after exchanging - _stop_loss_receive_: Maximum amount of Asset Out which users want to receive after exchanging - _killable_: Decide the Order behavior in case Order is not meet the slippage tolerance - **SwapExactOut**: is used for exchanging single asset in the liquidity pool and receiving the exact amout of other asset, the order will be executed if the received amount is equal to `expected_receive` which is defined below - _a_to_b_direction_: The AToB direction of swap request. True for A -> B and False for B -> A - - _swap_amount_: Amount of Asset In which users want to exchange + - _maximum_swap_amount_option_: Maximum amount of Asset In which users want to exchange[References](../lib/amm_dex_v2/types.ak#L72) - _expected_receive_: The exact amount of Asset Out which users want to receive after exchanging - _killable_: Decide the Order behavior in case Order is not meet the slippage tolerance - **Deposit**: is used for depositing pool's assets and receiving LP Token - - _deposit_amount_a_: Amount of Asset A which users want to deposit - - _deposit_amount_b_: Amount of Asset B which users want to deposit + - _deposit_amount_option_: Amount of Asset A and B which users want to deposit, [References](../lib/amm_dex_v2/types.ak#L82) - _minimum_lp_: The minimum amount of LP Token which users want to receive after depositing - _killable_: Decide the Order behavior in case Order is not meet the slippage tolerance - **Withdraw**: is used for withdrawing pool's asset with the exact assets ratio of the liquidity pool at that time - - _withdrawal_lp_amount_: Amount of LP Asset which users want to withdraw + - _withdrawal_amount_option_: Amount of LP Asset which users want to withdraw, [References](../lib/amm_dex_v2/types.ak#L92) - _minimum_asset_a_: minimum received amounts of Asset A. - _minimum_asset_b_: minimum received amounts of Asset B. - _killable_: Decide the Order behavior in case Order is not meet the slippage tolerance - **ZapOut**: is used for withdrawing a single pool asset out of Liquidity Pool. - _a_to_b_direction_: The AToB direction of ZapOut request. `True` in case Asset Out is B and vice versa - - _withdrawal_lp_amount_: Amount of LP Asset which users want to withdraw + - _withdrawal_amount_option_: Amount of LP Asset which users want to withdraw, [References](../lib/amm_dex_v2/types.ak#L92) - _minimum_receive_: Minimum amount of Asset Out which users want to receive after withdrawing - _killable_: Decide the Order behavior in case Order is not meet the slippage tolerance - **PartialSwap**: is used for exchanging partial amounts of single Asset. The Partial Swap can be executed multiple times if the price ratio is matched with the user's expectation, and the time is defined in `hops`. @@ -150,23 +144,25 @@ There are 10 order types: - _minimum_swap_amount_required_: The minimum amount which is required to swap per each execution time. - _max_batcher_fee_each_time_: Maximum fee that batcher can take to execute each time - **WithdrawImbalance**: is used for withdrawing custom amounts of assets. - - _withdrawal_lp_amount_: Amount of LP Asset which users want to withdraw + - _withdrawal_amount_option_: Amount of LP Asset which users want to withdraw, [References](../lib/amm_dex_v2/types.ak#L92) - _ratio_asset_a_ and _ratio_asset_b_: The ratio of Asset A and Asset B users want to receive after withdrawing - _minimum_asset_a_: The minimum amount of asset A which users want to receive, The amount of Asset will be followed by the ratio (_received_asset_b_ = _minimum_asset_a_ * _ratio_asset_b_ / _ratio_asset_a_) - _killable_: Decide the Order behavior in case Order is not meet the slippage tolerance - **SwapMultiRouting**: is used for exchanging a specific amount of single asset across multiple Liquidity Pools. - _routings_: The routings (including a list of _direction_ and _lp_asset_), which is defined Liquidity Pools the swap is routing through - - _swap_amount_: Amount of Asset In which users want to exchange + - _swap_amount_option_: Amount of Asset In which users want to exchange, [References](../lib/amm_dex_v2/types.ak#L72) - _minimum_receive_: Minimum amount of Asset Out which users want to receive after exchanging + - **Donation**: is utilized for the purpose of contributing assets from the pool to charitable causes or designated recipients, allowing users to make philanthropic contributions using the resources within the pool. An Order Datum keeps information about Order Type and some other informations: -- _sender_: The address of order's creator, only sender can cancel the order -- _sender_datum_hash_: (optional) the datum hash of the output after cancelling order by anyone or killing by batcher. -- _receiver_: The address which receives the funds after order is processed -- _receiver_datum_hash_: (optional) the datum hash of the output after order is processed. +- _canceller_: The address's payment credential that can cancel the order, can by PubKey or Script +- _refund_receiver_: The address of the output after being killed by Batcher or cancelled by bots (order is expired) +- _refund_receiver_datum_: The datum hash of the output after being killed by Batcher or cancelled by bots (order is expired) +- _success_receiver_: The address which receives the funds after order is processed +- _success_receiver_datum_: the datum of the output after order is processed. - _lp_asset_: The Liquidity Pool's LP Asset that the order will be applied to - _step_: The information about Order Type which we mentioned above - _max_batcher_fee_: The maximum fee users have to pay to Batcher to execute batching transaction. The actual fee Batcher will take might be less than the maximum fee @@ -185,17 +181,22 @@ An Order Datum keeps information about Order Type and some other informations: - **ApplyOrder**: the redeemer will allow spending Order UTxO in Batching transaction - - validate that an Order can be spent if there's a `Order Spending` validator in the `withdrawals` -- **CancelOrder**: the redeemer will allow _sender_ to spend Order UTxO to get back locked funds. - - validate that the transaction has _sender_'s signature or _sender_ script UTxO in the Transaction Inputs + - validate that an Order can be spent if there's a `Pool Batching` validator in the `withdrawals` +- **CancelOrder**: the redeemer will allow _canceller_ to spend Order UTxO to get back locked funds. + - validate that the the authorization of _canceller_ + - _canceller_ can be one of 4 authorization methods: + - _Signature_: requires the signature in transaction's signatories + - _SpendScript_: requires its Utxo has to present in the transaction inputs + - _WithdrawScript_: requires the script hash has to present in the transaction withdrawals + - _MintScript_: requires minting tokens that has the same policy id with script hash and present in transaction minting. Token's quantity must not be zero - **CancelExpiredOrderByAnyone**: the redeemer will allow anyone to spend Order UTxO to unlock funds going back to user - - validate that an Order can be spent if there's a `Order Spending` validator in the `withdrawals` + - validate that an Order can be spent if there's a `Expired Order Cancellation` validator in the `withdrawals` #### 3.3.3 Authen Minting Policy -Authen Minting Policy is responsible for creating initial Factory `Linked List`, minting legitimate Factory, Liquidity Pool and Liquidity Pool `Share` Tokens +Authen Minting Policy is responsible for creating initial Factory `Linked List`, minting legitimate Factory, Liquidity Pool, Global Setting and Liquidity Pool `Share` Tokens #### 3.3.3.1 Parameter @@ -203,21 +204,22 @@ Authen Minting Policy is responsible for creating initial Factory `Linked List`, - _out_ref_: is a Reference of an Unspent Transaction Output, which will only be spent on `MintFactoryAuthen` redeemer to make sure this redeemer can only be called once - -#### 3.3.3.2 Redeemer -- **MintFactoryAuthen** +#### 3.3.3.2 Minting Purpose +#### 3.3.3.2.1 Redeemer +- **DexInitialization** - **CreatePool** -#### 3.3.3.3 Validation - - -- **MintFactoryAuthen**: The redeemer can be called once to initialize the whole AMM V2 system +#### 3.3.3.2.2 Validation +- **DexInitialization**: The redeemer can be called once to initialize the whole AMM V2 system - validate that `out_ref` must be presented in the Transaction Inputs + - validate that the redeemer only mint: + - **a single Factory Token** + - **a single Global Setting Token** - validate that there's only 1 Factory UTxO in the Transaction Outputs. The Factory UTxO must contain Factory Token in the value and its datum is: - _head_: `#"00"` - _tail_: `#"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00"` - - validate that the redeemer only mint **a single Factory Token** + - validate that there's only 1 Global Setting UTxO in the Transaction Outputs. The Global Setting UTxO must contain Global Setting Token in the value. - **CreatePool**: The redeemer will allow creating a new Liquidity Pool. - validate that there's a single Factory UTxO in the Transaction Inputs. Factory UTxO must contain Factory NFT Token in the value - validate that transaction only mint 3 types of tokens: @@ -225,6 +227,24 @@ Authen Minting Policy is responsible for creating initial Factory `Linked List`, - 1 Pool NFT Token - MAX_INT64 LP Token, LP Token must have PolicyID is **AuthenMintingPolicy** and TokenName is Hash of Pool's Asset A and Asset B (`SHA_256(SHA_256(AssetA), SHA_256(AssetB))`). Asset A and Asset B are in Factory Redeemer and they must be sorted +#### 3.3.3.3 Spend Purpose +#### 3.3.3.3.1 Datum + - _batchers_: List of authorized batchers who can process orders + - _pool_fee_updater_: The actor who can update the Pool's base fee and fee sharing + - _fee_sharing_taker_: The actor who can withdraw the Pool's fee sharing + - _pool_stake_key_updater_: The actor who can change the Pool's stake key + - _pool_dynamic_fee_updater_: The actor who can update the Pool's dynamic fee + - _admin_: The actor who can update the addresses mentioned above. This admin can be transferred to another wallet and should be stored in the most secure location + +#### 3.3.3.3.2 Redeemer +- **Nothing** + + +#### 3.3.3.3.3 Validation + - validate transaction has to be executed by the Whitelisted Admin. + - Both Global Setting input and output must have the same payment credential and keep the Global Setting Token + - validate authorized batchers must not be empty + - validate transaction won't mint anything #### 3.3.4 Factory Validator @@ -288,8 +308,10 @@ Anytime new Pool is created, a Factory UTxO will be spent can create the 2 new o - _asset_a_ and _asset_b_ must be the same with Factory Redeemer - _total_liquidity_ must be sqrt(_amount_a_ * _amount_b_) - _reserve_a_ and _reserve_b_ must be _amount_a_ and _amount_b_ - - _trading_fee_percentage_ must be between **0.05%** and **10%** - - _profit_sharing_ must be empty + - _base_fee_a_numerator_ and _base_fee_b_numerator_ must be the same + - _base_fee_a_numerator_ and _base_fee_b_numerator_ must be between **5** and **2000** + - _fee_sharing_numerator_opt_ must be empty + - _allow_dynamic_fee_ must be False - Pool Value must only have necessary Token: Asset A, Asset B, remaining LP Token (_MAX_INT64_ - _total_liquidity_), 1 Pool NFT Token and 3 ADA (required ADA for an UTxO) - validate that transaction only mint 3 types of tokens: - 1 Factory NFT Token @@ -310,42 +332,85 @@ Pool validator is the most important part in the system. It's responsible for gu #### 3.3.5.2 Datum +- _pool_batching_stake_credential_: Stake Credential of `Pool Batching` validator - _asset_a_: The Pool's Asset A - _asset_b_: The Pool's Asset B - _total_liquidity_: Total Share of Liquidity Providers - _reserve_a_: Asset A's balance of Liquidity Providers - _reserve_b_: Asset B's balance of Liquidity Providers -- _trading_fee_numerator_: Numerator of Trading Fee -- _trading_fee_denominator_: Denominator of Trading Fee -- _profit_sharing_opt_: (Optional) Numerator and Denominator of Profit Sharing percentage, this is the percentage of Trading Fee. (eg, Trading Fee is 3%, Profit Sharing is 1/6 -> Profit Sharing = 1/6 * 3%) - +- _base_fee_a_numerator_: Numerator of Trading Fee on Asset A side +- _base_fee_b_numerator_: Numerator of Trading Fee on Asset B side +- _fee_sharing_numerator_opt_: (Optional) Numerator of Fee Sharing percentage, this is the percentage of Trading Fee. (eg, Trading Fee is 3%, Profit Sharing is 1/6 -> Profit Sharing = 1/6 * 3%) +- _allow_dynamic_fee_: allow Batcher can decide volatility fee for each batch transaction #### 3.3.5.3 Redeemer - - **Batching**: - - _batcher_address_: Address of Batcher - - _input_indexes_: The Indexes of Orders are processing (it will be explained below) - - _orders_fee_: The list of batcher fee will be deducted from orders' fund. Batcher can decide the amount of fee for each orders. The Batcher Fee can not exceed the maximum batcher fee. - - _license_index_: Index of the UTxO holding Batcher License Token in the Transaction Inputs. - - **MultiRouting**: - - _batcher_address_: Address of Batcher - - _license_index_: Index of the UTxO holding Batcher License Token in the Transaction Inputs. - - _routing_in_indexes_: Indexes of Pool UTxOs in the Transaction Inputs - - _routing_out_indexes_: Indexes of Pool UTxOs in the Transaction Outputs - - _order_fee_: Batcher fee will be deducted from orders' fund. Batcher can decide the amount of fee for each orders. The Batcher Fee can not exceed the maximum batcher fee. - - **UpdatePoolFeeOrStakeCredential**: + - **Batching** + - **UpdatePoolParameters**: - _action_: There are 2 actions in this redeemer. - - _UpdatePoolFee_: Allow Admin to update Liquidity Pool's fee (Trading Fee and Profit Sharing). + - _UpdatePoolFee_: Allow Admin to update Liquidity Pool's fee (Trading Fee and Fee Sharing). + - _UpdateDynamicFee_: Allow Admin to enable/disable Liquidity Pool's dynamic fee. - _UpdatePoolStakeCredential_: Allow Admin update Pool's Stake Credential. It allows Minswap can delegate Liquidity Pool's ADA to different Stake Pools - - _admin_index_: Index of the UTxO holding Admin License Token in the Transaction Inputs. - - **WithdrawLiquidityShare**: - - _admin_index_: Index of the UTxO holding Admin License Token in the Transaction Inputs. + - **WithdrawFeeSharing** #### 3.3.5.4 Validation -- **Batching**: This redeemer will be called on Batching Transaction. It can process all types of Orders except **SwapMultiRouting** Order - - validate batcher with valid License Token must be presented in Transaction Inputs: - - Batcher must sign a Batching transaction. - - A valid license token is the token having expired timestamp as TokenName and must be within current time and current time + _maximum_deadline_range_ +- **Batching**: validate that a Pool can be spent if there's a `Pool Batching` validator in the `withdrawals` +- **UpdatePoolParameters**: Allow Whitelisted Authorizers update Liquidity Pool's fee (Trading Fee and Fee Sharing), enable/disable Dynamic Fee or update Pool's Stake Credential. It allows Minswap can delegate Liquidity Pool's ADA to different Stake Pools + - transaction has to include Global Setting UTxO in the first element of Transaction reference inputs + - validate transaction has to be executed by the authorizers. + - validate there is a single Pool UTxO in Transaction Inputs and single Pool UTxO in Transaction Outputs and: + - Pool Input contains 1 valid Pool NFT Token + - Pool Input and Output Value must be unchanged + - Transaction contain only 1 Spending Script (Pool Script). It will avoid bad Admin stealing money from Order Contract. + - validate Transaction won't mint any assets + - Each **UpdatePoolParameters** action has limited power to change some of Pool's parameters and stake address. Otherwise, it's not allowed + - _UpdatePoolFee_: + - Update _base_fee_a_numerator_, _base_fee_b_numerator_ and the new value must be between **5** and **2000** + - Update _fee_sharing_numerator_opt_ is None or Some and the new value must be between **1666** and **5000** + - Pool Address must be unchanged (both Payment and Stake Credential) + - _UpdateDynamicFee_: + - Update _allow_dynamic_fee_ value to True or False + - Pool Address must be unchanged (both Payment and Stake Credential) + - _UpdatePoolStakeCredential_: + - Update Pool's Stake Credential to any other Stake Address +- **WithdrawFeeSharing**: Allow Whitelisted Fee Sharing taker can withdraw Liquidity Share to any Addresss. + - transaction has to include Global Setting UTxO in the first element of Transaction reference inputs + - validate transaction has to be executed by the Whitelisted Fee Sharing. + - validate there is a single Pool UTxO in Transaction Inputs and single Pool UTxO in Transaction Outputs and: + - Pool Input contains 1 valid Pool NFT Token + - Pool Input and Output Address must be unchanged (both Payment and Stake Credential) + - Pool Datum must be unchanged + - Transaction contain only 1 Spending Script (Pool Script). It will avoid bad Admin stealing money from Order Contract. + - validate Transaction won't mint any assets + - validate Admin withdraws the exact earned Fee Sharing amount: + - Earned Asset A: Reserve A in Value - Reserve A in Datum + - Earned Asset B: Reserve B in Value - Reserve B in Datum + - validate Pool Out Value must be Pool In Value sub Earned Asset A and Earned Asset B + +#### 3.3.6 Pool Batching Validator + +Pool Batching validator is the sub logic of `Pool Validator`, it will ensure Batching transaction executing Orders in the correct way and Liquidity Providers' funds cannot be stolen in any way. + +#### 3.3.6.1 Parameter + +- _authen_policy_id_: The PolicyID of `Authen Minting Policy` +- _pool_payment_cred_: Payment Credential of `Pool Validator` + +#### 3.3.6.2 Redeemer + +- _batcher_index_: Index of the the batcher in authorized batchers list. +- _license_index_: Index of the UTxO holding Batcher License Token in the Transaction Inputs. +- _orders_fee_: Batcher fee will be deducted from orders' fund. Batcher can decide the amount of fee for each order. The Batcher Fee can not exceed the maximum batcher fee. +- _input_indexes_: The Indexes of Orders are processing (it will be explained below) +- _pool_input_indexes_opt_: The Indexes of Pools are processing (it will be explained below) +- _vol_fees_: The Volatility Fee for each Pool. Batcher can charge more fee to each batch through off-chain calculation and it's only affected if Pool enables `allow_dynamic_fee`. + +#### 3.3.6.3 Validation + +Batching validation has 2 scenarios: +- **Batching 1 Pool**: It can process all types of Orders except **SwapMultiRouting** Order + - transaction has to include Global Setting UTxO in the first element of Transaction reference inputs + - validate transaction has to be executed by the Whitelisted Batcher. - validate _input_indexes_ must not be empty and be unique list - validate Transaction won't mint any assets - validate there is a single Pool UTxO in both Transaction Inputs and Outputs and must have the same Address (both Payment and Stake Credential) @@ -363,12 +428,11 @@ Pool validator is the most important part in the system. It's responsible for gu - All amount fields in Order Step must be positive - _batcher_fee_ must be positive - _lp_asset_ in **OrderDatum** must be the same with processing Liquidity Pool - - Order Output must be returned to _receiver_ and might have _receiver_datum_hash_opt_ - - Order Output value must satisfy the condition of [description in Order Datum](#3322-datum) -- **MultiRouting**: This redeemer will be called on MultiRouting Transaction. It will process single **SwapMultiRouting** Order and multiple **Liquidity Pool** - - validate batcher with valid License Token must be presented in Transaction Inputs: - - Batcher must sign a Batching transaction. - - A valid license token is the token having expired timestamp as TokenName and must be within current time and current time + _maximum_deadline_range_ + - the destination output must be returned to _refund_receiver_ + _refund_receiver_datum_ if the order is killed by batcher or _success_receiver_ + _success_receiver_datum_ if the order is processed + +- **Batching Multiple Pools**: It will process single **SwapMultiRouting** Order and multiple **Liquidity Pool** + - transaction has to include Global Setting UTxO in the first element of Transaction reference inputs + - validate transaction has to be executed by the Whitelisted Batcher. - validate _routing_in_indexes_ and _routing_out_indexes_ must be unique, have the same length and contain more than 1 element. - validate Transaction won't mint any assets - validate the number of Pool Inputs and Pool Outputs must be _routing_in_indexes_ length. and each Pool Input must have the same Address with Pool Output (both Payment and Stake Credential) @@ -383,49 +447,12 @@ Pool validator is the most important part in the system. It's responsible for gu - All amount fields in Order Step must be positive - _batcher_fee_ must be positive - _lp_asset_ in **OrderDatum** must be the same with LP Asset of first Liquidity Pool in routing list - - Order Output must be returned to _receiver_ and might having _receiver_datum_hash_opt_ - The number of Pool Inputs and Pool Outputs must be the same with _routings_ length - - Calculated Asset Out must be returned to _receiver_ - - Order Output value must satisfy the condition of [description in Order Datum](#3322-datum) -- **UpdatePoolFeeOrStakeCredential**: Allow Admin update Liquidity Pool's fee (Trading Fee and Profit Sharing) or update Pool's Stake Credential. It allows Minswap can delegate Liquidity Pool's ADA to different Stake Pools - - validate Admin with valid Admin License Token must be presented in Transaction Inputs - - validate there is a single Pool UTxO in Transaction Inputs and single Pool UTxO in Transaction Outputs and: - - Pool Input contains 1 valid Pool NFT Token - - Pool Input and Output Value must be unchanged - - Transaction contain only 1 Script (Pool Script). It will avoid bad Admin stealing money from Order Contract. - - validate Transaction won't mint any assets - - Both **UpdatePoolFeeOrStakeCredential** _action_ must not change these fields on the Pool Datum: - - _asset_a_ - - _asset_b_ - - _total_liquidity_ - - _reserve_a_ - - _reseve_b_ - - Each _action_ must be followed: - - _UpdatePoolFee_: - - Trading Fee must be between **0.05%** and **10%** - - Profit Sharing can be on/off by setting _profit_sharing_opt_ is None or Some. Profit Sharing must be between **16.66%** and **50%** - - Pool Address must be unchanged (both Payment and Stake Credential) - - _UpdatePoolStakeCredential_: - - Trading Fee and Profit Sharing must be unchanged - - Pool's Stake Credential can be changed to any other Stake Address -- **WithdrawLiquidityShare**: Allow Admin can withdraw Liquidity Share to any Addresss. - - validate Admin with valid Admin License Token must be presented in Transaction Inputs. - - validate there is a single Pool UTxO in Transaction Inputs and single Pool UTxO in Transaction Outputs and: - - Pool Input contains 1 valid Pool NFT Token - - Pool Input and Output Address must be unchanged (both Payment and Stake Credential) - - Pool Datum must be unchanged - - Transaction contain only 1 Script (Pool Script). It will avoid bad Admin stealing money from Order Contract. - - validate Transaction won't mint any assets - - validate Admin withdraws the exact earned Profit Sharing amount: - - Earned Asset A: Reserve A in Value - Reserve A in Datum - - Earned Asset B: Reserve B in Value - Reserve B in Datum - - validate Pool Out Value must be Pool In Value sub Earned Asset A and Earned Asset B - - + - the destination output must be returned to _refund_receiver_ + _refund_receiver_datum_ if the order is killed by batcher or _success_receiver_ + _success_receiver_datum_ if the order is processed ### 3.4 Transaction -### 3.4.1 Initialize Factory Linked List +### 3.4.1 Dex Initialization AMM V2 requires a Factory Linked List, and the initial Linked List contains 1 element with head `#"00"` and tail `#"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00"`. @@ -439,8 +466,10 @@ Transaction structure: - an UTxO which is defined in Authen Minting Policy (see @out_ref of AuthenMinting Policy in Section 3.3.3.1) - Mint: - Script Authen Minting Policy: - - Redeemer: MintFactoryAuthen - - Value: 1 Factory NFT Asset + - Redeemer: DexInitialization + - Value: + - 1 Factory NFT Asset + - 1 Global Setting NFT Asset - Outputs: - a Factory UTxO: - Address: Factory Address @@ -450,6 +479,18 @@ Transaction structure: - Value: - minimum ADA - 1 Factory NFT Asset + - a Global Setting UTxO: + - Address: Authen Minting Address + - Datum: + - batchers + - pool_fee_updater + - fee_sharing_taker + - pool_stake_key_updater + - pool_dynamic_fee_updater + - admin + - Value: + - minimum ADA + - 1 Global Setting NFT Asset - Change UTxOs @@ -507,14 +548,15 @@ Transaction structure: - 1 Pool NFT Asset - LP Asset (followed by OnChain calculation) - Datum: + - pool_batching_stake_credential - asset_a: Token A (2) - asset_b: Token B (3) - total_liquidity: Followed by OnChain calculation - reserve_a: x (4) - reserve_b: y (5) - - trading_fee_numerator: Followed by OnChain validation - - trading_fee_denominator: Followed by OnChain validation - - profit_sharing_opt: None + - base_fee_a_numerator: Followed by OnChain validation + - base_fee_b_numerator: Followed by OnChain validation + - fee_sharing_numerator_opt: None - Change UTxOs @@ -524,7 +566,7 @@ Transaction structure: Create Order transaction will transfer User funds into an Order UTxO. -Besides common information such as _sender_, _receiver_, etc, each order type requires different information in _step_ field (note that we only mention _field name_ here, the fields' descriptions have been explained above) +Besides common information such as _canceller_, _refund_receiver_, etc, each order type requires different information in _step_ field (note that we only mention _field name_ here, the fields' descriptions have been explained above) Transaction structure: @@ -533,9 +575,11 @@ Transaction structure: - Order UTxOs (a single transaction can create multiple orders) - Address: Order Address - Datum: - - _sender_ - - _receiver_ - - _receiver_datum_hash_ + - _canceller_ + - _refund_receiver_ + - _refund_receiver_datum_ + - _success_receiver_ + - _success_receiver_datum_ - _lp_asset_ - _batcher_fee_ - _expired_setting_opt_ @@ -633,6 +677,11 @@ Transaction structure: - Value: - _batcher_fee_ + additional ADA to cover output (if need) - Token is swapping + - _Donation_: + - Step: Nothing + - Value: + - _batcher_fee_ + - Token A and Token B - Change UTxOs @@ -646,13 +695,17 @@ It requires a Pool UTxO, Batcher UTxOs (must include Batcher License Token) and Transaction structure: + - Reference Inputs: + - Global Setting UTxO: + - Address: Authen Minting Address + - Value: + - ADA + - 1 Global Setting License Token - Inputs: - Order UTxOs (see Section 3.4.3) except _SwapMultiRouting_ Order - Batcher UTxO - Address: Batcher Address - - Value: - - ADA - - 1 Batcher License Token (which is not expired) + - Value: Batcher value - Pool UTxO - Address: Pool Address - Value: @@ -662,18 +715,16 @@ Transaction structure: - LP Token - 1 Pool NFT Token - Datum: + - _pool_batching_stake_credential_ - _asset_a_ - _asset_b_ - _total_liquidity_ - _reserve_a_ - _reserve_b_ - - _trading_fee_numerator_ - - _trading_fee_denominator_ - - _profit_sharing_opt_ + - _base_fee_a_numerator_ + - _base_fee_b_numerator_ + - _fee_sharing_numerator_opt_ - Redeemer: Batching - - _batcher_address_ - - _input_indexes_ - - _license_index_ - Outputs: - a Pool Output - Address: Pool Address (unchanged) @@ -684,17 +735,18 @@ Transaction structure: - LP Token - 1 Pool NFT Token - Datum: + - _pool_batching_stake_credential_ (unchanged) - _asset_a_ (unchanged) - _asset_b_ (unchanged) - _total_liquidity_ - _reserve_a_ (followed by OnChain calculation) - _reserve_b_ (followed by OnChain calculation) - - _trading_fee_numerator_ (unchanged) - - _trading_fee_denominator_ (unchanged) - - _profit_sharing_opt_ (unchanged) + - _base_fee_a_numerator_ (unchanged) + - _base_fee_b_numerator_ (unchanged) + - _fee_sharing_numerator_opt_ (unchanged) - Order Outputs: - - Address: _receiver_ - - DatumHash: _receiver_datum_hash_opt_ + - Address: _success_receiver_ + - Datum: _success_receiver_datum_ - Value: - _SwapExactIn_: - Value: @@ -738,9 +790,11 @@ Transaction structure: - remaining swapping Token and received Token - Create new _PartialSwap_ Order if _hops_ > 1 and remaining Swapping Token is greater than _minimum_swap_amount_required_ - Datum: - - _sender_ (unchanged) - - _receiver_ (unchanged) - - _receiver_datum_hash_ (unchanged) + - _canceller_ + - _refund_receiver_ (unchanged) + - _refund_receiver_datum_ (unchanged) + - _success_receiver_ (unchanged) + - _success_receiver_datum_ (unchanged) - _lp_asset_ (unchanged) - _batcher_fee_ (unchanged) - _step_: _PartialSwap_ @@ -753,9 +807,19 @@ Transaction structure: - Value: - _batcher_fee_ * (_hops_ - 1) + change in ADA - remaining swapping Token and received Token + - Donation: No Output - Batcher Change UTxOs - + - Withdrawal: + - Pool Batching Withdrawal: + - Amount: 0 + - Redeemer: PoolBatchingRedeemer + - batcher_index + - license_index + - orders_fee + - input_indexes + - pool_input_indexes_opt + - vol_fees ### 3.4.5 Multi Routing @@ -763,6 +827,12 @@ Transaction allows an _SwapMultiRouting_ Order is processed through multiple Liq Transaction structure: + - Reference Inputs: + - Global Setting UTxO: + - Address: Authen Minting Address + - Value: + - ADA + - 1 Global Setting License Token - Inputs: - Order UTxO (see Section 3.4.3) - Pool UTxOs @@ -774,24 +844,19 @@ Transaction structure: - LP Token - 1 Pool NFT Token - Datum: + - _pool_batching_stake_credential_ - _asset_a_ - _asset_b_ - _total_liquidity_ - _reserve_a_ - _reserve_b_ - - _trading_fee_numerator_ - - _trading_fee_denominator_ - - _profit_sharing_opt_ - - Redeemer: MultiRouting - - _batcher_address_ - - _license_index_ - - _routing_in_indexes_ - - _routing_out_indexes_ + - _base_fee_a_numerator_ + - _base_fee_b_numerator_ + - _fee_sharing_numerator_opt_ + - Redeemer: Batching - Batcher UTxO - Address: Batcher Address - - Value: - - ADA - - 1 Batcher License Token (which is not expired) + - Value: Batcher value - Outputs: - Pool Outputs: - Address: Pool Address (unchanged) @@ -802,33 +867,44 @@ Transaction structure: - LP Token (unchanged) - 1 Pool NFT Token - Datum: + - _pool_batching_stake_credential_ (unchanged) - _asset_a_ (unchanged) - _asset_b_ (unchanged) - _total_liquidity_ (unchanged) - _reserve_a_ (followed by OnChain calculation) - _reserve_b_ (followed by OnChain calculation) - - _trading_fee_numerator_ (unchanged) - - _trading_fee_denominator_ (unchanged) - - _profit_sharing_opt_ (unchanged) + - _base_fee_a_numerator_ (unchanged) + - _base_fee_b_numerator_ (unchanged) + - _fee_sharing_numerator_opt_ (unchanged) - Order Output - Address: _receiver_ - - DatumHash: _receiver_datum_hash_opt_ + - Datum: _receiver_datum_ - Value: - change in ADA - Received Token (must be greater than or equal to _minimum_receive_) - Batcher Change UTxOs + - Withdrawal: + - Pool Batching Withdrawal: + - Amount: 0 + - Redeemer: PoolBatchingRedeemer + - license_index + - orders_fee + - input_indexes + - pool_input_indexes_opt + - vol_fees -### 3.4.5 Update Pool Fee Or Stake Credential +### 3.4.5 Update Pool Parameters Transaction structures: - - Inputs: - - Admin UTxO: - - Address: Admin Address + - Reference Inputs: + - Global Setting UTxO: + - Address: Authen Minting Address - Value: - ADA - - 1 Admin License Token + - 1 Global Setting License Token + - Inputs: - Pool UTxO: - Address: Pool Address - Value: @@ -838,42 +914,46 @@ Transaction structures: - LP Token - 1 Pool NFT Token - Datum: + - _pool_batching_stake_credential_ - _asset_a_ - _asset_b_ - _total_liquidity_ - _reserve_a_ - _reserve_b_ - - _trading_fee_numerator_ - - _trading_fee_denominator_ - - _profit_sharing_opt_ - - Redeemer: UpdatePoolFeeOrStakeCredential + - _base_fee_a_numerator_ + - _base_fee_b_numerator_ + - _fee_sharing_numerator_opt_ + - Redeemer: UpdatePoolParametersAction - _action_ - - _admin_index_ - Outputs: - Pool Output: - Address: if _action_ is: - _UpdatePoolFee_: unchanged + - _UpdateDynamicFee_: unchanged - _UpdatePoolStakeCredential_: only change Stake Credential - Value: (unchanged) - Datum: if _action_ is: - _UpdatePoolFee_: only change: - - _trading_fee_numerator_ - - _trading_fee_denominator_ - - _profit_sharing_opt_ + - _base_fee_a_numerator_ + - _base_fee_b_numerator_ + - _fee_sharing_numerator_opt_ + - _UpdateDynamicFee_: only change: + - _allow_dynamic_fee_ - _UpdatePoolStakeCredential_: unchanged - Admin Change UTxOs -### 3.4.6 Withdraw Liquidity Share +### 3.4.6 Withdraw Fee Sharing Transaction structures: - - Inputs: - - Admin UTxO: - - Address: Admin Address + - Reference Inputs: + - Global Setting UTxO: + - Address: Authen Minting Address - Value: - ADA - - 1 Admin License Token + - 1 Global Setting License Token + - Inputs: - Pool UTxO: - Address: Pool Address - Value: @@ -883,16 +963,16 @@ Transaction structures: - LP Token - 1 Pool NFT Token - Datum: + - _pool_batching_stake_credential_ - _asset_a_ - _asset_b_ - _total_liquidity_ - _reserve_a_ - _reserve_b_ - - _trading_fee_numerator_ - - _trading_fee_denominator_ - - _profit_sharing_opt_ - - Redeemer: WithdrawLiquidityShare - - _admin_index_ + - _base_fee_a_numerator_ + - _base_fee_b_numerator_ + - _fee_sharing_numerator_opt_ + - Redeemer: WithdrawFeeSharing - Outputs: - Pool Output: - Address: (unchanged) diff --git a/amm-v2-docs/formula.md b/amm-v2-docs/formula.md index abe8328..24552ed 100644 --- a/amm-v2-docs/formula.md +++ b/amm-v2-docs/formula.md @@ -58,7 +58,7 @@ $$swap_{x} = \left\lfloor \frac{\sqrt{((2 - f) * X)^{2} - (1 - f) * Y} - (2 - f) $$= \left\lfloor \frac{\sqrt{((2 * f_{d} - f_{n}) * X)^{2} - f_{d} * (f_{d} - f_{n}) * Y} - (2 * f_{d} - f_{n}) * X}{(f_{d} - f_{n}) * Z} \right\rfloor $$ The LP Token users receive is: -$$\Delta L = \frac{\Delta y + receive_{y}}{y_{0} - receive_{y}} * L$$ +$$\Delta L = \frac{\Delta x - swap_{x}}{x_{0} + swap_{x}} * L$$ ### 4. Withdraw $$\Delta x = \frac{\Delta L}{L} * x_{0}$$ diff --git a/amm-v2-docs/pics/architecture.png b/amm-v2-docs/pics/architecture.png index eb5b61573c3830bcb07e5f15ab8843775c297a00..42c34aaf9d82f6961ae326a25bd7ffe50022f1d0 100644 GIT binary patch literal 257384 zcmcG$byQVv)HN!IiYOgYf^>s`9O;q{0Z9RAMBpGL-6&nsacBfo`p}IuNGN^iP>}Af z`yA_if8Ozp@!db}7>wZ_M>zZ0Ppmc9oOA6U<;T*P7^E0iu3W*Cm63RI<;r!~l`Cju z=-0s~PAvFn;2#wGC(`0q3j4^HuUxrzMOH#g%~@|P<(jkF=wbOC?aAyT>_b$)`GNTj zf`IuAQr+O%+FF9j`Hc;|$?__K2J4gy2F$l_XlWA@1y%*Im3*oXlRc(Aa!q!gZ{pL+ z#V}H4P@z)a`~5>i`=v-<s@Z&FcVG?OYl8a4&F+u_Fk!T6JGxeP@Zu& zva9~yCaO&~!})(7==a4e8F-q8jBHEEKhK^V>}@jW1vel5s9xo`PD(8uej5Y!(0ZC! zOyc<4=v*RHyUK>DP`BE5v*8rW^mCjfxRFZkip?KXbMLz!*;p6tK8E;V z-6eerH{nDLb=zMp?#iK&4mape6?)F$ck7PS+E~fg_bN2W!XD!tsy8r62`Gi#x3>3d zz8r#ybnjPi`ezXXy}iKF?^tIhDgE6ohUhYoa|YOWxn+RI=|SS;P~kJO#`6QRq=(kw zS<(@i2A_Q2>(%ocwFdftXGr=;q2q_!CSUrz_bsojk)Y=pF^fii)7kOv_V$9bGd)bO zP_^uZ%B!_8+!7JFd3-=cJ>@$!O9GML~~ zfllR@0-cB4`o#vH6eKk+&W>#lH=g0^gWGb+_j{bseU_cSlkuoSg6W0$82I zg4n;Te!*6`rXg)|kxDh_Uq?q*J{nJwVRACQ`R=l<^RkjOn*>oVP z1rmjpqlNow5S4IpVfV34+=|UC@((Im{^lPlO}g*|U3So3-@t}E3CIi_@E5miesgoI z&V@VYaZ0dRe`=z`Q%p$`)kaSbRVv9y)pSu5nrD3}0yi`)IaA-<#80YXY7(sYnsxgY zAu~aaQrgRd=5xC=aIzl6%BAo-G}kz+7F&+8(+n|AFb3;2dY=11<>FWq&HF12KA|cb z^(Jt(^px9ums56Ev2a))AAaV~=@?u+RqF(+7MyUZbKX{{GkLTv#TQE}iwB*kz+4?I zl0Mv+vR&*U!N<@0!Z=5~`#GNDYqh-@bgG8XxIMIF?Q}GkEE>AQ#Pp2ezp>#SDvC6S zAG2c?&;Ld<0kD}*lpy=-6QgRK#drakzHD>du`Fiq@L6Dt9*hzLIf|BO*S}+5_H>iW zMX>2q+>;2zkt!>0es48Vk=jik!DM#I+f5yucu&mtp7o9bNa#~h=!V3O)K4KD&Hg(P}BIdt?(>?oC^23vC zF4O>VKd*il#tO!#W9{Li%Fgx9+w=H{R-WS!JHI7f7xD^-YraILpz(KtHmtl@cHOEi zKj{3iA~e2ZP6Y##gsZh|rF0zz4@2$Ef}Wg(ebR6PK|$(hYc6b7E}lIFS0%;Su@-0BBmsxsWG5>IF9t`&SGTQMl@%{+S2qd-o9E(4Q*b{u{Va#DC63tAIwvppd>Pe5-y7>5XAiFWWLh)(}OVRd`*l!RH?JHh?rr)=u}jbGD@-V0`0}+-v{`0 z5iSZ+EG|5q`0pa4z5&U5$qeH1=6oSSBx%GUe|(NlAzy3$SOU7-4zbO*tFd3gYLB3d z067xo=vGnTn%b2EG6^ZuBhDx;Q#l%Y=L?+dubYjRFF$_J3VVcTJ#ZFs-Me43eMZw= ztdb=~Qo?OLEolFIFosE0K|%2IdvQOE4XeEdbx4W!dyqeJhVL$9)XkAR(Mv&mizF$U zJ63^yzXO444H`wfCY1fQtl}S;sCl}0;jRt#I!iE%hCm77J>%j6l6%$^3`uJ6uAr!F z<-eKq*OMXlZWsK+aQoi}rG+)H!;WGInAJMfI+ZJQ>s<+rJHmN}<;j_zyt{8iV>{oP zLmIrk<)p7_C^5yRpy_k&|h@IbBaIEE#LI)z%TAfIplZeE4m_ioe0nMSWhT&QrQqM&q;TM#}& z_=lr;4h=8ca1e++sbN}}i^C1oB5B?9i~eBeDv~etrEr@Op6`$9vtLTZL+y^GMX&sQ zl3y3(-bmC%D@OGB{k*vxt3~B@txQ7m|sd_aqwwWXl)Y%ZTysPfgP_W&%v2 zhq?35gZ>LAd9Q*jW7ZjEMDQmfY~iD5#w!Yj1T9gRyUTeOtnYm5GG-3fD9|i(z&J-ZkT+ z{h}E}(e%eD{5gL5KfYurhBV;PNF~^3K1dD$&u0H!{%i1m$Eg(!KIhr}`0VfauPi2~ zfk6fNfxG$v==zkmdOYc$5ey{C5O1cmUF{aX#Zf?E@L2>)0+Q@SpvYkNn(~ zZ#ew#tY1WcdsAG)EfxlIwYsDw@OQ3$#ZVh}fa${1Xe1f`WT9DU@QEi{?u0~B5XkC$ zDsY02{|wC(Ib=xrc*5V$O`=l)a{vGJ9-`HD-_gX-B$}Gh9;XS1k@8qH_4f8Q*A9*R zec0a@P1|66e4gP18Gpw|dGnn@BHr2aGJo)q!_B?T8GU$H&GK;HKYyEyj4RQ!a)y7G z@F>-L{Ks)>;sy?i8BIFGwJ(mdjpff={i=NoB*Bbn^n5&^{qwm25)O&spsXV656|%O zM}ODw*F^^?DZU-?J$dst(0S5=Po!;X6w#8AbqPM5e8%4){5mRHao}@P)x5C3y9nHa zWLL_-ya z5HdYM1JINQrd@79h=lQE4_}U1M^EQZR$A*L0o`cfvqu2#sZ`sUdWG3Hd83S#nd6TX z>0fr$$wtwNfneNNqX*!+GC)3cUYFC8m-B76kT?sJ9qoCVMRlRW3um#+>f*j=H=DHF z1%mHzgagQu0g7V%$&=NhMry<6H=aqOm9{@ltZ76ML%B+ns%_xWGQ|D3qJ>@e&}F0P z&nvFIs{Fg*|6DX_g0tX37|D)<(t(5r#4hOX8EIjt!TF004yYGwFmOv>fc-PnK0LWz zP})h4L8aj?=y5WnPkFQN_+VXU_w&M57&I79w!eddm5w zi@lx)#c9Jd%p|%flJ6U4jN;c!$*a30TqZJy#0cSte*eEAPwpTF;GJ`%}@%t4#`A#T^!#43xLL=qeb}1 z@YEg#v3kpG_86HN0oZLD`k=~b+D!nm_H~fO+W?~Dv>aizSE_&_zNCv?eS?mRTKRHH z{PN;_du#5I+IwXbkk}wI1WSBepM0-90!wMT)OVM|DO%9Q?$yR5$qg)WQBW)62)jGq zzRN$<+GCwF`a$)E$mLmS^(82(iMdPyBRNvlA+|+z4Wd4%&(}c-XxN*?qXjn!LhOS5 z)+=bzV)@kc+whhaLajiXCx-nQsn_NCLog!WOv#X>?wq6T1>?n@#Eos2+jnoxlD1(rflo`oTZp zPojwg89I$e2ukHavVl8})BQOIU@7?QzTM|~|8lB^zUd}Dy}`j6B8M$m6COmp5+QOS z3hL5cp?v6kc?_xTLVFts1ED71*FqCRniq>2FT~q|3By`{3}oNxj$;b}ML5~9SfZqP zTW}WGyDm3_XIOKGGM)LHx6*O-Kyc?``!ROCP%f4^$72jsQ(;v#UY89YZto~SzIR1; z$fOgoX%piWo zT#EJ7r1LFG{`iqQDBy`H4_hYRVs^}adJUH7f!#M5nsunv38)h-5%BCtzbvUR@$ML= zuvaYl4T41Mx-SmgmIvrsLrDhL5{J#N-6DDwuSj6p!%~!GGEXAHpp+T|h0jckcCffP zJO_0dZ}RsZ`Yw9PT-`hWL~`DHAZXoC2o}df=?9zt>1j1`sy)jEPH~U4O;rJ=n3^b3 zflk)DjjGWfOF_zCPK~R5vdP!0AMebg^gQ|$cuNCeqa3rv6HFx+mgaeK^X1Ezi#**p z8tmIWBt_Rv@vmX@hs+yD4uC+a__+X3M04|PAvqs|Y3vt!a-ssnKXW5m9hjam8bC`_ zo}BM|=Ab8%V=a_+%zt%qw4D`ii!j0G1AjH_p%m(~bkAcw^nJgn>fVp9iey3>HY(^U zYbBW>!`kE(awULFaAAfqb~4t063C#?%yg*KtUt7D-iwK#nn6P@va$o>DmWOtehSsC zB4SBXLzpxk7Aa{SFv6gR#ob|MyxZqu%LELM$MvVWA5I4if9!h~Y7OEUX$PyPx20dORLr9d^FSKJ`9dPu= zXNj;F{bnrL^icUKJ(DGNfxR8i$R zo5#uCkD(9IAMP6yjw1;@r_E_46Z{E0xZ(^rB~znDw?w<>J1)K6n8CYDxm| z7PiPDp>{_EOrrlJGHYZs-TpsD(|kumGQQO8)^0!m@e|96AtcPjN@$5Mt9ZnnZ!gB?1gzc@drBPZU>EwxujRFZZ^wc5G zs_oj)$*?r=OW;AVBG6Ax$2+F>srZNzp;V_9dYD#qn+5%ZC)gD)ndRK6VZtJ%T??); zUioT9ZMZk`3Z12f)4VR0O-=DxvY?}?-X+@WfLB?BGRxge{oJbi#Kr~06pvh`G{+*S z(JhH!4CG|YggU{ywzDod#6kA&jx+j)j{@v70HinnCUp^irr+SILA*%-(b`R&+SM{* znIC7!gOg|BtkIv$XWt}uC)Kdk-h)wv(QmrW#dv(KBxMTZ=1G=B;UcK(_PifoV^H(_ z$^L52_yyr-|_mP zM)GwaGZ}%Tb#%JfC={y*o$3f?)v&hpkV6lqv!kNiNHNnxphZc8^0Gv?+Ai_H3-IPV z!|EXTM?>v=FF%7wE*3?Q`3DO8K2_h5;9a zo&u*0gT>HsZOpKbJo8m%v4O)EKwcD^^-~Ob7I>bYRDoC=soWJs$Gya<;_j@0kT{mG zZL#;_z0)?dHP>Q$c4RB^nI0nINA~~VC9dgWAg`6PLmgazo87*B2 z+6gfR6wHSD;~1sSacnKYge;+NPR5J7=yl{9@#y5dGsD)8oG);a+ zDP7*(XG|C`GdJ$jnm5pe@X0)tNmK{q`5;DQ$<_%tXf#&iW%O8FOUFv&$*)nvQA3)8 zTC$+?)v7VUb@9W>fX$Q|dap92bJa7HuL`CFbi@<%7Fq#d zD>~SHNcn?;f3F5F2e|1{Zwj>&ClYWzuKJ6GV@;w9q8RR(!-ej#q-s|{N#1@&JDC*o zMY9!&4q3uNRsD; zx!Z+D>6=H8a9_uzmbhPlW@V;~==0x!_JL?_xG`Dn`HcO`MhG4qMvfxP-+rl y#c zwnZD%1NpH^>r#Ih_1`KC9}+T{O%s&g`Ux2Z{z8UiSqLH`N`nYxi5@_^$z#>Me`a_D zAX1YsL5n-=KMMlcxIbwSlg0#;NX@T^S5GM0D$iE_AGNyrn9g*@RXOfb94DBRsR z%2tufx=UZFvreiri68SROPwj4%rB?h7jjQsRHxd@-%_hzFS8my3*n=dLgjx&_NKXw zg~~4GN0rMt2Wv7nk+FYRv&f~pN7n<9)|S?%WRXJ8c8c`L(KSKNK{a8Ui$ZEPTwSp5!X}c(yFg9!1u_n5ybxxFV!8S_x-*@kQxyey0Du zNwgRKusih@hfhK-(^sm}^f{Kbyz<4t-*jTa{@c=QVBshZ!X(D7&kt1AHN zKDs#F-2T>uk0hp%q6-LW4NMyi9;ZgDBL!NGp7m*qL1Yivou3Z@2|)!MBU+iaO%vx@ z+sE7Zy!z9$h;Q-+HM;*@bWt=^K;)=i5gm@9#=${bV}d`1U_z%v8FSp? z{}}%{I9cS5WX){^&Q7gz;9Uk3K&|`bI0PqJ(Ce70#=PLX|7r~{S;YP}r*WI4pOIf= zkus!epE&F-Rbxvz%bhPdvM!VLyV&A>sQ%$8!D;XdU)aNo<}Tw?T;^8^9L%t84c6;=FT2rNIFU3mzt|y;VW9uAQ!% z?Rs>yP2&iC_F6B6KcTvR#x+>w5r3BLXT2j%7lJxh5*)-eP$T*0JtqX*l(pM+M!PsR z9e<#!c}z%L@x6{2j7{N%I>*9&q6Xoy7(xd$_a{&X*#Np+}g<=y?iSJIbP=k5&+r5DY}0P+zaGZ5;3=6$3+)K zJ%~}Xo%e5sW11=RYKlLwp15H>(;$`hvR)BZJ9761&1i(m_7=*QQZLFkH_5Qplge%4 z6>(`KKXoe-$bBz9ix9!3d9DliMWets$ssTEl^@7wtd!yb zhWi7yAw-66r458O~?2@KTI3D>PQCdDU_#QWDyz zHvnv(abDsxSktJ9D#)KmRfL?^<_h35MFBm|`Ra!1BQu$NJQW*_lGb6Iy6F@a`t#YiG>S>>&ePP`z{ezE?=(3cSNX0W_r* zy+qY|R|f)i-Lb%Zz;+t-ByiGS2z#8&0*EFPO^^9oCCmi8K#m-XSzmIM>;6Xs$I^j? z^3hO{{)|j4QojVy@o47qA|U*(z&x@B0ucIZor}H6=QvCxExtWn<8TW|a~&-K*tnox zwg+j;yq6!8Y!B@Lnu3S89O+U>hLe*ZiyPJi$_ezl{0}gQSObUiG_yd;_m>}dCtCv2 zax_a3Z)-5&t*IJ^t4nkd_YIp3TKqBn(==^0e;2sh02Ppd0{1rhkk=nC0QcIF+m74i zh0sX;)7JoD)o4N_194EE)w~irJK9#ny2GYzaxgcz)KNY&tiPcLmsNW650*e51G;te zxqUjiM3Xccsy3wend24f8Bf=S0l1{h2u!>RVYF z*}>1Tt3CU?Q?KSwTgTnrfHR4=c50P>r;cjFFwW#7|>UmZ0C6bCcU_zNf2&SlH(1&RY9pnEx%a2;=o`m$ZDH ztjC0BPts%D@?CaJ#Tzs1L!qSnjFxeOP(IH~$M>~sqay?=W*09$uY zCH2fT(j;2HYgrg~D-~=~{Kje#z$lcN54LyS2`1F&21Ps}*kq3YWAmlVT(!>gd>sAF z>EWg^&?FN$js1_yZ5O0y)R5`}z%!&7^U)AjsQe+2o(#Z#4Uy%m;FnB0!i=Jh!oq z5u2p^PPp)nVBY;qsO>3;R=QO-pIQ?|ygaSNR1;JzRH#)vOQ?SU6<2B_ zlxMapW#{A;FPq=Jd-&NtaoY`J@O^Jzjr8MY(# zX>+L~jZx&W9FYK<3R88H7i{CJz<&VY%Slh-wapAl>G#*Pjc3y#Dz_Yk@Bxk}vWuh* zFIxj3x?b)UAU|5|Re1#~217Qiz*bw_mx-i4{&D>E^gqB>o!FVp&ba7mYjr5-Fz!2Cy!jG;e z1z)Yyxb(yySuiji+-Vyu_UeD`tXt_a@mwZ`c9@|g99GfSnUffDabNv0hrZxL)oV9N z(XcmXBN%(0Ditv z%`jCO2-viTWbSnr0S^e-QwiDj`jUYlLWLN){LYfzHfF|+*E=E9uZI=#NoyR}lW=v& z^M^j@R>Ol{!-MQPHJ-Iud_;=X7Hnyq^nLx^^ba3Ca$W~E9svKaxXv>h; z?ttmnz*SP?oYUM58QZWvoeSuU=OF^R-qnazxTJonJKf}HuRgDUD`vuTlfl`qG`0tO zxQ7lx>{19dL2EqS>a)s-oo}Ndw6HU|$A>}QhiIUl)$)5}ZcGMEY(H=zxR&2;cC2{CVM&XgDj;Bu5(409QU(0~J*lTAL+ zp)#xNzva-K0=zPPGVI+1?d={m#neH*q42<13BVd~M+FSfJFE6Rj57Tq zP$CV1`{p^;L>fsn;0>|~S$sM>7Gx6cXP66h67y-*w;Vk^HYS@i26t0%z}Fdx#JsU& z0^lk!C>~#Nw+;}<#%P~%>MK<~irT5N zwOYK#h$TyxuML0RkV%)9X%uvZPU&L?Noh+>S#5l)_{kSV{&Ld)PXDFUVR*Uidbh_r znH2P^{{1bV&L_T9E4sat**^!YjGI>339n}t`Bm(V%h$GpW{DqJyK{Uc?K2!Y#27Un zuxL%H6=+BfK6y*15v3^XD(Dc2&dZ7d4os?!i9ko-(uOiS0gFaYnSCu%M&}_H)DJT9 z&kO>ZH*Y56tic3N>ZevBJFv)al2Bm_W(RcqezOzX}8Tuj1alfZP=U0I%>3*!fpxI|gg0u#dv+~=L%5|3xAFhaj075Hr zs9#6L8*;t2brtq)e(*3FTqVt+c9F09iFW}fQh6B*P-qxz16cO{>#4Xz>QQMAc;eB~ z?)iAfDgG(1jBb1nzVN2-U@#nd+ox4&K_>p@3S><<+*2rtTFgxk-1_jmnq0pZcsU zad%IvHVQTcuXj{`dm5OpLQSU{*5^1ZaDHr;QsFQu!aIqo5c~0otk|qW5sNf&dF3OK=xz zC{5DLOqSXh{m@!(_Y}Cd7QiW8Oair0QfZL09{zW{HUgdTFr-Oq9ZC6iz=H@?p>uZx z9HI77cq}es!QtwP(0wVx77KDYG94IiMMIXB%jHFVb!tm4JZOpR{9wXbs<~K^Qs-KO z+hLy?o(mleF#bkw(EY*+%G1oujcbK>3_?UIR%lp)?`voRD@G)ZG-Qo2s!+f2B{N*h zLDDmy{c|i!Jg#MoTK+h{<61(c8HAHa1D%jVkNov@OfEC!?K8%Wua12qOI)1-Sov7S z;Y`@7*>a{kj}Q*CO(+}-2ah4!bsUSqOG+++r9p%yG1?}rX5oCV&#d14?UTmbzRPWsrqXD}jZ{GwU!dv?q6>DH^_#wRA_tVYSzp6^ zP443quFqSD^tZdrFG1AIQAkv<6ifARxHxk`R?3|$soav0$3W2=ta;myyDR=Y-?=oX z)!Ri=%UT0y?%&k}{yAMX!eDCq;<+W)GSSG@A=xsqb0H8X_M}Yf@d}f{hjW9y)U$NR z$fJRcWVMu;p6C_3u3Vg-Ht0D4(Phy+i$$~W=tOVo9;ya7rY3Fq7E1r5)jlauKO(qt zoSz|8<8oCFgvt7uh0_7eEI#5}v>ff_v=1=tOdv|u$@BD)D$oTT;JO%qy#B}9`Rn3; z%&oIDsNsw-cY-SR9bBKFh4D53S2p-ZAS_5zwfzvMTj{uKyudli5 zARavLAqGw~6rfK4o1auVL+H}I61HTs*9BW+2ag}2t%-qQQVf;n{99MJ18o^uZt&g& zpn*X)hO$M?G@A0$af=l;rSOBL(id9M0GUVgI28a>g(Z@YDR8%}{AUuvkwrA;ZsvQ5 z*;`=7M?8V>xfZXFB>S*KW9eY1ui+y&D5pr)io>hmkKOn0mw>5#w z=0a+D!+5p}4DBs9oJt(qbobWh{53hQT0e3i8x;>$Bl%KcZm*E?kTNf>w>j!sUj6NR z&Nk^1h)k^-8%)p6w^tT&i=+=;bv5$M>NcJQ;^N0G1o^^068-g&@Se7UDyW}!tY zP(iW%Dy8%x1&wvwCN5k1p9d7<9MpPg9rYz{nK&?P>sOgDpb(Q$pGu^WYS<+AG;II^q;F~%B>-=4lf zmTwux@%QAD-W+Xx+I4`!m#3#5g3;mwcbW6IX2o|(cpV*N7(}->>=fW#9b;$bfUftF zUQx!EgYc>G6NI9pp#y&9%BPRA|M*xWnl!<~xckZ93GqHhA2U%c`_bgXU4#S#y}sVEan~!;YEWu%Gq)!t0AKo$%6M@ykdOhT z@WO#&KTi`fkfrs({l^z8wB|RM5kdkZ;Bj1?cdvJ9GQuJys2+I+SZcDTD@N~Bxh+uw znyy=uJ&0)igi0dtZI$ggm-Y~cAA^#f@#l-rf#iJrSa-+58>Yx=HStu4%GW1R=(>mQ zpYl06WAj&h3|Z>0ix@SA@V~Nulw5WBX!itj^3rvzs-((c7lS_HZeS#S{5@It1OJXU zU+eEXoZYrhF^g5ST?lBeGWVj^-rKZY>!f&d>kf)M(PN0Z&a$UMAWF*;mC-v!=kpW7 znz90)XA==5g?_>6t;eMu%JsSsi9lkK^MHQIp%*g?`>XN9U-I}M`BQ!mmgh-O94~q} zTSE!&5C#)MYymdgtfxaNXg(!y6IBD{5mIUceIyM3UNrpgN_Zm?9`MRX;{Z=K5-uG! zEq6xIm&8ZjVT`((;u~SuB)fobWSIQCsWNQXD#q+iL9Uooc7hN&DMV z{6o!tr5z=nqnHHed{i%I-2Fc65-l`MvuW{~kyqSx_vZ3@GPkxY@Zw88g=hE4EkI7q ze}InHdGcVTxcTUFb+neV^m7`t-giGcLbXViP8%4xm!TI0`iN(X88Z6)$&T&|kq`#rROgM~?6e}v{|*CyRtV-Eyg}b-%D&ZC%>mn7sHpT*EjZY1>>j)Xu z8}5%+VS;kn9EXnCW^0XwHkg7m#te3Nx1$(ky~KT+pH_(kAFyPPDk!O`77t5`?eP7c z@v&YmC>;tRCqInw|8nv{5bXCx=fy>VL5+sLSnrQ#I8W>9N%hCQ%xJm7p?~If)33jG zHJ;OMi;>0}Yi%l6);K3&l)gVP1k>`)9AK3gwc!{R>K|WR2&=uAUAU22qV}6s$?lm6 zxOpqN`hqAZGeDx?dTJV?l{pW9=w~qT9J~FT_i7)j;^F2)?__x$=C8CzB){0`isr!Q z-zR@9&R6P8vgwPEZydYa!PL3$F>ueGp5U5Bud9_xj<(VACuQUFVwF#7syd0H!#7c8=0uQtY{25_PD<$u#a~cax%pLXA*1P z8ml@bifY5MHc7Jz|N5vlK@P62!%qD)-zKf>AR6fGFco;0=h{_c)2^JR^n4zPrUtN2 z*FNj#{UaU+Ub*=mOd{|o-2{`^t#hB{dbqAPC>otfT!vnVj?Q#YneUV#>EQWxr8mp? zHw=%O=A@>fQ&p(;W~^L?6Bj)dHcU@UMMJJ*iX>M4r4{OyE)M5tB*Xy^stngvv{#zQ z=`|D>eSydvez87+)%fjF^RZ+o!Eo6?o*Fy>%;YpYR;$998HyTIu#(d=WpVIBy{_U& z=(^5+rM^m;i8@XDbM}*~mYRJnb%`O75D)jVO)hekthNVF*d$kOzkhPVur_1gu8Mf| zeU9u~56;bph3A&J&)M{RvqN%-fz3$^ic2i$jQ&mzhPzD@a3ldS?MWUgLqB6u7eCzM zy|KXOZg2x|BN0fJr1>eBJZp*n?}<y&rv$r;MUFZa} z#c9S*97Z3eaIFtnJTHu!TAL2mI$5iHoV0$gQP^`SOMOqbO1U$NhB7$5Fnm0g#Y3#S zlpA&dI#2+sea95zJg_kh)s%&(rAVF3jRmHKc(piW7Wk9bx$2k6FmPKL@ zugh6Ywdd49eFASzC0~cd(pLt?WEK?mWH;|I+lH3u=zdU4R&?ilvu&=`q+oq{$lf{@}d7LbsxxXMxt6aX!ImI7IvIFpg1s~)wN8`*UT zxFJc!T4O-earE4P-zl+x75!uKseo&x9Y%xG6O8Kj_yFrfkk9{7xf-RWZ1u--q9QJ} z6sNi(j~81+V5Ij=ZcV@~py#aXXBbs~E!*D&-2B6V93_K~UhrJ`@F>$;nX;?X;CpUO zH=wjDrUl(vdTd~mCe{$8Xu|!xn?NG$LTF>A-tYPTO5$2-ogH?pyjgQl)@bP2%EMP! zq(iLU1!UOHz}?KuR@l!C<1rCWWR$Q}1MjrWaYUIdkDa01BAHmhInV#1uH2R2_* zJEPAI4LiwDFudX8w%BbjCgyxk6UU|hjmV*`NV_Nq1byxt`Gb^Q`8jGUF~f*i{< z8tK{GzgbmX&38_}zZp50t4#LaVl^JAFAgk^E~W$ltkzm(Ib0M@>M%ilaTzr`_qz7T z_=5KK>P&w!LkyF=U1)L@D$q|pfv8gaa@hSgStS7op`w1wnDzMtnS16l4rtB(w<1z> zMgfrcjSa{qT|=c3?$2$lA@E;W9l}0f?Bv7ECvt`pN^EXWONRUFJS~+rouX0ljG8I_t0fRq@Nkq zNq5LW!fAahrp9~>lqn&jCuchK7E;fJPET(x_L7Hns$?cwumqR)x^3S3jSDxnY31-p zjB^Vm_Yz7JCu$=oMGO{dM2c<7!sEq~}JL)pg z?A#w?KL5xU%) z=~{lEv{2{z;Gvb;v;^Z# zu4j8dxK8GC3!chGx)21Wz`^=l)KF~(Ts=>J9j2eD@4w6v5At_uBF6o00dF+iF^cXF zod2WU12*~kKNUD8DiH(I?v0aS%CxTOb!Use+Kv#I>7zU=nOECFzIe{NV)V-P0^rK=Ph4U=Xh{Z;0wE zz-8e~Unu$6ei_tfmBG`KGvCDkE`+8ar1QXbhoAQKk zI}VL5)uTfI4LiTTaQ@eh+@b_`xoA--{ka&wR?^2CG1Pm_U1B0uXRcKVP2hV!xcM@=4@2^WC-x^hWjoxKbcx z4DheGM3XF-OFr4mGvXYR=*=cs$Z>dl;jh{J-wgz_Z1SC`RRd+v@WRtC$2;=!A)S>kpyO7+tm>^dthbzuH4}6A^{{< z;27@!n!a+aqZN|&^+*LyVkA}n;%nwLuID|0hnq8GDi4541G@j3Cue}F3pzScfq|wC zXgw;K5;s+?9DtJc<~9kQ6R3(k97Xfz z?kPwT_>@EwD6h7g(?Yi?g(vf)LE|a+=sVfyw=~jNyGy{PJ@?~l);$IdwS8ba0*Wqo za~@FhI#Y!Nd~aZf<1;)amO9fGYx#qP1&|FH9sQBi1SpR{6dcF)W$DTR_NWEmi(L$P z84hISd7!W(y_5HCW<_`L%`zSZKq#>sH>bm>C4IR`) zy-rLuTyCjJqsgcq$D#j{Ilbo9vXKcvQO2uG=Ve4G0~lEV;6bU)2i^fVdmkvOuSW`W zjL%Q@XOpt!V!7b{X*`91VP(a%O>Dy~&C|67?8)Yz2VMV{O zF;%VI);O64*jQd)64FeAZi!=9j_~8=S6@!I$@@Mb`LdN%o{G-GLA;H z7GkuHc`>t57o~V+lqRCsj!kryc^W|Jd0z;AtZD!bSUc!L2m``!Qku-do!JW>kZLcf zKe+tLTMd37U7irR)@UNL-~|XUCYQON^0)yOel#b}2kd4nbsnc9os<{Vz|{IcRg&p;JVO=}~#sWs=bni%k7)1ije1m!7 zhcC&++cK@b{qX|$VfcYF>%(>o9M8su#@Fz!;fe(8>@w!1GWr71+8B-aT9oGYxJk5C z%I_Xh=fjPZND1A5G(*s~Y{gtsbqMC27?>*yfk*Q7uyTHPreM}vBV7;xAZ%yE{lEhe z`ex@NX8L*Qx;Cy1q*|k)TxSMJO$l*N{d$kU7A6{)wzbCIG>wHjGiS>s$WB&pdbBEE zrkJxeeM&P~xU+t?HLw3@W^$J!DoOe$Qkd02|1pzgossK?Jp8jFASxVqkwW3-z%mbd zQheP+ftJprE&@nM8D!_B0G0Tg`)qrRT8z5D(PR2%a0z$=<8uYOrH4URl_4eS zlnd#)z@b6x9F9Nw{1B_XJNN@w@=PcK{sNfFaUWN#6o3weEYM6U^|GX#!tajART1Z{ zCU=dTn1N!XC-8J(c%N>Km6Jqrxu-XH%e=yoL_A{Tdi#kbLu}9bzc0{eFVd$QK!m zRomy9b9PY5nF!Q;&60+3Cmr$kI~$Q501E|KbxVJIa(uxS<5l5!Q3!QioPF_1Aln|a z-~{PwrV-nmKi}@4RJ<0e2>ITZGSMo1vz?i?J4dU;C__4eV)2YIO#@PHH8D~aWp<6I zpS_|yl7R;E4+Fh%1kxwDh;*-Yk{RKm!u|8qP!i)hM{?z7h@^wKyzr4&2urv-eCK=``Jpb9Dk#h5>1t-W2Pe%0t+$35EKfPSC$p}sOQhOgbvpc5i-L@Mq&pEz0bu-^8?A_HDB)d4~ zu}!z$AR{u7FDK!Co)C_niV2K_-mBP^M66mkz+tr=ka%W|q4D5*XXI7jta(sys^x;T z4PENod;2_!_7?4zX;vEK`Y@t)AgkN4W0hCP4Q;>&!dsmDhey^j@UD!(tXYXBeI(Ak zC8Y@7F|y@_+(DNrRW7^qNSh)!{D~0LG_PU93nkGb6~d0%qUmuJ1@G zpy264XrD}=-v{4};;(`Ki$Oc`_pWCST`MoN9{Zu)hz!#L0#i(=ec-fqJ>|;gm2Bce z--3Mwh>44OVP!av*JX$Hqeg)RGc1Z$))yQcvah(zYK-=MxBFokle5R%;P|5Cg@G*K z4?15HF@iypkk7D+yA?ouQsG;IPcH5*$;Ppg0FR_`pZ!e`LXqZUaOM_37sTQP$SnrI zSGkyfC-nwCpPdOeLtd(GIs5~#yl=#En{*~S$2ia%a`_sFN0>F7gIGn71lH1Ah>1# z^RpBLBu`|A%@{Zrk@5mg8xjDOd>YXJasB#4fQl#Z&@`ie1ZMSF&{#~&YjY2Y#U2G< zf#y7nBhU*S3A)peMnZJ@;B4U0dcD-8`~-B&^>^ljR}*9aU=Cb;Wsy(Z*8%>$YWg`4 zmqu3uvi+gfc{>x=njE+yq~6{Wo6N@FmDC_bZh_eu@OWpi_lu>ZVCnKq)lPp#dj>iK zj%DK_hm;43kMC5NL=R>wpoDlAff+a^O?-)i63&EKb+z<0@Irv06g`MgNpL!J2k8(AiFc*S;>O-!An!(`@RFnA39kY z2FzndAk>0(Y#)gyO4So7D{Yd4Vk>MI& z)zZ)RH zLl3BD#nI|cPd0&>TIyS|-(6Exq)8LJTSpbKxAR?oYc0ONA3f7#zLBin_55_RyUt}- zG($a03KQ8li;feK1#;P91cXl#0a`NYXkc2P(NhuhZE;#Er3p`|Jplc0H$WxO20T}9 zfMK;-^Poz3WwO$BuKC(wH@iBddLBPrD8$(p zV|k?e(5v6xkN?#VZ_pp;%nW;yqY#7yEG~?-&T;ttey#^=B*-!s`Tm~@H>ZtBPC`w9 z2DiL;AK%Yf@1d{g+Z_|`r$=#k9*s|{LKW;C4FJB~Kr7RlC_v%_FW#5G{l#cFp{>z* zfZ&+w-$XSl2VdT+9_-X-PeUPNR(qi<O z)z){;&euLvH#|w~elhi)XTCi=B*g2P#3ogJvEl0VpYIiFaZ_3s3>&r9qcLuv?A2{l zKf$yjt&}W#|JCN(5$=PRGoAS^uA?M}@37PElM7vUe3044{WkIIv6+tcu@A<|naZ+)9tQ+|%mi-~A?oj+QIJ(w-7oROA|$O;n)=kf zPNveJ!ABdK_C-y_HuV&HGt24_GFD}kRUKzrW<4^k78M2)#;WJv^DTgP)t>Hr?+!@4 z>qceX{EpXgg^{$(+`F;x-0wOMnUQEE%8Q{wD*nn9UmL@g4E0eBnN(hqq+!eO-T1z& zC-uQqZkL7ew%M|g?OW-rEc%&(i)@Kz%mewtfDlPFTvtLnOGA2fO|knWYCO+t%ndcc z%Ya(JyDdPk#3#^TtGEiOs9i;r=9NU)Y74$anH18m&hB_ zEvi3`c{!)y+CUHz*J}?p#f#HFDKlCd?rn}!X61%Tje0&SwrX>f2qL(~lcXk{^3g#h zQ`z=iXB_I+thT1eUg^-DRe`#qNU<217{#kn2ZuWiGPpDgTRD%$N}O_WU9)b4au%S= zk1~F5C<0GvxRWoNAm|=^oHL&VG8RcqfPdr& z;E5+crt0ueexnCEGS75G)vkyi_ssltvHm%$C*F1dIBz|?-V$%F)D@%Fy}yaL zD75P>-sDMxRd7~4Sqz1nwlQc0sIaA0!#^oMgH7_i6FV37ri4Vf}SRv0f2hBvp6Cfn7OX{l>b`MsUPD;m;c+DGT#4L&L=9;X; zwDw&0em$cSF24is{bJ5!FR$|5colt?Vx;|FN$53iJA>|u#dPznf4G!p@C%9&x142& zf=KyV$9C=aXxvNlbu*rWNJ^2E!gvOr*J>Ij8rRG{sc5;_iTq^~P|f>&Q%|~S#}X+5 zNLlTm4Zg<@&W0AcKTjw}^&fF?zy9{8(nEP8OQT+a`w;KWE%Gyj`-_d8HrjPGxMQ0$ zU4Dg6$HXm?0PzmkRCg>b+uA)WcX>q@#UOaEM`>o<=%3Od{NJSmt7?K)$i7lJy9$Cg zeQo2UR*OxeB&Sd?3v=sPO}>b2cu-(?$?@%(Ich(R5QgrpUwtitJu7+2on>^Sq&q4n z`Kj#+dHL4H9t?4E)hsp8?VP0d^j&z(j}->}PsQ%Xe;;jG27V)*H033 zNU^4`_8qxY`|I;zNW|cBXN9%gx}^X`*y&QZH?hEf^tp2Oi`=$pXOq}^>6PWfgN0@R zr#L>&w3;$|yZUVDi)&%WwR@kLR04w@<3F1DX?}p$K38!?Vcbn-kCco^dSAcm$PhVf z)TXhxrqBKadCo!Bl@{d1Yu>Ly@=NR9kFgGZ+eJ~2xt~|&Mhz)`zc*Z2jBgZA1b)=? zf=e(##WtN`$q(&XU+}`%q6yaXiWAnP@Dd~Ep36da|Wt@pH$ zT`X0qe`8K;F$vDE z>9sCZ6fC@rX5uBBKNKfdPyVdeuXh>%uizNKVBZ9CrUQ$Uhh99#WW9feBGteMoOjKDJU(mcVQNmB**my|fe>l-FA* zSB95YzI8dWWBhZZ;u~<$vQ>47dHl^0x#IY9NAx)0sr4k27WLc5v1#J6TMW5;4MUh` z04Cv-#ZK$wB=b3yOdIRK=A5f>JrgX7FIi!n8TWGJ;n|F(IbF2jf_Yc;Kfd5Zy0riE zXE#UB&>|3WO9=uFD+Z~p2{k-u}<5+VS{3CJ=# z`WS5`n5&XT^hB&${-j`pH)Bp(1ttbgmcDOKgkJX>g+J#cGrj%n@ouVEVl-dXN^cR| z(w8_h9moDqQcc3P5XHvrQv%ix2F_i?ev27z<($b#=C)j|e|H9ds#Y;N6sJ#n2*Mba zi9_kFvn-M%?5jlPtOvTDQOr1ya2q#9wKbFR{}X>zxwk;pT}2}>p$a}q3s3D)mdyn? z?-64H0P+cUI#MZAsHB8dWPUBtjWGP~Mz4|te>YNCTX@Uy8ZNwDU1~L`ne{P?mr~d! zL!=_S4TO$;esd<_b&IQ5P1QbWsLu;+;~hV*47I-L7JwHel2R@e}bXN|MNW2HMa@$0HlDq{ttI+>>DKvus;qw}q3^ZKjzUQ^fvDS`RBO^|=S5W}Nc{Mm z0Bjm>e?Iq^g8wb=>+9M!?fV0iVmRSMOl_mjlz*80##VX6H<79~4u{+?POI+f7qJH@ICGtNI84T)?CstYq(K-Zmjm^l>y<~Jo^oE8tGV;*s`^=LLz^- zx|&h{w6~~eyQi6pMmu%VO4MeNrF5{jv9O>O^hhx@2SscK&6SVSjcyCWW+^1B@x|MWH<`aTEBMn(un z5_PugTJ?XB4wTy=ZGnHqbesqHH%gw&*&0gGjXv?ETf#2y!Pha^`1+K6)a1oM=8ME_ z3~|pRiVE@}g*(EVmWt@7#Yl2Rw02xoo(_(Q*lBKIuuFFZE3w`1dxSqHGR7-}%Qp6Z zaL#`ff_{wu-sOue)(j4yOW#5v{9k!dhYqNhmqX3rqLbbrpDO|XIV0+8Kv7!cLTz|Z zKs7L2D_z&BhQtPfAwuE)T1ZuFkqf&Hp(7^p&!QhCFp)uv zhxR7%F#>8X6d2aB0W1x&WS)5fAi(76{A;-1&FLE^l_Y}u4{&*#0qzlex-;e17oR?_ z|8HAx|IGzru9~OH{`dBtr-ca6V1q2$!TH(W!oc&yD)1<|_d7kQ6Am zHU4=A5*PvC;j%jl+maH(S-}hQ8l9SDSV~0$hpF?%K)wb>Janajge0C}kO|fnf)fUi zg%so4X8?NnPco6Q%9hs5c$J;LTW0&k_GC#UNKiom-|OrXG)sDQAx-l1MkEz1fK#TL z1#xh5B|7g-yMa&R-L3rQUr-nt!2Wy?)l+pS!5U+}pq_sj8;pre?EP};TucqH$$!=s zWcjWA z!Q#P_7N87AB5*GNdIsp_K!9190^?~OB_h$-R|Zh+1YA12hqZ6#i_iZQm9qmNM`1&K zA2|Cu`UQYK8vr)l+Kf&hc=J9m7x7)4+PD`(8OlJ+5B>YKUo2JsHk0O+TLX*-F4NMq`7SQ%^_MFY_mP>q=WC#venH^u6M%}28wo;@ zl53IfTO9!3PZuu&GWc*7z!*N7|Nk{?0}@pcM!FiN zKG=lbd4PdRE9HA~!tKkq`RCc<^^DNed#8iaO$#cl>#PHV{n%@061x#TF> z%UG4hsawtj*uhYc^$8FRq+bE}ep05`r-ctd9!S*Btn2O3+(@i!K+e{HMwd|C=wWPm zAz&9kC^w6WG*|)1TxZ4~Y_M{Rp1`quwN(I?q^qnaLn8?215Fh`S>^QsKuhR=IexYh z-WIWkQ|ksoUzjQ97AoJ3paQ3L2k3Mls%)PCB^?ZsZD6P5Tsr>1ZkBArrvF%?>i$|o z!&l7+D!`sG&#dV<*oK8Gl=qlwW=d1VgG~{{(lyh*A_Ovu-S>9q)UOv`EE!iGFCH2^ z_wgZ|6PIkfJ9f3>JU{UrVpvI)tX-_A^m)HH#eTjU;XhsfhO_$xCAQUu?`3AIm4>Hp z!apzSw}WY}myarVL7T-cxtPM7U_Dq3qyj<56(Km+|Iy_6K?M0ihco3?0ba?H3fOv> z(pNwoUnvRRoQ$bCIy(zE$MYD|fKAlB*7GGgoT;>5+ba zvAtPTyg1l<&y)Erafx3uYP`_s@OUQP%VMNv+U+h}qu48cF!&MB(?2MSz_V0%twEu2 zZqVRPh@|hF!Gd}ObQ(`5UV{X@eSl{v??(yKGLv#PC&3h=DU*BoB_9{NM1Ty=dML-M zB9ijA1KWckw!qW}8XMk)V%3^ZkQ&GWp~v6=II48#o@nG2%&YW^?cTU6*7=#x*}w19 z{V&8dVw-A_K;wa_lX%ZhkMfcI`3}C+bmZ4tiE?s}lAQ>&6W@vtlg%u!TUswG6q<<% zpPN@XI)7F)Glo}Q&;S07#oZdD>=-D9hG{ROZxC5uPv%xVO2(|doqB%+zaFcaF8A?5{#GTvNgI4o_z+V)im5xGN0&> z;Mee@HF7~dD6MJC#h*OlM}rQ)cD$m_ko4oLP!E;h-h8c=%W5r`%QHex-5?0aW9tSW z^cvOe894Zs77M6P%~V-J+srfNqHgj&+_th*_3--VtwL5A)ERMCy@`*WhZ8+FN%9!X z1FzvFLT=L5#ul8e*s#y2YV(Pfu z^5zpB%l#lICOG7!eYM`3aN{b-=aRnV9!hK>5iADG>YwWzzP4- zPlrM&Zg_way3nMR^B*n15v-!8;fW{=p{-ZvQh1%bd@fAx;;Q>z5X1}gZJwiH5q+!( zU%sLUj5Ue5NOia4EsGa{nw7EyDsGIK(HA&7JA+k;Q7!Ka`Ori2H-fK6V&mlJeDD8?;(^=HsJMk42Oqb#3Utty!fi3%F;Z@ z()5;1BGfOto>etf7%}}LJ2jn6Ba2Q92Do!h5m-`1B5zo2N|IQFNhCq22n=ya&&$AO zS|AJ_3m|2B{I%wVie`g*OKm}5+uAGu6%BnwDS%KBRWlu$4t4uhC&3XXoo5|_D#ZT@=b!T zv*3kYY$o1}T1;%nrdrC=m+zIpvvU_WRC96tL6DkkpfL`z=$;`(ApO*lBG47vs^>z; zP{7=w{$u%vl?AB2r0UZ-Q^6braIoc0u(1fyU7UI3Ehdy+1@PwjHwv9aU5+?t*PGh# zf2$FwqY?SDwmqyJaHrL>u=7cyZQIi#{%F?TT^lr$n`y4L@SYI`wVHB}2M-c+p2*h^ z!av{|Rs%MWz^?maF9^jz3*BH8AJ4)@Qv`3PRYPs)AwF2k*!UID7795V=YvgJzpin@ zv1@9LW(^-FL`NoFwBYkmk|e2-$H%^~u;-lQ4+`pXrVG=TA z`Bq-CY5l|{VpWMsEHhe}-ZD>Wv>>~^-cf_i@}CZQ)e4buomFj79S0G0sNI`-P!cDm zZ!aH7`4B%{yrZsU2ktpmBt1nsPpoq3LNkoz*L*(r_P1Y83JzF;EhAcrrezmL2cDj% zmkIr_scUxk>!(Y@D87|Ce74N{3(Y~?L3L}X^R)oci5=B+I zXgnEGM@sbFMw&;=QKgCs>}7kQis&c4&ilG<3e!Kq=!tvIbm(phz<|nZ&%RM^#wKCK z(ck^No4B38Mgu+YJ2)YiI0`n!>cLA&^$C4QY5c-&KY6KTOG*{Tg_p+*|A6o#QM~NE zFJfNy^9|0#ZnX2Kuh30L{O)|pYxSDpg>SsvP#|v{3|b41^W&a6@sspwy||pMv$6#M zVy}&tObF!XXT?ZL>WZ#@*(|hh_#HxWzSfUiq+(6}^5+)c*;K7ggUzP_^NQ{O@Uvrz zs@);q$@#2f^6v>KACo3YUN)vlt_pl+eHjzM%(*h(>5LGEYnc?u=>$Up8h!5znEcPa zyPsW2^VkJl)Yp(BM2*SY~(J zzOctWlV{aV2obt+hGp#6mF=zJ;`?v8QUZ!Bi&p9>7ESlQK0`IQ7PXul)DK&=ilO&B zq4-EakLroH$G%xF2n~sUskPD@-A5r}$wVXW>;Dm~P4hlgHlqv*8VR2$Vk@-_)pgMo zXqL0p{<(*+*D_Zf{(h+19Y#sYxP4$(CG5O~=5CfT-dg+nr;b3Qiz}s{_S2LsR$8O- zFFPd?{^YBShHmbLuYA4y6GqGD+|R{jP^;e6=sNToh}(E(1+6g-ERTPfbfS(#-ODo0 z_jSMC<$KGO8pE|!k>OK;cTTUXB<}GSO=|qbl zUCoDt=CL1@7N=&==_Z+3c+MMXc#ozOnW_<5O!E55L?p%fv(ZFG4x?0e#Be`^ZZ<5I z)^TmkR7IcHP}=D9=$XYrmggzYR3i3!Nmo3HEBWLL6V{tog7bO6KmldO~ZJ(?ql9xzgE3j#`P(%km133mK$uBbTLU%hP7p z%ruWwMa`?)`@KD8jAD2^iA7*e?K@ZRaYja_s`oMS4Ufrf`9*X8Go87#6h7{@9{>KD_W2Q+%x^*0!`+LD zvQo9WbYEB#?p?$AW8$}}1dd;MePzer=^7eH79VV-tMR(tYFiAY-hb8ix-&R=)v_U& zAFEl7O^>|akYGI`5u<&TuugZhj|j?8P(F@7SU+`GIPLtdI#|?#58q38q@7qQ?^5HE zR6@_i#byR;?re{M&C=%Jdi@x6o^r}2kn2%-hV>@Pd#-L1UkO4MJcKC08SR4Nj!}tx zeZcPrSS@0%U^my|C+=8pr7-L8TGN}!M+Sgn7z^UJgK%L=oiYHVOG7f}QsSp>qwzb~#6G);cb%TORCxD2Y4q6R=?u;3=EhT3J zb)U;jd%5%Q-^LSu2~%yoUfeJ}%lvKJ%93_4+SD{|En0o%=td>sqkT`Un~YjxtdeC` z$S(GCh*FkbMUnf(C9_H?b6Z|N*u)-<8O2FD+KzWw~YxuJjlEE+R9NkEK5)>{3a6Mu@e-+EF&< zn_!^kg5lxC-O?M)$vfdyBs#peUkzdK{A4U7Ie8>tsJZ_5t6Z*TLau};>;vt5h-Qd#X0<*oE|u6J zj{Gqz#&k)2HLv$5uR*g9^^Mq>;>dNUdZq@tlfXj+|Gh%ZoGyR98_VnOzQ$N(7e>Hb z%s)A_Nar7iTp+1hw#QbK`O2>3KMNL#d=&l?R!;`Y5P#x&$vc|oOj#?x=t?^H>!w4=Xw)M*2hXwu%4ucXq;3oF+b#*E7{{$)+ zeoY^{IYQ(qf?2WV?}J-7AVCbB^|IjkusgS(-46~(OMwM##5)EkUD8rlqX@4V4NWM0 zwrw{W&ZM2;87Y+EDLt`Rmg}C$f|BZIsU5>*IHtXVNmnFHNPwv(*Nf9;R#Rhqc3|qK z`KI0TUs2ye*prT%Xicf-KDwqLF zDl{)vlkM_}zhJf)JA#~Td2FFpd6P-}_pnhrnxusHwY15XEl)E<1B+`)gqO`oZ;0m9 zxePH{R-@0^Ya_)7l9w$8Wu}e1*1wpHSB(YDYt<+uls5^fbYW6jS1zAM9!-_H=^Hfp zK5G9Rri|#Y8ThWZ`zE)Gw7D)#cAK%|zvq7ndC62Y>f~g0@uP~iIa`$XBttZ8TM?vO zp`24?ORd=$WJAt&YZ3DzM;Wi)Oi54J?X*%GiqRXU{B+#ed%MGqx$R!^jDX#YNxc3j zUtGBLuYIoHKOJ_*{s|nf}2N0IsUKQ2m_BO}n51->U!Qb=qj(f9}(i7bP zk~7VCJVKnR3aW8cp~6|Y0h8gVxTYq|;Mo7^7%Fzfp4 zXkBL1eB{LX@R*8Y`A@l3Z;aFZZsq;7#;`MQbQprj?4uYNv9y_R1J0Y!w~&7t9J zJAABetM`I@C%Ww^(P)A<7iZ4yYA0Q^i9^{t8Kshr1v1g0EACm0p@S4{EO)a4ps!TP zk_*2Vu1X`zFZ;AELS;QY@s7@Zx2CD9^$c)^5vor_vBdd8G8k1T#r!?O7R)E|UQvvA z1+O_Xsc#_0N%Q^C&%Oj&~oj&8^trQG6OxEb;XAMvo;NF zFSoD$YP8IHl4zfoTXbovBuUbAt5R1?k1Vz20RiL7QbFYq{Cfoc0#<1y%mu5JubZ(1 zExD3p?onL{X5GDDQcIz#OquxUE-IzWL)#RXew0@+8QhRAY3PZ&BSr=6nIW4hYE%*) zYu}Hrx8Fh(VU&|WZ9kDEHmZP52qZv5IrbHLTMSr;JiGnRU!2IBez^m8s=*^5HdF+V zxi>X0i0mVn1-lNnpX7w~GOoyCy-mt;_$AH$*@ZA%=pX$>V6=t3$ zFOat()5JvGHyN;!26-b*9dRcG&jM#HiJ@8bn~1{frlMNMQ~dcFA7bb3p@c)L{zW+o z_~tN;ajh4Ez;r)tHerWOaf51w(&P95cF%O|>`zm7R!^kU(L5HHVLb_{l6K44AEJz* zUkfW4Ta$H<1^1`f_KWZa=9yv%O^J`?Tph-!*Oj$fDq&NOYvZO&YM)V`ACr@^YJrl1 z`6-tot~b%rg@fG_M;W5s+G1kY@q_9Vn_<*TqI{TeLMTE zhy6Kx!ug#V*eHEjM(Ys?X8>Gt`IhTTC0s`fON4&PU(N4Nk7~ZVxcZ(7Db&pSoT}wy z*7;Rr8gADZJRvYdX!%f3gNL~IX$an$0l3@v_S?l z?=xk4B5E8ja6o~)@DqK^WakToh0tXj|n^4?B&_q=u5zlO_x+?uX^Zsc59de`9_x3 zF3#Ld8{nxHoA#NJ*EX;Ckn$NRd6|LyXva&9p4_bG^!?u;)vCWkyAd)4nx)v9xhm1m z`^Zh_$A7%HpQr7d)pGpenqIdl{AnP?MyUHPlx!Jv=h<^r`gmmy(dnW4hK+h>PEk$$|B=EcHoh^24K68D`G`~O&5 z!LLk2{sJQjTU`FVy1xe;2Nx41L+}OTEuH32oVv=L&|jYzmVxB+-9$-(c+~rgVM~iA zDX-p3mE-OS;1V**OCMx5?l}|MJfSc3Z=A|*ahc|U0v87jm_!!_RF)6&DC?<^BND8y z0BP`{P>oXqJyjRw=618c0!JqZ0>YI9Ksa|KATH=Z=>5k>0xZagOu$gIqX`1WgN5Nw zg)1P#faUBVkjw@F_KXo^kQ42hfr~>J3{ym1g{BBt;eo$01_=6AfhVN1EyS3?CjN>3 zYXceYI0TT~Qi!^+A(Nbdp(_LEW#5Z8TY)?+nnIm;Va7X&m5Q-ny(kD~f zLHFNV*X1mtU^~b%nCo|g9}zm}6NW$pW+Ty&g8a=;4AAI@gy{;JME!I2Fe{6|bZCFG zS`N5^9Y0B^o$AA~0#sE#ssM9TymYk`nJP^>3b1X00X$d;ZDqdgP!PN`yQQ{4B?c zXZH8=OnFb|im_KE=fneQb=*ZkzZq{Q_2i?cgjB9hdx0m`W6IQhlRU(UUlyH`T=G^6 zbCs3X29og?pWopjaj2Am@94aL3K?SUX+B$R^$u_zrU*SxHPvW}Mh*Q_L81`L8>{C6 zoxw`>8{~rJQjJwL8td_N0(cee(@VSGWn@>aaHoFLPIW)D=&^?U%k4J}!he<~ z8?vRJ+LH(jk+x$W-QCB5O}mvXYklH|i2mH2L6abCdL*t!Qg0E>BoUEOMOXY!$dGlzv= z$9#bVYg7Qz)*xSDU(0!Vr^ zO?D#ee(AHsw!}YLeaqk$Gmi?x^myPx`*E~Vsn4qBjKm=TD$tOh4HU+X&aQGHo}_T+ z2|V0KQfPB$P{rOg_D@WvL@4GPojg#p!DcKu)|HVjVHCXY?}`3I(6yA9&V|0G44AEi zy|KJb#4}Q8!^K)VV7!c$Zm9V)oagnpBb*w;YjXd2kRUhF?N_{9VlmYh=i>I7RC7RO zsk{+45Emt7b(9NRoGRWq%H;f|FNlBc*xq59#-DF^>Do1#+-wHwPkwvAf0rxw-7~a} z`9Le|CJX8%rV4q8?cJT5WLuW=gpXVEMEa3gk`}npCaKU2)wK@z^s@7cvaNgf^fjntOEEh zW+GX*yk)OaP(QmoX357 zVtT@LD#b<_+W1}1i{v%v$4FkkmAxW-4Uj*Q*H&GvSC)3pLm!uuGvxAbshw_*ri|;N z5MQbak(K%1g?WK(#b%8?(W7}W&Bc-u#b5|5(M~1;%Fbl*yL!<#vYR|@se9h~aB9)- z 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�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 Ea7N-yJ@@Z+FhPO4hrMsVqzm>wDCL8OYpmiCur8 z;E;>1aeX}^;xj?wDWPj&|(A~>_6f0$ocM0DklFS>Ngs4 zp7jj}pzl)a7@6i9fC7pMM1Q%rc(TG!izhNUiU9}aFhv=Xbs!mK?JAN`@}Xq4G}(*JvGfa{ zGhx4u=uoL0@?xs$Ts;k{Ff!3JxlH~nT}tIJ8p_fRNsk}Pw`a~Sziut)R^ypIuQ;sK z^eqjhuXX`EbqoL=8f8yZxFKy8!6n=(i%~6x~qt(j0$cN)wE68;f*j2ymDugseO%@ zLdu(!Bku>WgNT)1@B}9?)bLA`{R%0q`bj;+cl)n+4dTC~JGrZ-0N#JMi`l4whI2Z{ z5YBp<4_(e#XKUCTTQ4_zU(I}HjlueL5a!xyfy>~khEqOx7JOq?@r>xDJp0VMk@F;n0zuX-Y^0h#4pb{ z4_%lcrc)!2r6}GiS6OHEahNSy{tx4+i0nJAaNok4jI)n^WMYx~M_b z3h8fn8}tA+9xBx@Yb~mT2?ic}S;S509a=#ckkL%(_wO%|<#u$ex;d-z8}=WK?9_eP zfF#DO)G(<89XZRspv%decfJ*`C0x(Tq7yH|kFh14bw1p-cNx57Y?O);?aFkifH@ib z8sj{bYAG31W=j|)sjn5n#f{4<2qv$}p2EyBFYf>TG6|&p*SI*s?V9^ z$n9glrp{BUP*x+{$v!9S8J~R`Erd8_kbCk8odeZ%>lyeK8mg*RVD0 zhwdXx4Xpa42ci;Yxg4O;obaf-6#HGOVK4N0-ZE3#Zs4Rt0Q9 z4uSt;7`S3gi*44ef#51`?(qtmCW>(?>!bbSoe`Dw(^BbmW4ggp+&Z2MBVR^+i#x1dW_KKh505p=gz5BDJg{0CK9r24|4d0XF1v9I~WYRY6ZO! z3dFFfs?Y1uxtWW+^{}@#%eFJ88H$*{PR^n6RgzWj;g%re?D_Rm;$T?RrcKFnZosE4eV5r8ssgb3rm7qvzJlxsWJ0naB!5TILa}8 zhMwsB_)^NNiRJ1eN2ymBl={u-BeIkVwCnvmx8q~qBlg*zY#f0ac$&2Hv z=Jbau34dP^Y&3kU;Bf?+jRx7_%$nxvXk}J_?Px2ng+f|HnxM`iL zcc}+5ERT0KDfE1b6K**1R=3A5n&BEzJmIRiwR-mklYMnY8e&p)HZ(lCpQHtGWTg8} ztF)nEWFg8%qh7g~Shzmj%OSU3jDB=&dn;NghO5uHembMmoE{z4KUxuZLs;i7K6k7C z={XGC)pLt$)}G`2bD0;r%H$>oeLurdE#zDaJ4d_d^L4R^Ohis-T+gA_T9_7fq|;IA zn!@f^lyd`gFP_U`6)T2Yd+|oYmWc#A&Iy=38v47sU2z;iQ)#mqwGL@Qf&l|4o8w@V zqK(7X8gBKg{CMoc(6F5w3%biSPIO2VM^qc~W)fw8jpprEvt<3p7zcAUY7<6V2(z)Q zQa6vfafCymElXPZigZE#tm%aHQoZP>*{S)5`MN8!=nys~%*P%NV51N!o$*#K&Q#|! z5n@yeP?z2leSv98pLl8r1H%J{5OXD!CJu+n`@qfpIl_i6ccwFXIz95+P*_?o@ux8} z`7vh3$t8WXS-w~ac}|z9?G)le?SAvaXTd=^Bdr-mO`i{sH~f7z##7AGZ6VjID~~Vw z#h=PmtQ@oNd_C+-FDTo)W-*=6{g!-D5jwisJ)R>!iv!wYiRe`v3+mkmz0<#SBEKsjl5xGB-=9k_zVImBF=d zD|d;yWy_n+arP&2rfMA`!dv~uZ2K1{8Oaa*auTg{2#s!Hoe+tU>aAqfO#&9sNV`_hRj)Gq`dxX~m2BP7iK zu8@-8f(}!^`m4t_u0Ml;OUAs{Sb?X687~lH7U9HM5a3?(PGAsmtC3p3!8B1oQ0}Ci zig_>Xkg5qWZVPaT4WbL14-jG;m(wiaQ1_%7j+f}i+gG(H9Swa8JF(<(1R5y8|IX-Y z)I{w-B{I?0fu1w!2P3yciIwjgELncNe;$Gxfm8!m_YB++1$7*u2QVm)?nOor-V~8; zR=o|;m`eKyhidVDA*Z13=gskVdCpTW+=tp22t>RSEf8qf15DswMa*J{eTRe!d6c#5 zGVd;agIhh(4C3NgT>0Nk9&xzn53NN1E>fNug|PQgIiWnmKU@GTRU!w5XcSlkclm`T z&vtZ(M|qVPb?~Fg63XD5_K7^avs5 z+sJ9Xc@xELfZEpYfx;}nfytK7i;jM4h<5th`TBUgd>0^9Tsuy~TH5~zzW|~YviU;W z5ut?^NUWNehG@a-fmR4%cIlm`{6YWMU^ZcRx_Lr>cBo!&B!-quzQ&of6sqY1w@hm&7n;pU#itn%5*bUtg?;%18_r>veC<&pRH9+pG@>_+inFWo5)0MR089mK>c-n;Y-U z{MwkWucxhCfUVtYdh$jtJCwlg&-3Xo;HcyPl;L!~9PtHj-ucpWjq11&o^UNa#tiA2 z^Ex_lvt27csK21<>nN>Oh{Dg(@2=G#9M~E23?{DtCe3O*Ve-zw(EW8VPK_`KvOxAy z&hs3r4EA;C9FuN{E{~t$q*4{s3D`4>^FYf|f zVUWPw`9zzdD8~ix=WY=V<1io+?%Fh2!cza5^!OQG>iK`jryHVTv$H89^{ZYS8CZd?w(#;g<&fD#t1l9LQE$L8&AY1{%ox*_B7nvo<0mlKQ~m!FLmNJFWxP%j3V42SXgHSu#hB?n7frC zlKx$(m=^Y@*WkkNDUJCHKZkf!*D3YV8uZ1UNRS>@avWmUVre)I-f(eose$#4E=OpX zy(c@op*ZZQ1p}-m2iAC9b;p=?%^8DwW0(vAuRkAhQykL1I(%Ihh|i%t@RGHzq@NpPy=*M4CcRU~ONEN<26Jhcn;Bp@R}tj-#05CB!C?kiOLSnJ zaGCLmf6xF+ZDLtOe-}Vaz-e6<*Y@%-N*( z@XTg2ikoA3B|%M8VARyLEjs=2+F&y`H=R%*o)MV2^)ylJQz;lV73Z+?3!=L*oDuXi zOCcYc!sp2U5}tHoaF< zE372tjFmfBn`a0yfx}qlS1jcLE#J!uY7dn2R7<3BU1rwa8Aq|~uN<0hOz0eLY~U6g zqy>${W@X#x(1^R}Rnct^zlI$I#z=sw-5%kL3M9h?ba{8lFe@$UW~XE6@RRKMPwn0I z2w#c8UwR~0n*zbA;PMDz_6nGyL&^+?+a60eJEENj`hVa8sw(^Da9Q=#&&F}^iWVhI z12nVNe9%!G>Zje<_|YJv1*5#%%H=ZoBeK_p z`|!->e5Jpuj0~-=nSKZ5PXWAh7=(u+ZP&pv9=U6k}XQL z4JObH@7nHM$;cH{zvJRK8esSpI9Rn?FJr&@)^xf~+;4?iz7h6Onf1B!tYf=)(e<7p zE{FmUVmMn;Dd9Ll{C|KNk`BU67&tV^yR$RE`@fuBkDuR^dJtXkZin~Cw3YxQ^q!JFAY8oB)$WXN{K07FXurqa9)to ziE7&d<7Z-MN5ZEc|x}-#2hnU)&sZ8c=mMj?bh$# z&`e{Bdqgnk$X=G``XJtPw=Oi zEl2oqF#-};B?x=fQ{~l$g6s{39SUd%CNkQMy8KsVtMyI6E9FXhIiY2Wa`{<61tUIf zn#1!Dyfx^Pb>ckLxjd@@Qv*JAs))*^AJmsRoSMz5UhB`w-I~qXuhN`6Pp@S^9_wMz zsDM${pLeOgQK7N_T$DYYm;QoEA#;=~Pxf~)l99Cr>GT+W1rSAnul?NaDAq7s_~kv=Qr-z|+Gc)@JhX~X+#fNi z+2>e%;e6D+PM zDdXs`>T)$&jXB2)vvd0w)rpa2xys)`Zb!)XGYFuLoh%R1cXNSBElJbTymJ%#sNToA z+*1sXN6kx@^tj+^pb-_{;4B0oW+v|`>63&9?azxwN1#d?AvYnL#P{ea0jDC9e$N0H zEy`>@$0?Vq`0=k-rZF-y%Kox7kp$&)d2Ss}t(fJ3VRMt}Jsf^L_?+;38N+5>Npy2( z=HaCDFmkJx)tLvQVcU!=62P5s9Y$6HyJ<9<8wO3e1teZ)|6cMkJPJuExpKZhAC}wE zSZ4Z`6U+8_BchjQGdiZght(w8X35m(ixAVYNUt8@rtRP(tabN83D)F=VbWLG8#Z!f zpaA_UE_M?HYes6Y1SluuT7^1)@B-uy8P-~+|g{v4Kz9S$M_^S#=pjBrK+EOZ6^_PzP0xijA(|7N~5n<%({V@8%| zT2#L3*h017cLgRA>35Yz?$YK!(s$>J^$h>^HQ-t#6x3|OoX>v4N41N|gISOOzZ_mo zaLLb-$uK%v8+@a3;u2)avBwY;_W4?8hn=x;&@IT$eP*+uKA-rIfE5ZQ=|aIgCzF}6 z`HJivn&Xj$^2c7aA#1Tr{e#9K8Zxyj$48S933^9|{kt*DM(G9e`QXB~;kCW!)H#x1 zTbHGAFo?>}w+oZcSIUx+U>8WJKRtimoc^sHt2AhU%1%JoK`8V*^2b&Vio)8#M#Sbg zO$<|;HmJHU3iqn)1qzB|hpnI1UsWlw$W;qJ-8HqC!29YSzghq74?X~Z560r7s-cJV z#R(h#F8}F=EsF0E;;2cy2>4P1$kwov=p6|>_18SP!^6XI&btC9`mI9%IrD|;n_LrA z-)#H2PBS$dzimvF<@jRJ<(t=E%NxYmgyXQ7VD z#9kApEH5afTjtLH92fwn4q;_V*qWQv-66?VUAG@KmREQbNSA0JC|Mj7SbbC8Wp8yB z63wXNJ7<4Nv)mV_@oUYIE>|LtJxlOA&dE+X#c}kfQ;q858NdGZ z+HuUxe$rY~6(uKH)?L_M$DOBPHH(hGpGX2PB6Y!)XMG^>${4C(P6jf=o~LWsNDBI# ze7n5UD(54RjFY~3ytQa~aM@3K88p(xoKtFinlDzLa502I6I&)Fw<$XsZDTCE z@{=*!*4W8rYxEs+_J~vrrm0++#EVOHDsF^I5^%~Qk;xvwcsbRdU`+q#9b>|tonwB4PH1~K5%Nc*ETEr56v2#uE-%9zepF++3-$GP|V zD451vxVig#x*Y>g`qI&num(%pGbR`GmV$6cjV&a_2~K0WqO;KHk-FUs%GZpDA{DJ-^XPu|N0cRBW9fIA&RA+dwb&dnRz9PA$tG955CM! zXB2moIPbfesZ~xJGER=4h`R1P+i|Bs!s|R4QQUaFlWXAZwyV>{25h#9?2g;Zc}B7n zgr*IOl3U-}wsD9EcP2e4s2OO_9(oIu7rYu8k0nZqN(X}1ufoG1EeA<{$i0$h{Y%M% zpG5jOuD~Yz%G6Qsa+QKE^LB3=~70wSuED)0J{U+P+rLw)T112A%?%4Rbipd?fOi@moF%X0hL zMHN8_K@bom1f^9(Kwi2O=@3B>Bt#lt8l+26X(SYB73uB{k&sqt>28p2IO74=`qtiO zoqfLj`{!KeT<0GzKzQC~&N=3o_ZZ_I_biQocBl*pYkNy0p?)4G%tN>HBZPMyTd@I>AF9^8@YvS-E3Si zi^vaiu3CX@a~n_EH{DE;e9O#9j}J)xCF8_C-G3#Os&pWE;(Vr)EfQv~M!|i^VJ~e4 z$3u_!@!|PLwVIo&j?P+zWRVqzPfO3EG@T~$)r$?{Q3plKULjhQ&gEBCQtdk?IH2it zYN#W-ezLQZTWbOjZPKdTS(5!Op^{@DY{Qtu!w5e3(_39Z%stZKRz^1$V`>CyRaruk ztm4IN_p;SZ0nFPBRZ9ZO6M7ujJPcI_3$E$t^DE9o9@9^+{HTK`HVse< z?R-gtthV{uKTByUQg68MUt3tbWox?n0dqZDcca^A>lPLI-)}`U=e3Kk@oL z$Py7{)vQqF9_^V3W+K|I8G|Ox{kbooJ@MogSIr<&STocMYA=`T1SB z(>Ld4r}yH*yy}_FjtnwsSG!ddU#R2TsLqwnbLgH4?3^#oU2mLMwQ=Ze;sQ~=e21j; z!F`L0^3?{2AO`y<^aq=irxt%bZYKpKlFf702q9IXL}HZoT!adu zo>6yMvLk@Mh>K~vLaki6sPa7MGNI5(*Qt?I7S7vMq$fAn5TNy64s+v2bwX$;iETxt z?^SKhUV^&*8GuY2f!;DL;VCLD>dCEgw#wt4pD2V}-{ZSNNb|3#yg{YM#pv;k zQb9^@$9gI@+|~TuoU@zZe#u0)-(mp&BF}>)buH2+6?*iFTS)wCW*Frs5nWQuQOL8C zoY5;eO5R(jLK1lC!;Wp?dB3wBzj1!^pVO8LC&I|U&T{ikKmSkH9e4pLNBzo2o6}Gh zu5YHNILQcd6{UaCS)%8gYPMecHQue9=^*H`F=2S|)Zx@-3k6rZ>NQoPc_m$f$cN7^ z#o6h8rR3asue*qLe4_kr$>FNKv*<2%d9Z3|hql{3HEKe(Q}!3re2A9O}9t-g1mcD za^dWE&C7S+SxvR3V`Y|SURa3e+aw1B)KDw0lBg1`94CtJWTzD3D3`aJIpDZhJGD0W z6t80{Xs{ri&ZUb@JF|gJRwb-L)27bYa5k=&W=6YPGlj!{P7FmEB9$_MgOXNNf4-o5?(nK=`ibR30 ztG^hvNGN#)v2N17|H-=lBS4zVZYR~5`9K@ako?OgAgP5ibufv*nA+xP$RjR; z?+-PVSFY@~CMyW-iWx_%|N4DBcd2lx$83nJGxyFpYA3YTe)hsS+u6<^8)|7r>@CsD z0l=1+uD-^$R%yTHF5(FjM07iw9K#Ya*FKy)0|+p}E@FT@Fo2Mf_%S6>U>i2@*zSeegr&n@8877y+TLFx zloSFCKc33VDSsBes7WG@I|9|erH+TY?j2-6BtlCJo)dim_F)+EntK17IAYYcx$HS? zObB>MY_O(jJemPA^>7@WHNon~Pm!B_!s&oHdL1UMb=c;$$ax&ZANBmxAN|jD2e9%! zWLPlwuW^pe9F2@p7~W(#Hvx3GFGIr^dd-o zlM+heML6_*wdF-$eiC6|d%>Smdi>+O`(J>~KW|ebN85X2u@?Vb0HFw=={nP@_5Iu< zKtaCkq8**pVE2Sig!Z`jT6Kc(o3gtdDqH8TsPq`Rb<`THVArStbVDGE2mO%;%l`kw zjQ(y-ATK=Gz1en*-^VvyY>83Jq9;6lA+1Qd0T4mc6oG}u%+>DO0pBcY#{{+2RupISINEdRfA(BD@!Vy1kqz*`hC_Z_kc;I2uMotmpC9_S zeHoe}WqKrDO$GCOc&(}I=-VrQ0x`PVI+tPGV(vr5On$duM~5S4wrQ@#-}as6|7Snw zki!0dsvk~v^g?3CVUW2P^L0<46zWY{R?#;%LOMg>Ye`-wO?r zIVp< zVII3QuX_)%PhtuX4cjf^(D}n$F(Qz%@A}`Tv(VF{CShct8FCz8`$q zm%t3PVViBVJOtN!1&Is8l~iPk{|?T&#F6EI0c0WN^8B1;Jmg#2E5`u@_Z5;0U}OrI zThUI{l5{XP-iYr*;r;DJ+kX8uqbe|?St{=wj?Nr0`ad)3S$!KkrZ99a%*jAyVha<0{_9NPu>h9`3O_Ftvg z%bq@258j1ei}uxP5e&Sd3O9D0_G?Q_H*ek%{#4bXDg{M)`akAqk%Syqe;^{x=lJ+! znXns38MrQxCi4{8Qz)E$gzI`zwJTjI1Re9H7)96Tw#AGHVUt|2*neVCL#!hTlpc9F z-0*ZltRwvrPhCN;goe}|?R`RQfAC*NX$Qm=Tp>a-*(#Y@>A-`69R0z4XeG#ZST%@G zNVp2EIad`wd4k;X1u3Oob;cyuTrSBAu%9HT|}Ib6x-wKcwnwv zh0dXi7vLtbpAJ*eQ%#WAR638Ev`0XRPyY`J%iJR6WYs}qbSK$8UVYa>_$Wp^5u?6|0L zNtG*cv~M!Hi#!LW5+jF>!Y%BjL`+=d;`+cy&Mv4#37dHcaV=JqLfMY?(f9 zjBHs1`;+5E8U>C4$vOQUv&m=T+#n#g;Ie-e`lS?B8I z&!;H81Mdvm|CG>(I6f?BJz#^LFS0+2q7|8^g;w4V^TDh#uSJ#obbSeFiCoNl-<t2zhI*!nmtAE`lQk$Az6eh(u<`z(PQ z*89sCBcw+&p=Vzx$jKSN^i@;a;K&l(Me<;G{%AywSz5yT@Bq)eEH?#T-&2VFSp$>L z_lub^I|U};w*YrA&H$!drIwmU@5UNxQZLf|naoS@h~;|;2!WB-1G9+djYzG}lOzo) zFAV<&gkJZNXDG`1cETH;1X#&NrNEaJw8euNz~oXBZ+yI_=N|%|^YE?zj!ca(JY)EE z3csn9WmUBL&EVgNH{jVLef$dB6E+<(6C(o~&CNV9Xa9AhiAZ9BLH(>g5M+h%K;E#G z(u4I;fqna%*XblTGv89}1|Jn+0(eq4LsGd5+iN@R9~?-uSCj9PB*p+gz$VjPcKZNCKD)p%`x9mI?|7Fb!m! zi~HjOn85{n7@r}7RkwhbYWPuYf9v`U0((p;&W{Mk%hn;B3gZs|A%1qAN`VnQL(X%I zODezxZ8yq{!3Go=g&ZP-R!a`&lN$tjK-3L+P~|BH)!eQDyP3dm4w+>S_yw%$ONH{VCfp``(vLl; zc&&_TeMtF$M7UN@<7Nacr8{tjb)-DF#;TShHqjJTIHCae3Ib(aj?1J&5@x$%(0&Xb zZo*SYjI#29x{Sf$!DOU)3Y@U&W%k+fg6qnq{c48M@r6UKkASN30P@MUU$DrgUy^Cv zgMP5JZ*+k@1(5GfhkGPuo7gJz#)jD)amqwtBRT^N+;Qs&8*-Ki(|Q&UEv$x>{d=p7 zg6svcmnhf8I#&MKYn9|L-L09xl6k#zu-u7Y$Mt8(o%P410lkZCTn|#z=7b%McPM+c zxWAEtvEPraIJQv>RWN~pUpG0B9Y+YJA<{F}#X@#wR9sF1=lbL7SkV`!XMhlrmwVHW z2Y8!OaBo06bnxaoZ(HrU91|RLmIOF12N#bu>2<_X9$a!Xejj+x4)L=kV*A*f-MChfjhsLPOD3Wdrz!~aomw9Ms1p)2E0`4v zi=7&ySu*qdK2sB>7!wJv6xjIps=@U2uC#O4janY1CYer&Hol!B-`{H&hn|)gmCU^d zKVHe@&kcRvdVKhr;Ive(dQNcd z4Hx&v5C`r7;X8@;mlO;xpal26i7fPF%k4XDKwFSd`*#oO^+vp0+XJlHwb{O*=@l8= zt8LlETy`Uj4=N{R(;w}YQVcv$U8gL(??0E}a}^C)+nue*g^~ZEG4BW$qOpsFQS25%@=RqHCCK@S2us*mL&H< zsi*1gjB(psxkKh$gC(&kzR-^ITlGOr&DiT|)L}y>>q9Jc5{UntX!79xN2KfAkuB?n zHR@nlH5C4x?-)=%`=nCfCBgZz)#lRZ2$ZSG zDQ02{R?QOSsTijW{P3N%8QnW6psd+bzZCA94c_$uh?c-jz-iaNLboKetI2`6f!j+( zylrQO=A%c@lW)e62J!hv64<01NuU>^^6~b|w9H<^aFy8s{3Z(1%t8G~g z{i0w*?Q8uqG98~RNlp8+MMp}2y*mTq|F<#SlHQpUkxKLL7jH|PfPIKL? zLh(+0zzWG_4|HB6eaL!}zZ02DrvS))Gna9;fDzLfMlpe?=r9sDN{BTYOIJD?p)7XU|q! zo+L);Z|YVjz~=9%Y6w(-UWI+5cR;$Q6~)qWS?~0da5>HU(q(s}_vU_;;pXCiBlH5S zZx9#Oa-mDsa<1vuJrNQ%)5y&J>SXdWM9D^N+nQ@}hWo){buLF8&&{))rg7g1HN!Inr7?9Mt|Gccu7@%i-?QZk|)v znn)Ny$>L7rLM$n>{d1Sl7zcrvnbq|$CgWeZY}9#!{)KyPa5=oDpk?*|{eFAo}zs!ro0bFVwQ^BY}O6@RAW%N&Ds=vdOWT zJ?;4*fA#*F9&DPA6a&wmio54dChqesg;J#q@yzi@Ht)t}FuNS+tWC-%bS>=8bWt`= zZw`G{w|zRj@ro6CjTX`B>n&3hoai*orBEg7r}Y7vC9@GPme7qR0=5+WA9E%$6?X(T z_15@jy_we5Rhw*NqDwnBDjuzGudG}4QT_MFv1jJOtH_nfk35A1X@{EiW)Qyg#p7=m%*$ln*QV9Swg3rl`OL zC9RCBTAw2dQ7Y*s-4g4q35+dES$13l4o;?|%*_671_>)u!dl!1yC$7w`9A7))0vOV znStgP-@BBqyd%hk9)5cuqCH^a!Vv8&-8IH;N<)EqP%&bKPrefc_|Gn3MD^Kh_yB}C z%^BoPi2cHk0dVYAqEA zM0tU2l0>RO*GxJ!zPz9$yJ4k^H$5G2osLi}AE@_4kjnL~hZ487w7Vkw3%m0p=Fgu$ zZ&{Ake7&7OTbBhcB%TkfnP})|**t@`fD)74#37miYt~mHz9qC#T@Vg#c z*jq%Xa0zdlS)qrWW@(AHU;08L=8(zGI6H-)&F76p!JV>ZI)zJ-YtK3Yu^Zf?@|@RE z4>D~MR9temKM+U=^NP-OxyF5QIit__hAB}tpUo!bxc^M>VvU`{3S@i>A=K#i&HOdVY8vMzROf+&y;vX&I7n&j!cF-*-O}AQ>4YmDnmxGHa zQkJWx+v~&6TKIwjmj2lvPCEIWS1j+R;)T&scQT(m4-q{u!yw*l5+tChnj35QjZ=%F zTb&kJEvjI&&1_sDM-^NOC_~kUxX%9klb!d57(cWqUw0e~)13_&M$&`AS0!uY@z>Y{ zWlHT158wDA{l2^QzA0L28V&(1sh4#Pj3#^(9?XxArYOZlsOQUcQ_InO?>an431<^d zE%8@3=)EbZ;pm8r`R$;H0JPmM;qqBz0rP_SRDR-HX&(E}9nw z`DU>m6iuTSh7Kz;=WZ3L!HJ%(-g!0E@bI%xoIBU1CY)kIbRa z{=ezQ-pz17N7k%#_)%eQ^e1Va`H)um-d+d=$73(*?neL0-g_zfk%L#QU3K=0zn0#& zwyffpQNKNG1T!c>JlY1 zvR@ONw*#B3oCSB*yOyzVlQq?^g^Mf<#7Eld&tU9WwqGjGH44Z7(i|;!>Xje}`VGt+ z6mSG?JLw*f&HgA(#{X8aw@9|jF;g+%Xn?7!Wh$vb^;5CdXhmf`hf zJ)XDc?NlI;HCrI(MO++|bdf+dS*8#1cNn<#E|!n?INOYB$zqLqKIptQ_H&qJN#EJw zY;iR8(TXippNfte657eIY(HI+(b!Uws-;=l%JsG>ahdg9OWaQpjP23mn$sZ13gOf{Ly<|G_MRfwhwTcJrr@Lo!^@n$zE9Tj5m8=xbM8`?a2-IFCbeA}=}cU?^dzYk1U<{@$_Yuw zE744_-BsZ$t$B$w$8HSCgz?Jg#zvTaO)!jc`!P6?r@M>VHROd#e7Cmi{d{Rs)1I}( z{_b1bGc(~T6KU4C)Bf8-vp>(jv{m(;ylQL7n{U!3%R~}XvQC|9-B#Hn6p^_#V>mZc zf4a~8dT#x6XU32~)3T=X%*^c8_nQbTg2*T_IQ{@4ywLX1m)D@Jy<(tD32~xBZkv^! za}~RfdX_&ASqI`rny3h=4rOe&tfoU6DkkJ7EruE_e6}TwI|o)>AUrJ~qcw6&O7+^; zqCdH86_~MyZjR8|iWx=xduLR{Kk`~?+i)V-WIKUl-avBg>U6n+>w^g&rapehnCNUt zeVG^?!Nsz~j~U4tN_O2q;o09YQBB&cN<{apeM=(RD3?_LgSyF2jB0V)eIUraynS6$ z+u>8BT$LO{EB)SE^{>JmfIb9dAN54#|CL z5J5Ln{CPhle`q0AHRpQ@0%x`s2i3m9{ftY|OIYJIF*r;kQ43^8Z zGgYD?8dC4+$ZA+9nJHl8o0|_#v0v`p$aXO(4R({HaCf8q4@S~t6TspHE_Mrty`X1|CPdqNL+pbN8)%S?|Af06%Nf$E=5byS}E!Sb1i z{T*d|>fK;H!iDsbry@&T5$p>W@yR#xZrsom-Q8H|98Y}Rm(}D9&Cxc(*BC=T!={%~ zw@-ka*vgpwc@;ar7f8Mu>fB%uRSb}u4@>#-5V4IjNCs7e$e9X*?2I##WF-Jwc@hGM zNRM>bo}>RQq&)xIIeGY$lru<5ehbG!;G*yxt>dUY2e$3b5yM2J$^|}m^Jxt>g13rr zA*{&gw_Nh`J!Q$1_>~?>Pmhjr+F}N4xI_Bf`~;Q4D}=~-j069s5uZUM~4A+5faI``jcNqoS-UXu4~@% zFGgEh(k_nMysts#O2auJKqMFsUV0H9`SgD+hWtzN9=6r7gvuxrWFhy`UQBzBHPCj< z9HZBhn@~IG&m^Kl#y@%$Fl&)jeK|Pqn&>Ek5G0T7?c3HtBx!XLTz2_MtSzCSrNBi`K9}PJ*l-2R z$S&6tPviv9KvLYQi$!*I@cAL_I_CjWGgvN%^MT|AymS%wiT{l(KV%b+-HI2qN`)-v z5`1C`V0v*cQQ`Ql`$0dzs#4q!N{fVEsV5-M*hszE3ZHLh#V7j&0!aEBLP`>}4OoD2 zH%}v<4mFTt&+LVGW_4cRz@Nmtjm*`X3mZ$uut@#uS!SfRe{liypP50xUi{#k_=^)5 z%fw)!u3e&QHOqR0vuj6XLwEOGn4QILFCt_vERn*IM)BC-MR*r^`PWjQ&lFlyYdDKd zUkn2n89eddFAYHFE@R>B7b7r1R}3nJx;8$q82Ibk(L#T6t=cd<`xNZAVJ>Jhz(~EW z+4b{-hv{#ax#q>rZafxEW&9BtAWU3?Yv!5a9d)pb?4; z)55Y_m=hk?DXnGPeck_eTUm?r!_dH#txMrFgcrRH?H_qo6VgaG)1QiN7>OPC@=!Q! z0qT$QIpL88POt}cG)#i?aA0np7VRN9t|b;>Pan@O6pfBLNfLAec*RTYmb#{Y#D$D5 zG9K^~51K}V|H+bgfq{8Hyi{=g+`**hH^(MIX~WD3;9#|8G!+w&(J$d4p04!gtb`MP4hxgj4me>2h2*q2yTT&6T+8L-J#?CGu@Vgvp&m$QXL=49M--F?yv3{4r}0 z+G}9=1;7vjSM<qq{i~bd-wYskktYDu7z_r;xnOOFBf(vn=gHra?HL!lNG=wPZ9#NX3b*AJ zkx11=552x6#y;oh-tXkV^FqKqw%*k@y6_ph*~ocT&G`7>oP^L1ocCEQ!3zGb7Pzce z=z^{{as=Rjara~su~R{qP<6M;qU)_1u#HMF8VZKw3bsp1C)kmy2(kt@F;Hlez5-SX z#Jr6#UlCB7&?J7T*FKr4V5Vu_rY)x~0SYg;_T}1maYWV#6RnIyvS8mVr=`2e^ku>E zLqw{aV4jxbj6rq?15Ps^g_C7M#kS?;TS-6hASRZon%h@@kA4qdgDQwf&VpTtX@x7A z^H>@L#x)3z&B0Jg2L2m*g_N9eN7ftC=N4)u-fDqEk;Twj>aN!Ns)2l(FlMl6Wh8oa zT{rTh+@C@GhBR^m5=Ndls>P2gVIRFcn^4Lcu*-DL|8}grz(_d>Ut@1weuLf}(2LBZ z={swBd}O%0+ksUNs{I6ICm!gsBZ<9j?_xFQ=(MaDPXsKYD+lU`~4nf&hl{reqRI(LwsI;L3X97L;wRXtAUOZ5i112+=p<&LDAy{lblq2^0O7~TUFgKsitR5M)KZpA z1Jaum>+rfOYcf0Z8G&c;_%oM8XpHN~=nxw@3Fd|6wPe^0-6;8@?c77oaSB4)VxW@I z-Knab4&oXq#_b8e;L>f;fk?P&xWeU(3mIe{f0gWS^g&1iRl%qGJL^}KlirwBY#YF> zNivLH93x8fvCYs_>Uce*A7*Pgxw4z7Fr$!+=7A%Co|`y`frQ{&BWAfr_{Ts3OO@V@AD%8P#L3cZKpQhb_{-NXEay=K^`PBkSN{C2_Wj!?$ z@vOk_s#7RJlb@fxHz1_}&9hpY19sYwwoHt1Oo1{>A|6}WJxJldE&gD>_zo#=&U1hc zs4@^zxSTf70L=Sd$w3t%tLc3k)Nf7uz_a8F9qw6!cAzwLW0zY^HYcAG+7fwj8b4=F z9|fXOB~qaNavx+w7NQkToj#lOMGYpw)Cndf_p&;uz;Nk(BMkqL1`k3_BjsPXdi@hF z>D34>KpK{Kg{2&1Lb;r@~vm+h=FRQ_edv>a!2pijsRl8NXoC6Kw{e+8GW^|?3f zt!C+by`@{{_q9&{HUqI9RKHa-%QqrG1I6gnbxs1}fbbLOhG2$gnyb+`-AL7#k~!RB zMugCyg0o3*v)>v;QabXA5`AI=s=z!-{HI5OR~5n?An~+zF62>nAAiIdHzch?brp;o zU+2i((&5qfxpMbTHfTGZrh_Cd z@uD?~ttN8pu7^u3g+FfW57$2!C<~bt>CwBLU^nEV8Yr}rg#WFX4pWY1scbc1zX{Vk z*P!JmsF2J*Y>C5a8IX6bWZEXBTv=!+5NNXDmEbQ*|;U{!YCu?9)^r0bJEA$$+A59)$GKN zmvO=nS3f)RpSXHMbw0xLF3YuKC`mp-0_vhMV-UpHaFJ!~V7Frk=l{@LUq+S;g{q5o zD9vZR`jDt#6ydNF3mt` zM#}*?q;NzX*m?`m3eMF4UP)pd|D&}{e#d7!`x!WYM&QRb_QetJZQHGBxTIGCWlpGl z0!v1AOZPdIwQ2~Cx9odejKot*Xpm71ETa^#&$>}EeZ?v9O>xM#eumHoP*wWCu}`zZ zZW=Bz8*b6$*Y39vX8w&>03`#hxtCAH+$L(@tU@=~*Y&ZuPkjU`xgmJr4#L9`8UFSM zbmZ(Gr*Ylg`{4XA>t>q$5iZfrW%OO-aJ$WIUU#g(Y#;^k!-0Yu?_Csvx2Y&l;Y%RP z@pK8rvBdAV(!kVNY(3?-c`N*8qvxGTB74B!?Rm!Sw}65X4U!AJ1d$nV8*kq`2l_#f zr!n=?Tf7Ad0#WfNZTHioWh70f(k(OO%`8RWuqqn|{_7P*T3`5AhzlsG`j$cJ{aD$xkcwpF)yl~hR z&|t$uX|H2wyR5%OWHWAPmU!w*x3+#gnsn;|!m|+9Mv(##o}3qRp#T+Fg{**EGCkvx zmv5u|j-Ps`pcvW=j}ZNBrZ;0ijp{eQ(YkUJXB2XFo>EFD(7zgl_B}32KU4(A4^ynr!h2y|! z!Za}ZIG%R@(`@AlDn~3rch`5uyVf^Gx&Bp!m9{0SfC4>$nV) zTgUOATyuKx5sL*_00J16_>pFn`_H0nyVNLnEFQnB2I=s7u|h7&Ai02k@X>yGl!Ht} zcy~VcdUxuB)OXTvuj=;+uj$s^vRl+B-=2)@o#pm=NoOelH!?#w;C8q>ga||_gZLrn z&5b1u0`_m;+g=TvwO;R3O$A=+Rgj~ju7>!5)q2DY)W~-XDJb%sEW>07i%|_i{tzVE}uVY>oPw zVz0HimJ>wE7U@5aho8*={jCFdqZu&0y^lWvB~-n_*+D!^)G<<&1fZ59P4Z-ry+qj; z`jO|rb%Vh|D7IL!YX&SLZ4{5`_YWRQ9Fv~Sp80S^N(Uh5M7D~p+rXa91Mz!8*N!Ab zjy^MxcJ3&5vg3aZ^t7gCR`bC!6#8(jT|xhnZv>mRkUurQ$|Se(0UCH!PH5HyUVT%c;`t82^qYx&todSVU~PDPs@uV zO~@b1+r8HNSs_IelRgqU=&i&=FvY64F|WLp)7Xv` zbb7}5W2=T(VHnDV)1cew{q0*6Z*CAN5^jW-MRVxmqRa=;>Y8A@Wf0OEV1#fBLjZJ> z_`M1}4$}j*Gfhu;Lxn-Uv>rNRt}RJ63jTo?>On0S}wA`|<|l zY2+BCLt}lPW8pXb1v|?z-l6NXHWKbNfZRA z$X=67`57-0`4q4BcSPeHUOdU+yPG<<>HHl8L(#ZNN)rA=CyB5hV|ei4kXL;}ERYA4 zrpoHh4Hzg)_=l z`#WX(Gpmd=NY%piMvJHJ7A1y;p?z31shKdY&|(~1CQL?;){H+gFV|;eW5I*#k4zb# zvIH8mMj0QZtLHb$zOo9Aw(`;T(zvWpY_-_W3;M5EaR2+Q^R+4HPeq>|kCL%6-DM%~ zc?B^@Z)p2xDdIc6pFC3+d5N0XgrskZqn7b}jkh3(Hx$Dk;;)uG;lnA$} z!A{rZMz77!T~MW!(xR7*aA;%2*q=0VYk((E^FhufrFU>fs=!Mvki8V6fTDcl% z275DbMEJ#ig;jD;6}?U+7xeWtuFqp!<(ORH#j@X@f%skgRxv68KVI+C`%(5#`F?x+ zkrv_1@G{XU+epgHJD{41Vqs*7g-p~_*S0g5T2G-rLqB7o?3qO**VA{&kw0T&lc7~0 z@^ED@p=LBcj8Zr-wBecQGvVufnlYOD%Di9=AMc2CUtX$H50V>P##@VHh{SO5jOwkp zSGsuG#El{H)8Y0Azcue+tznVKJGmcAYHNXS&^|(()Rz%c^0-Ya-McpG%NFqfub;g5 z_Q;o5-ePT#DJ0gZ_9xyZ5%jZpvcu6xVHPS#a=$-}cu8fjx5kKcvCUiOQkxx~qB=Vl z#mhR#e#-WekVNq$3|oZBp=pM?zji40^LRJ1J(Z5cz{2%he@&c5a*u>-F~{3wBus!i z;q4PoqBxBA&wZ{PuyAXvbMn!0^wwB0S8AMP@$F#~XS#{u`$KRq{4oBWcOOLVmlmh(fe)O4rpJuYSTC0DGm zV}=xC(>L};@=eEHm9B|k#rfT*ndJtIZJIgWY2*%~#&!NdQhN>{)jVk^{#@}Y$5lTn zkb2g~)Dfd>D+L#Xx{qSV@T?A|tPgw=I`v*=ad~qQCVGV+6i@0y{)-&%Zk&V`T`__~ z%Q3?RXmgm1I-BPoYv@CjkQIl1@=HoDFWs}y-x#*kx=g0=EuD{oLt>#l?Il|gkjnzbCx=5rHbHDLg zj+Ckk5#dQ9iwhpi`oxvZ8pfmKSYHnf#RzNhu>79tdJx$D^Xi&!8=b4c? zsdE>#?Aun3zSQPLFaGmhLYA}ZN6rTq+v}EPIy6z)tf8!aepW-(mAMW3hIYL*(-h*I zmby-w!b%1fw!(d1{ePT-?f_q9l;W$Kx4%TcPVI-XK?IJ5S=4X+S3Plk1wRjD9jgh?MKV`9gI2L4Zm$!-G(Q82eji| z=22H7;#V~cQX~^R$MZwa(S>G)%I)nbrL3xlUA}WV_Z;0@W`BFl_)vqI^ZNFnl-pt$ z@F}WW^C0G&q{fM=T8#ecCdPyjdZu@GdhZsu%n4)`3&gTmZaa*)?D`g04jQF2B33_9P~3%dZ|Q zNrN2RL^R3BVj7D&5BC>U(%;)b7xkH)d4x$7`K%1Ob@rR1#?-x9R+wFQ!oKoin~~g& z8XGQ6rwf+T_}n;T-Rd7Cr*ZEaR(F)!6K$Tvs_Q&peAXV^hjqobg!+O`P00(G#{A6Y zd~uF}EO+o8iv1B@ll}&^DurMedeoXOx5dKM`>-whu>p|}C!E)b^5Ixt&RKI<|HTEE z=bU0b(%fD$oYh=k^N8;5BueHp>Uas6Vs&QBM)72hOz(o8nB z#`_-bY1iJOD>g+|FRWe#@jC~4k@nVf7-uB0$eXPAhJ>v9O@EXf38R^t7-wl8ei%BX9qhZTwGgh#HQQXI2^eJqI zIFq@_`Yy* zV=;Xw%rrf~-E}AVt5*_&!s4z)zW?--a?ryP2d7!3sEJV(k41^uoP6e+a$wmd%%62< zIJB-6t@!>>mDQ=Yj(rk-j!fgCgjCbU>SeE$@N+oMMI*QZjdnuVza3lV@HVH0?C~f3 zg)<{#u0-1JKgJc(Vqy*>*QuSmp~U<9i~BhW0aY~u{ffC)vCqTKiT+<4b~z3Ft{$#= z;1C1faQ2azbZZUrPdR8(g!}pB$m0n!?;}eEvJf+nP0M$V$K7qOMOg5P$I3+U1Wdcz@%0V&Dl)x; zUlRvMVNWcPN8c%~8RGoq8S>7La5PLN|^C z+&R5G!mlrRlN-JD!z3E z{mEB=+);K!)Ut;1y!eBnrgIszmz4^_iCajRNNmQX&CaqUc#Y6=w2!f4RIj%(a!mPL z+;|(r<@bD8np^=kVbIs_Xk3Z}d%C9^tQ-{p3dFX*Wm`3{4L-KK5>YuOO)HKnp4DH& zQnPvz#m!tsG=h)Qx8xdQ!A02qEPILMo&XI?Xpy?Nz7oCV&uDI1+3ng$ZuyAAgWV;@ zj>uiBGW)?gM)QDV@TZjYs+GmR8s3Trny%UiJqmIvDRN*W3_@Eiv^>RXlW3Gvm2MSz zd{HQ~_$_L=r0%V`K%q-D2IBs?}6{oxNAgK z2D>%`_x6@ixg4pKCg0E_*kk3=z_P>T8*f}&`oB>P z*03JOjkA6VKI%tE?TZ8;wHm72y-$;21eGM)Sanj03HP7SpH&t7Eu#aG6{F!b?nZ_L z^G|z^P4d9B$EsiAz0)I}IHM|lZ}i>`i!mQ(@hjsXD6r>$-}@TZ*4-91lr&R;$D#hM z6O}yM@#1P<{V&&O1dWM)t^^PV&`JH}zSo~8sCmjL^@t$RSj?n{W!;sRw;brGD zM5+NdJIVBM&EFw?rdyn&Ga!J=ty`6)*LVXL=fM95h2EXPGH)F{a@Eg(%=U5;n8!@$ zR%{v)zHP0zJkntJ${Zgr6Gri|rr_n!`x}8D+tD<43C*n@c6$>u`4L)m%3PvS^+{+7 zV~ZTh6_yRJSAL#>%~KGB5yb6O_T^*Is8bem4)esr(}7ds3FGy4zCl=6gm>v)%5O=s zl{&0Otr!?PvDVKsi5<{3(yIEXC!rL9& zljEeEqa*iD@c#g#g*5F>>GnIrL3W=0N^cEs$n(eKeKa%a0Lq5^S?!2RC_PT?5syj zcAxW(|5Nsx?U_n3mbzV(217a&U%sL2ddFGfoza3$r|X#RrUT$0^cbcij7R&-QpO$(_&NM96OY-}k%Xg7drZe+5+Rk7rzXag? zhUmNPx6+eu(JKMkA81&6Nv7$>n>S`kD9OhrKd0e)h&C6ddo9?^hsu)}H2)r5VC)@d z6{TiFVxUDb;RzSg^q+38rNhxWR zMp9bo6hvCeMGDd&rQjkYLFyGwq#HrHOX|*r=j^lZf1K}pXWV~ z`_6aHXFks}9aRLm(&H?DlJ+-ze_W--oEnz79=EH6#0vCY!;+VMJ0v1t=;G$Q zt6_#(Y8TJz1yoSX55_2NOrQUdH`)wrECu?tu|rIzaH@tHeYVd=-#SV85yKT-pAoIr ztZ%F7azc$6wv0Q{-!s3WM?X23_mXN3yJ9V7N51k%y}s#LIepI7_tFW~EEV!}cRFmw z&V3vy2aD4#PyBu|RinIt?3Z0)de>&EhCJSx_MQednHrC;ZhU^I|4#X6vFypS8zwH* zaS6ToY~sen%|2R!YQr0elT-YiW~vyCP32zk)UVb`jCr)6&)!j?1Kz}J2~^L*4H zZKYQ9NlBZZ&R4gzTl#^G_+HJX=~+ou>R`c%w%k%%DVw+}*O#k3UVb-p_Hk>*Y3(I3 zu4G0cGzCe+<+B;j}QMn=Vr7w>pk{UAUf+I8@zvI)ccp2peeB2`JqQTn9YDgGy0pXUcPVs7mcj$8G#wj_st8uq5MJPvPn71&GL|2bbxAEQWM-cb{; zCc~A!c74{BolP^xq)(lV9<(4O*lJCb9!nM9(#$+^eB33%uS8UV3yDTV}e4!!Fw`{e|-Jf z7Zdg5*b^zubr_p*BF7To}+pGg>=Wg$kB+IuQ$J{q-;_=)-KOj zkW7`V*|@*Au^esB={iezRCtQ1aP+v~;89S|L3icEotRq>ThgqjJ@0GfHioj)=kIUj zg?@I=wq#Q0&>Bu(H#yE7_+c};Loi&N<3lxqBg2f`r4+JFjow{5cJbdY=%?WH*u<3P zQ#Bqd-Lm~%-e*Z&SCnisxzKz~^g8mkxqPt3gn@XGlbrqOX~Bhp(EK#_>Fri}?W$eU zg7=EkTwjx2(tcM1f_BpE8>tAk9^73QKPV^jtqEmn8HrDHLk@IihXQ;-{oX(3iB6BCg(_P4jW`NXjyUXc_s=f6!8wC!va3Hi` zND#Y7Q4hf+w>dIy{EitCwugQ|FuM%k%UxfLORwmpE~_yn(-01s4ls%T3>5!`H+dux zdsD*>%+rE(^-751(}>MRU6x>e{=sMj?7i}TfHie<7!UQ6Rqam(e9-gW(6dkMndQhYydr)Ja7nqUA zbk1*0WfE@Cyiz>4Y~I*FHjyIUsbJ(`LT25SOT!1#bVnjN4%PC}$3LmJWo#HUE{|#F zkKduu!edgRTpr9v2a;qBbYs55qz9NyQs0sRU6M3lRt{EqltC~i z%+7mj@fx^i6n8aB9n8LzSi`mrB;lZTUL6erFdjJ{2H?P3i*us5Dy%US$8D9$ot$AQ6|{!c5GT<_^NCZ&w|_BXiD z5aQ2%m*hHq$??lbwU-yc!BntysuN5ZxuujO90V*%N+6*6e{k2v+4F!z#eSiO0bFt# zMzLgw>>vE2dp2kOc7+Q1h^3jiY9DZJTXbHPhcRzOh5$ZNx6dm&LthBcH=LubE-~nc za(sr4l;aFl)p63rAY5EPo27x@tN4hRRofe|(HGUW{aLX(jZLTXB%Fs0?lAby5BhNQ zTDiI}r{K@KVZ`;;xrZ=*5d11SI43XTi^_5eHW7#^7i0p}kdZC`mzIP>p9hzf5En-A z@c9O1k1;B~B_tkd2q4{^LG_>XM4W!%NrzKfnktyCgt5O_pW!xZBjmgph${`~#*4uc z`x(2vRlRgYDmCc+|d~~7?>`|&1l+wI{$(wExaTu!uK1| zPz%c6L-j4b3`GmtJ=4|K}j|;ym^P)Cx6M`5u zw{<#b5)tp{i<_n!OZKROJ|sNGI`~sw=pfsGjex0(TmH!N*t4XK4ll`@gC1Eoa4cQ_ z@T2xu>cxQ^o0Ax3F1w>?57YZ3m=ah`+{Iws^_v-#y#irp(Uj+EhJkh{Dr zc!b$T;ze%oNyrD$l~J?vopaq`OiJ#^9)dYo|}ru5542Qf4k?sa^NR1{lf@rz`4wnlX+O(EgOdwNkww5bS8<0 z3xpJr*%OZ->5wNf`+E~!{Ciu7i!VNb&*YmLH=V$-56GOnT^B!9QgVTd{y5L6*kMd}#bP|qm|jHPL=Pz8Z!i!qUy!r{Jw zn?Bit`-W4N2~fPoSOYhluOR3uX=6j!ZNJ-KG$lXhvTC_qG91<|U|NSsahY6cKl;Uo z-3M3QhK22o5?5#HiCih0!N6)7)E*h^@_cR7qO8ZTWnWU!v@u(`D&^}d3j-g+$7S5D zc{`Ei)}V4QLpa+{?8Al@#yuW);ZuPV!W=?fLWiS6psm-N63}26AU34742eC{awx%9 zQckY6KalX*QAG*go_i_UaIf1`lp>)Ip$EclR$yvDn1LdRLKqW8_rMCEJDR6utYFy_ zJ(wk6)hWOLP6GEl_DI{(1uf3Ti?*$dA3RrFZHmVnT2?oGBTC$Fpn{%{Vofq&Vdme8 z3{r(sk7|1eto~#?6P%NWHVnu1s}4HLMHOx#R9CCViEh+R~K3GU9NS zKzP@c{K$O+ZJ6h&)y2tXwKwb1UylZ>=dW7zWj?0+@U~imcuDgZ&&ag5&@DOs_kL#v z$(Gm)sfi=g@q8!4QzcgIe3FA?#jxtri)A}2FNmKWUVrkoB#?w=e_>nCRGDU?g4^m_ zQ6(vN#jV$@`{bqiE#3$1&hgtmmc8#ItvBnNeG7u<0=qBt*5G2KOxN0zd%H4xh*>+xTt4qc)0$zYIk}pw$@ezxs$5q!Rr#nwSNgjn08Kijgbt}| z%`&ksByI0T&Lk>cGH(BqnykKTh{Q&C_v?T@w?lih^)z}LOv73S0ZF_`Nosgq_{?f% zWhmZeq1*JmgLzTW(Ca3W!=t5+imIX7sTC$Xlv;z4BS7H)Ho;uQ+)e5+8-&?DUmq1h zd%$@u;$C;OwedEA7TV^~TvGt&oZN@)!YJv8W|fy4TXkhDxj%CCLN;caVF>yu;+=lc zSg%{{Mw+Y%4Kt12?XF%o`IFE(x+|ig(uEsS-H$*MF?&)^ofbkNpd3;NGq zRVo#q`p<&)_^xvESxJE<8R0EvM)2ri=0h^4Uwo98uHC3B{lfIU^eI(>z%y+788j$E zxi(pp5=sWk+!)-S*@PhZA!6OszfCj8Hs({Nv1vS0Hg-`qEn_FF;`dTlb{zi`)(7bd z{sT*uAvetmjK2LaQ2B!`gvohm-EeU>?TkX3`QQ=OtoDK1a&2{@IzVFr;R7IpFIO~U zs$I91{m(XrtII=ZRAphDsz(|ySkvPE8+xr(-;V}c45L-g2qa{>q}rO3YQ7=)Ip0}0 zTI-fy>6(L6XuCI{9WT9KuxD$Jiq-5O$zS63pIc?{FBf2zA~+%uAPYjl1ftUAc0NJDdj z*%lV`!^pYc@ln3~2dl@y!8B45u0xU=P4)~|Y$(+-m`#;zlna86%_j7YCrb*bLPIzD z#@BBxjtaO<*E!aCAntU+^f%qOn3;N*!$M3Gb#Ea+tREsiZ;H->8*Uz$uk8IMxzJTfkLgfpa<#GRSd4^NhE zQWq_s1(|T4!Sx|P<);+)MMqS2Ik9;sEbA05bu8CdTol#X5=F9nD}5Y!h4w&K!BUc} z(P;t^KI=$MvY<+8?{yMp92k!omsqO?Xd%IEdW>X}gNmBQXNaWXvS-;kx~+sWh>PX| zh#wEgD<==GW--xC-a<>@pQ=-@qP~a1;sE@!BS7J$9_$GTFoXHI-;Fr^(CD_@y&29= zq-F$;_qNR6P^6KU7{GK&>Q{;iL(;0XYz6LdH^U;Oa+zsfO9@=lFeMmS32p&5STlmO zxBCq9q6btu2QiOBbEXwb4x5nn5SpCda{9t3ZZrECp)3f=SZw1ZTXV_X*LCfsEw9Bx zmLN(ase7D?p!2$nr94BZN-pxF88L1u7cYG>i~4i)%k+i1$A*#={WZ8A6HaRq(w=reIP!?h ztvd%R!-Fzyg1Mqj&~)tEbkc{GXmAM2EKnh>=-Qd@i6nl=3Be6gK(-V{tx`1JGNTg9 z9^W*7D4}Jlw%_F|=6at`U@N5kEZB6WXK9`V8^=qsd;%`ZIfc3auEj7TQ_Epvm{lGM z8KpgvR@eoe(j{IhdbAWp@dB2@W`jx+;6$;Znq70INdk@;k=Jz18Xps1rpPUuzIjU; zlgrnS_AuddMqJA1J8k0|SU)eBo!64xNaO{c#cBa#fxEUoczA|lP06!m$eWPbK=bNe zK=ecmt!|1`rqn@AA^H?kHT|t*mJ7^Tq$#z5XY^SaR-! z$7n9oObpdOrj^#?N)52QNT#TnrOrao-8Av#H0KaTV>70*F&4BEya7u+k?UfR^N4aK zV)UMD96#zX>m>4s;jl)Z7>ePxP(q&5`V4k>Fy=372>!i*rdpv=xAq%&eBZU(`SaUdL ztA$45YY98dl**jUlIvGB`SDA!r+thwj=V)nme_cb9|lR)9_i35wr%AXmi?-n<<}C< zZ%7ag{q!iH4$B%1x{)HH<3&mZas{m;j92 z-uG2e+EpXBzn#z%K)Z(`f-KbBS@?Eo1rF}`Ag{J7FW0t2Bnb(0^MA_mxn%_y$g>7S zYQRBP!2;F0p6hacb6wB28#!GYgS4&6I%nm;`c(b5H;-J0@N^E2C>qgv%kn9!_${Gk zW;7_$7;1>Y3_VFnpDD7Nx9z?031a+vdkcuvXx_2F4Mc;CAqh|E}bZ8&^&W7q)oBgq;83}Z#UjYR3l z_oa?FbYIosN0#t+6Znizi~f|C|1Nm6US?RKKRb4rYC2>Q{KclxTg?wd&YC|}#Pq#&DMh$7eucErMC)2$W zu?z7AK4U!`@Ozgdv}1s?#c622o)I~gX~l=sGZe^2`csw-n zJ7*u2dIMev1KkSh#N&YtrbLnNHS(mGvY=ep;(z+#h&)_+oT~zvib5TBkCcQIljrxCdRqj7y zwd?@GnRk&sdo}0r17qOHD&fKMdj}1k*$&#T|MR4Wuci{Z#rDR!;GWze>frU>x)75)miFl*+-!O{!($I@el<4r0^RtWV?VQ{Ct(#sRO!)IF~ zUcKMy?9H>oH_V48#=gGKr<0QIakdE#P_Ibr<)6#ZhU+$sjoF19)9xz#a`V-GbnO4` zIf)`jIjWCtvl~<`|6i^I)I~<5xSz#wO}Hx^hWE#Csgx41mboN$#3fcxC&Ii!metp@ z=lTZj*0H%$zMTP?qtYXKmbM{a5qHwSFQcAU4m`sGdHF+t5bwN%Up9FuU(gya@%~R< zpp5EuVtkpn38g88y9O(2Ym1`ZpW0}a0_v|H$-@`t?Q5U{ku@ss#?Hz&$QX;1g=6Uu zL;c0sd-N89RWT__a|1;u>lZqE-1x9L9;9RKBQnlPQpxKja5oqB_Oo2*@S@Ik#`1r) zGeH0F&Tgvif7=;`rfM2!to2L-JbB^r@`?uQBO?Am%;&N`%6`>)}_ z*}5H;@wGA<5NLUvJ!Kj+;QUL0IqnVQ(F=pG!Kf{x4EK0ISbP&zrkscE(Ias7BIykM z;RA@|JI7>D5$VHgR8A)Dgr&kq#Hx)4GuNLx;q+Ghxo{kaMzb|{)uK^x=Q`=7L8>5t z`f6KrJuY7avS;?O} z62Ul2B`lOVG=l&9L<3fdrksGI7;L<7B&y4I9j%)|d?-fD%Tu?~owqE&$_w>Dc;^F9 z8-36_vlMlOcsYMQi6m#Vp9A&hSn6moio?Fhnxm&IFUnsmCZ2u#xo{e>aKJ9)_!e|g zAL4^|9WEU0MGpJfgCf8hJlma@uJ)f@EtV8otwUw;FmCqY!HlkK)Qw9`;Zz|%K0TTN z2>s--?;_#Z6U73zpPA-n5UVTRXGU($eG3sg*{47EFoO|ZFZ|QM2n%sAJ-gr!L#m;q|n*dV(rI>f7V_5v|GREDN5ycnw?|Ol_brhdIy{G&UYF`mBc^qz>{$u z+}({qM@=f|#0>LOA^@760ZES}C}h7E+Zre&+`*?ototNC%3S>ORmLy8p@*oV5&!2C zx)}}kX5+_xN|j3po^35C}c#TC3b&Dbl~n3DnGe*u~i4B1=#SO2Vua#-m@it0cA zY>b&yGA6db?1o`|A7OB`Ww`%!l3p6 zRGdzyz!aBf8Cq`5po>Av%eVT+4rGH6VO{(29_ot3F)A4TJWjU}u|Kp9Iy|Aj9%l&E zF#eli=oeHRu9h=qp&0y(X4le?`?=xg(J$^7u%O6fsOJJV_GAD@ugr<7TM=|U{2;vu z0yhIp*`>ZecjYsPTBH=}8X0G6SiJDkpop8fi(B{VE1a{PfWLm}uLp@hqv6bqgpFr@ zgMf)Z?Y+D|u%77kD_o@o&03?R)@(NW4L?$!?GR2h7$|zSzCREDJN^3j^R@UjEGb_9@xkn7 zSd=NSMp$^7^(s*(tB*JRp9gw@l9N~VPZ-3*dc9QH@2Nf3W$;1fU2&Izu6iEoG5FE> z+_9fF1Of@8$2f@ZCGdTIpPdu5QZ@JmnF?Pn(eg4c=3x2V^wEfZ^wMgee@#1%wa@g8 z(yg2Wfh>JEDbA@fcta$&}EK6!mDxThpM&P9;Xg zhNc9oXx2~l0fp3cNjP8qTf}906w8@DEVC=qpF!AkcyWKb;KvvKcEJ#|*R%s3C<3D` ztO%71I~8Kx@qwQbNXtDX^ueQr1xkm`Hk9sjmLcJPju-#jf{of{$=~AGNJxIId>O@G zVTM#z8*U|>s?6J_1U{yo{@-8Qg#mGc(&^*-ZfY6Zt3R{fE?>@dl&?HXZ^g^H1X7{$En?WUW=fS)RnGSC!nqy$jk3(&Nk`8KSvuKv<# zeh3gU~zLm^Z*JjC2Slxw^-e zQNUs|TJpFz$0t&edyc(sfqQ;kH{AN8>Vd|Q^Utiz)1xjDdb7ffCAYzzT_phz}hv@cBpxKjiExI2LgU_;SvF( z__qUF>M1?as?XLx z_Q`3Ol9fs^c~iu4fLt%kh)9x9NjKELO7Wd+=!+*>A` z^E^4QND%b^?Ma_F2tVr6JAjp-fYA-aj*gU=`=b$JUSRxU)Cev_12MHN8DJW6?%87B zdHM`u4t+}Ec=dPU=TWC(%PU%Rkc#@koR=xkZhr*bw+`iao`F~e$bl!b@j&bB$D)=| z0~&};Jx4dt8q-0%f3eW}0qF(vVD5tEI}!wb^zA?}2nJcIUu?SvlE=~)q=a$1MR2G> zH=Gdu#}9feGXXT7HDGIH(q^0pMNz?l8`vQYezCws5mN}R-_0y?S<|Pl80?~x3ce1< zC1XLzv(0f0qzLSpCbGw~zU`hYu>F~?8XK$zW zlXzw0IL{Na9*|Gujt5G}gi~}&)N_+^hh5c9~b3z-PD@>?`1bamP5htW!<25 zEl-(pcJz&@SF5sb7vCMjZl&&E;ZoV;Sos-W|8S{WvS ztdWl&9r`fMU!M$AOlP&S=dCXoqE1}9tA9JJy#M1WTbB`oi8k7w4bP+0j5m5fsZ1^V zeqN66*{|=lfh?Wns^9_iwXKCjJ`OTq6WHo=Yan~Q2b?s!nI>!%Qm%VJmK!LsGvwju zK#0W+2}~`F=X**HOV$q>a1=h?#!bf8`UUo0L+Y1So}d_@W)+y*f(bG6;P{28XikQy}|Ftueur`Qk{ATj9;I%t(s_~UzcsVupG?|aXtyvR z%^XH9gzfP%^zLp>{AZJ~Ykjsq@G)^|xV@0&c4Tjhmn_>HD!;Uf6a-a&=#a+~tIFgy z3zktl9>|@jc{fhgUF0TV>Xy%wYf$Zz9ARBMOSYxBt)5SJAvH$vjaRwvz4uSzKW6tE zbk@ZMad$h`FmM0bW-lwU4Xom-edPv@FD5dE$wb#;D%B38sp=jdSm>*Mwe^iu;@ z)!d&5zFS3~^dCzS_(x|`5vqnd_Yfaq(1lq4KHi%Mi~BxDi3VCL@Y3@GSqPHie6FcZ zxicI1(lIzn)N@+cT(y|P#?VT1{bE_rPT?-7iAsDDB(7`c?r9zxJrnZ^GyIPS{ZV(! zeb`cn$pPTdz3&MLvPRi$$nnodsm91EJZj#%$8`m}@#?%GOE_w<(1V}QFOo+&B;ryw z^E{7HoZ^>$z!gg~K_QjWD9iksM9dQreJ|qPN1)sgYU$ z7cm|(M|fpi@L#M1u{%(okWDr8A#|~hM;*K3{a0di6h6sJHM)I3iAN4t* zVDddCY9~H)@axol>xohlA}c;Jqh2O@eeh%pJ$R?3 zZQ6TF>Wb0OQL8i^oAyyGzA|E>$4^-l+vM5Ly=+%u4S9OxMI0K7@sS2LI&dN|q;FQL z&tMb!yx+S)`g`gI{YPo+Rhw}VA`mP|-Fmjhk4B@M6!xI;ipfHSm)hZm_MRueJf}Rn z+ntO9H_>6^pPCRR60cu50tLH~<+f6ypg)T9N1}B*f&{N3zFm{G~@A6*)!M zuoJW8Q*?HdP;Ne}&K=(5cC)u6Yj^Db|wsA5eL5pcguKLdTBb^J%`fWD_qLw{w zt}tqUbtf}|rT6J{xaLE&SBgRw(7q0#fJo}_yBcjJ_#WNsVT*(1r`I)e529XH!U0h3m}V%(KT?6>_1ljbv}ug-E_|wYO2>x^&HB-VJ6ygvtwy}LJbU;3 zCPR0+qRW;K^t8=8^!!YilxQt>b3Q)$LdULG<@-i{prPG=bE-EpO(CnoR`V%mq&69M zx~U<8ayqeHU`@cq@H5Z%ttx_^kob;#X|#z0_vWS8gupelfb@jzj71IPV2q=?yNI#QE>4-;Zo)tVv48r%#X5jA#ZCU8iaG z0aV9f2#5FOA*^9Zpqt!dR`s)2Jpjj}4zVhU;BIXp=VjM-A_+p%RWYUsCdOiz*yN^k zG0bB*Z5b%iF5)M8+S?M)8={a z5uL%&w0Hki55A!JZ!7z+TyVgZIJkd^uyWMomFt~%)_g%V{1C)9I0*sfAV(W;&Eh{p zV_N=J<(U7w%`jHb8g5~3uu)uqR|q&Hqwh-{1-fBK|H;^-nRk|ldXwtZgK57*eX*+XpzP zIPY20l=a#_Kfa4jbj0P#_U_QQ5fNZ5cy_3I-$vFq^=>{JavvuN*uB%h&)*fu18(=* zGK-Ele4{ZcU4FbIcC z;y&My^X^A*-cW!C>m$H!6^rF}1MdD6<*xQhA!E5QQQl=#^V!GyUw2=9k@?@OoZzsQ z45-WANd({k!yg^8qRY~!Dtw>xE6D*XuLnJCnC@_)B>{{I^@9U9)v(sr6pNVmb}{hnWqkD)1Eu@57*}T? zlC%Jh>lAsdx!#n-yz;2r(E2YtK6&LG8!;&Wg@f2D&^(_sgujVHU2)E)Y^-1bMa#~d zi@G7_3#mOFXj`;F6dNf&kY~W3+WJ)l&PeIostOyV@=P|N_kP3GcY`q$L9NryqQ=%C z2#!%!XDvwnyh!CUdiDg={fm8>FTgD*9*en+%?8wnx1WJi85z_I*gx_NY)_yY|A0O} zr-gAq2uYg%Gf8v}f_4TD@L#-@ZFm(itO3|FC6FZo+QFm$89v9rV@H>O2 zFaGW5{rzvEjhb}};~#66wzs^uG;?(=>5vfreVCG5(b!dIrWINn3Y{R1^H;y+x23K+ z+Pu$WJ%|UT1NXw>XfaqFy`|A}2rkHkj7A!mSgj05(c^73wLPen6(rT5C!>-kjZMg` zat`JA@*G#qbjD+c7lw(RmbM z>Ol3ebc`9_3KQRs=X~eN14Of2{O$KU#T5sc?G;!BwZpLPeBX!<%@F_*#>Mrxhg;G4 z;6nLL$Zqk@C;t_!yXMh1yomm{BX_JIbMKw!$B}ouZNzdBTk|$Li!Dn#SyNleZ{j?> zgr8lCl{c%+B=CAD$R{X7#1W6X^?FtO@O6Lvq9awc(R@V7<_LrO^RI*t3!lCOX=aMr zQc)!F+W4wTwXVblB4VoUV5Hmff!|?4qT`z*Zy}cxwx!j?k-?pMX{RL>4te%~&g1Y0 z{yo?G2`oA7n_QTqgvtk2g5=KU(;}Il?<=K)nqsd-rqz?;BF9C>l8T=SPFT>5UA6F3J5QMJ@&U1AT zxVhXmO^=`egc9F}C1A~`AWE9!X2#o*u;5oG>}Z`#HA~_2rfTu#1nd1dcRQJKso|`5 zz44C6T~Oe^JTq#Ph9I`ql+k$B9SO{Qd;VCIT7a)DydemES=61{tstHMu&KzJoXh5X zIL+}TTlG(rKZ@oZ#r(;VZR>`5n?tSTV@UT;^HyuWRtxisAdpWOi(;>aN+_d+7NO9zHx7WyQ1RI~Jn$zK3$aZdrk#f6hk?N}^uG5@L4WVXUrpQ- z^5efBQ=irNV%fDwHLNQ9Q;vrxLFc8K^*zLhN?>D2u_9&(U$<;OFUt99seAB>8FXQBEEG`kMKtZ`*B*SqmDW_9F0>vXiT^Sy`Ljo-ez?a`oF-ikd0tsG z_CPFB5wlCbc2e|{O1_nd@Q#xvg70~bWfzm+cUOmfb61e00>rAO1dZAss1sGQZ5$hdC@_;1NPWA^m1{fe2UPYC z()V|Is^t=XUtNWyh~{2$u1JOGdBA=onE!px2>MxvpOFx(XstCEP>F-*jeiBJmpA?% ztd?UGqs_n7edujAtRGH{t6siEZ@IfFXel@&$9H_ZC$fCUi6EXv*?QN+v^UDXw|nWB zy(NKxLDTk_tV=W=uQjUig1^#^gMj_78ji=~8JUrMii?#&(%;D6sqIBFdQh7E_})#w zaTwda|L*h^ruc*DijgWY9GbxwUo66n7WWt41s-^=;a^=CAzv%}^_ym>VYee`H-+Wa z)3W`2&k2K;NLqYqPg2~%kyvStp){8DvAHjxdByti>Gye1G1rWI6H2ohih4Y_uc)4V zjH92Yele3eBET#=!ua^D*{R$BFc;+`uMK)_QWs=|g*fE>PvNuf9k0tT+;Ia{_%w1J z4$Bq|6NS(k(HZu??tT2@9nY{cxi9vUHzvak@h^LS9LsF13K4x?3NX=6_V&4stXP%2 zdPT)l?P~1;Cq5Pz9MZIWlZ&}n7`GvP5vQiIC{m2p`y0papU_YBFNeY>r?4yjVKwJ- zzlMEi`?161NSKW34HwO5`CO&rMOWIc`@gy~LlzKDrfOqZ2kSHAU*<~CEj%Skjg?bW zB6~jSmvez4)5`O7oj!EC^hHMmllTjOd{fmKD)frO4@QL8#_z3?TuIa0BF6Q0X=Mz4 zPn$Lu7vpq6-<_DM45zu7{`ot{yl(uq4F0US=95Yb>c?F>PXmIB;AWcYbjY^X|QFr}hB{IvQjrIx2!{ud?9(~xAi>?dF zMr`n4;o)`iKKDzC51pHn^d@GGhN7v>)FfBHdRGh{B8cf|Prr~Ue(jo5Kp*HzX44Dr znpdhxJ-F2|G3;z*@?Z;`$L81%YS(9^GZab(DkVG;#9Xdyy=JY4oyO_aX}q;J>c%}4 zUAm-@2sS9lN;~}59Pv~|)ghP@7rw6T(=e;u5V5KrLJJ}g^Yy9xJ>&pn9uUN%T$}_S zVkC$|^>HaJoiA8C5OBK7kv_Xd{JcXyB?hz3^35aJe=bNdFKoHLW08XlNX?uvKm9}s zkypM?e_L#Ed3CxXz92+UN@2Rv=y(@a23hd~CtSBLjS`YTuZ|LOyFw`O-U@rYlj7Ma zI#Y#i0Uc7%dCjlf#U@QZZBM0aog3Ekm3($&oVndnMr@p@ThT)OD_oiDo<|s}(tQ4F zob*VXlfo-AGRmA@H+72e%63n%eg?aRTMN3odJUc|^e{DqQ54(nxMWNsgC#JXk=vdt zk2IT4L{6pc+{)p;WmNv}@0%7`V6N;BYA||(-K)6ih9);F3y7?cdpEhF0wVNbPQKC|dDr-B8xyiAdw_XvJ#1lPw?Taxl+RGgWJM{-#=?&d`^wPnOx+ z(7gGzIp6tb6u{9pdG)2TanM!1TGMjwTY_TlodP-6V^_aO#n|jOQX_i-@7zm|Tz}C{ zBC%z@m&r*jk9rcmZzpQ{jypfSIwpiljh-?k0mpzD)i3yvCRK9@3e5ygd8;%mKQQOW zz$1H1L%QzmRi&Byx-5v^H|+Zl_RE61*AEu&IGGMpq+wI0)& zeanznA{Nw?0wpA3D-%935h6Z&BZbesAMLyF`HN9ZH(e0i`Q_WzPeJ!DVb&8zML`K7H1p_Q^sh&KTWcjJ-g z5Z+@oSElwE<b> z<-l5#^~6cIVE)#V1#M*^wgg_{D{nksbX93nuQ-g3Y)xMg;4-P>tiQ!b(O%}@&NRoa z{c>(?2k|bDi)On{Xy*y7Srek7TL)*=|o zkHjuoopE*degDe2stjpVss3JQ83tHy>ODy`fa0U_`RQ(&L~*!u!q84qdR&iAwTakU zUgj6|m>f-ofv1#AkW#b_Mkzuku|A&LVjVDP_W|+ZG$E&7-q7hGLN(4|D2(uH&?@MH zULe z0IiLn=nzEbpTW63l$`f6bgx1Slc4EnvcEo6;<`ZxD8m?Ou^i@0KBy^?O%oJD4I#B+ zr$+>q_Z>{Td}%!d!J1`+l-EYEXl<0jtle?G&8KQ?_?>&D%hO233U9{yZ!!37$Ldx_ zPRs42hF+bH)K-cRia@Ws)>bR`p~#WXvFp)+1k!$ClW6vqDsPU+(J}54F}=rdpX{4T z+4O=|8&T_brfQ)txtFh_!2N|^r`NulzUjPthWY$|vZl^39|Mn1r0%$HLvKqtc=s%{ zYY1^U*vTL&trOSC@pCf3m3>qBu=%8@=q|*qgnS01_A1~g>%GciI#$=``PWL9 zKL*fi=4ktXUT+fMg~-Y(@coFFjc)ais8P> zS1XPCE8&knfZ#n9q}U)aRg1IE0@w36*Zc9e8Qgak{bA0R35Y@>f7H*QK=j?>G94q! zudFL1lo-D9d>Yx>#FgcRwe%4;nqGbzQ8ev_-nVL=Gm(?^2!^zZ?*4_a5vTftD z(e5p=^c2?^6}&r?EyODVsOyl5LX*p-$#+Y+Z6s;ZmETwc@qk zT|>N|wJ<3K9Y$qi>HIfSJ&Ny|C!@I;)TDQ#M;5!rVtTS~3{&hItr!dce*9p0u#!ga z_toZkZqd5sF5ZsH=}tK`JUSTQb?oq|Z{9Fp zX?xtCkNdXz_+^mw@10E|gm8|Fwh*^)JaPZHbx{9Ob;PSZnCkWXok%5S7*2?FaL!3- zG9s|@5I5DZYE(9vomVMA@Cj*S7y)KAeDbFjj@yh+-?B$m`HgB7B7=l^K6 z7Y(5JoE{yCLj3N#%Rw+tVy4Ci{pEeh!?DWeB$P6nhGf7cJ`VsQ<}QOwI3;6TUH=+D z3USW1K(RuJv8EK7z-0wfio%R?$RUU1kAuc@YnrA0xvOY*>5)C}-O!NLhm?8h2!eTb zT^@YKN1lUW3y#FozjFJTRSE=^l0-2xv}XbqDs$1hk5=)}keG!olt+}hzT;~luE6LX?N3a<5*&oySf$tHSX#Cf6y<*2`ZjNFBT^SLzj{a@* zGDWQT8QoijUPTtSjdlu#q!EaXpT%?5ERPD9otMWgh9|2wB#NKUykUNr8y?A2{)0nm zH8nO=b_@7w$yu7LFQjdMV1-x@@9zi~dRBv`S=YR$L-l%W=5Jyv4K~}~+PS|+O6<3Y zGdzV!Nj$6k^k0ZJB(TtLxMszC{4ITjK!XS+!|YDoKr(Aqu}2ASewGZxWVbJNi6Dt6s*)^j=qvPG z6`YB}FaHDzXuYZw?J~yld-i?(762!!{H-SL^gqKWFia}pV7-%7+sy>%J884{l0Rfk z^w(moQ!C;D>xSVqF9C5&0Y~|d+WDzLqZ_CP#r&9ABsJLDxbWJks=U3;KA1&uMM?qP zt{!D3Rr>-H8RJSwq40D7nwA8#4b@zelYju?o_oif3076WkoDE? zr42BS!>nT?Cpy&}kXh*tSeFBZKGQ68Lz0ZZISP)Hi8cdJq<7_6X!T`IX2k=_DhXG7j)G`$AMo^1{x=y<~ zgF`_2X4-lxmPv3G3>HOMUx|Zb22fbg=;z({R-d-*^og!@ic*1`8jj(ChqzFiNhbTyF8c6{u0YN$i zBn0V35Jd!}`&%3RJWPv% zc<2p*v3_rL`T1Z=8^qo#>oJXftLO}Hv$t0i4v#n^DGrU(*Vwv-siy7nv)NO)PlMuO zF=-VFs$u#|QylR4kNg{|ke=N;%riu?t`CM7kkmcDe+60@UhwF>fAca5k~h3ehk*-t zz+*i`k2p=q%es+fQMXk&9U+!-`dOlxulsa+j^QuV1A1udQh*;+s7?!!*8_@+QlulE zAVf>b@2wUnfuN6r#U#MMjVABe;My_J*cUO@%^TjQ*@d7u!xCKihTG4q*;1)ha65+h zJ_!l$*H&7cHC~li`y(-V2*^r-S2Y$i_s_^rJ4zsk>b(D;CR)oV**=a2noP{_nlg1(45?hfRY;*L{nI=yGHJ*Vj%K4N(gVxSphw1=DF!@@$3o*kh0( zX(dsnQNatCo?fJ$mJ;lq7XjbSOeL^tc&Y}g+%{+zW<-xO&mW|wXFVGc5vufLglK(i zUtTsJL$_u;JvoVrW1Uq}qo>;fp;>0S0Go9-hLk%2VX^P*M5dvk$*-feb{=~L`f&pb z1sc$R^uFi#)Fvi^Ql7;qbuJX2*r(AyO~eYS3na_%ol(puHxv6`2&&qM1)NcBm^y_| z%cVXIB^8#s3->9Am$&q@h5b;Z(c=W4C3yC{56R=2** z{~Hpd0$Yx4T=K_L6XVejY<82cX#y@z=rRg5vW${3e}3*0k%o@)YGO&S1{kqA5uRjMS<4=ArNBW7L*cr(}3dT@KAU=P4IsWtP zLjd08-YHN&eB+a12i1X|d}s~4U356N+EGy4*>)(6WYBES5~~h!SK_7G>0~8Wzcdx( zi>g=_bV74vwRRqi&B0T%AHuKeRVz0gn*%@g$kT4uOutUl`jW_7J^h;2ZK7VQYWlUA z+$tfQRW+(6m{nGx8gWr^GVp<B92kXa*kU!F8GjN4$X+nF!kN+)0uX zsa5_`qO6v$?fTVgDBh3Dpeh&7f`A?}<^~og;lkmiVYf0qqVAY!adBiONPS4^+>0K6U09}GXzSt>RgekhjF*{t;E>S+3E%1 zy_#7CH7zyMg!)yr)}QEAHdD$RB6gOpqtxpbKgaX?KCHE8A!2`yi)E`x6oT%QTq5(NNoMNIPxC7;US#p5OxJ9{~vJemc;GHAeq>Fa)jE+qOri2&w zFH%Q6(L^<+Zeaj^HFYj zo^^15u-A8XdIrhp8ds8*tgu_}pjWzdGD%YT?6n_zpD}7gR1#XRvxY|0SSkhKJ3_XN zIFEFWRKVA-2-%QjMkYvC(}zPJ*DA}O%b@KmT9dGaP|szkLt2{ioh!;7CXedW6>9sC za+!8*Y@fRxjoKtvEXqXL*D>o|&VC7>o@kP{Y!o??9j|}HYTP6z;5z`-N8jI&xtD(k zZw|z~Qrppmq7#vVy(r}jm zDha8M)>yU0aYhc1E&n91(gfmGw)lN83dP!^7W{y03p~nyya30+{j)z7XQ+M^Fx!XW zR^0X6KN7FD(Rmlh4jt(&B-`BRf$GqYm~%jw2&ia_UIf)k#;uL=B35l$kj=kh)i}24 zuW-x~W+@lh@zvGJ%1U96&F9|y8I$(+s-qVjiXxQ{j`+pziGf}N-lGEGh9q!J7s8=U ziu)B*26ND)rNiN|?`SujY|A#>j(!?yIYiO~jLqWfMns}A6TB+ZEu|-USRCn8cN{NM^Io+29i*sACPoY` z1?*@|4GoQZ(h;Z>=;-Kf&c&pdB{0fpb+F2M!Sy9!w+N<+I3QZ0MqPHmUMq8vCm30h zOm(PeD5*UO%a>r)iK(e%Wr)1UJ4|5}jjr^nnUdAQB2$_WS?vvtIzZxs3@mU{CmTT8_AsWgd_4*|qRxzkFA9#Yw6ieKz z);89kIwfZ%j>cht#GXoOY(qGs|3#vHh}r16ICUG3O7tlg`;~5eBJ5$hC@6ffCd7VP zEq(cDfj6Lz(n!!TDl#$K+-uWf`fxje{cy z?OXXAi=$($Q5Oe>h10tE1{RGE4!Q=XT=M6CXDlcBqbHPo75Ca3U=3_Kd>Tyv|Fht! z(v}5L?c?K?A?_i&igXaIUcK0&!xjEcwD04EU48vZjlO4hdNY<~_e`mHFqxTq?;#~D zzM6Zt^Bj-unW``n37lX!E-?yz3oLN*PSmtpggn^DXYQ@34{%Diu^G<92EH=x9&H=% zF}s5cw7a{?pgl2k92{z5Rs}s1%68f?v^zw2^n{o?9@yf#`SCQlV<`3D>h@^tB2a@E zeR6rMMh}TP(zOiUk%TE>CoHYZaC4K{d3DH9~t8Y|b^nn!>74nl5PIZtJ`a$Is z(?c6tT24}=76SO!kX}zPJxUbFAS&I}m;IGO+e_|#@a(5r5GEM`lE283Ds|+9XM_N{ zclk%zpl)UY_su-AXauoBC;9;Q7K;!Mj~=#k@`_`F336+A1sO!BihH7P|50N)sbKhp`F zT4ds&#hO|pg9k5>mU=vVtldZVE{j6x^da-T=vygc1%jz1-T2^Vjo5)Ff3!N|1u7a^ zbVJ?uZ5s#KbQMO5vAG%DtAxd}qTgP+6w#AwxreEn@t(7qTY_U5_*`6E)iLVeIxn=8 zUwHvaKl9&Z+L^NYyvZEk))Haz>B?9{E{?lz#1bmhMb{2}xzcSkoCJ_2jS~s*u=YV; z`s~LhPU3(Ew^yW^#sU%lR@HR(xYRi6iA82nw0j_UY96F*#$4`izNKr=XEj6%dd$8P zA`!rqe&z`#l@Q^kR26)d0!>|IfE9=b+@Yy88#%Cm$S7*$7$HeyDNL#)TJBMko)i*( zjd*b-;{J-Aqk!U;v!~TdSFghp0TK0uKO>h`1aU<(U|2D=S~r2shKG-j;PPQQ6IVg8 zCO`L8b=5SHB!hF3D`GWdrvJuQ=7fy-D7||1s``PlwI1l2TDo}a#fcpW`~?}07dIBz z=vEy=3Sa>}mjS>A+}oipgR$Gy7&f|Ee>0*5rhkpdi(w#p>kb$ZK@$MFTYO^=aNM0a zARm=QPo1i#lP`Ej6>$w<+T3N}J4?S&(|!VnA~RxoF=OTtaGnD3UKM!USyaF~qtZmb zIW;ZtMpO4&Cft;qY{|yHX)&{aCwlQxVlE-}R;;?1 zJgvxVeh;z6o=Xi1s|Ap;Fu))^h$y9`@UJNKf|n6CD}}+R08`--$ec+w`TDYtD^~qu zm+4Xkm{_wgLzs3VEqF?g;2`N3b^CD&3vkA>YM0z{5cnQNivM;Z;mg{VqTFN69Ql$3 zedvReVr>zQy9cuCO-=+)yh9T0?I&-=+Guv0C+=a)G|H~;y&)ZGFWNq@^0}WXP#o zvjIbH<$#p-B_`S+H%Uox_Y?u9edXIo4*O{;w+?~v)R3aGPOb196Jro2F?@BOm#)6l zDPy8EiAk0DL%=>)UgXu6Y!cVY!!7;H%jXY0HaG3-oX0S>eX&Q=reE80Idm=KSTTVq zDQ~>nNhTS`AH}nOFZ~vnsDEapPbU=dl;$OfH$BnMvfYSyW!zvw_SOp0gShYjb}V)8 zslmwH2z3hN{`&1Ce=!(})*OPe< zwcj*%#&0{xe<*`L>ij^y*8MGbQd}z!#`cgIQSX%WK#%499-}@C{T5!vI%ow3fNgZj82Xp1Zhfo@ljS!uckkhfscjQCOvsZ$N zwYGyHqZRibzLOTsTx`R4YMxpBzAs5`8jiKm^+KezKZPHi%d9m4m;s}PSO#Des}r=7 zk4*PA7DQpQ^`zp>b%g2am@A*_EU4AUwqrnJg*zIc+N3ADis9kA$D~&nGkw?i=GD=* zp+%UxUBc>w>sMg4n-~#8>&oj?1 zjD}#X!Xq2C-`#UwJG{>Bw<>cMBroEO~VLo2OojNlVoU7pfoNNI!F8B z(iA+6?cJsMg$;6w6S7m~h zM{u7+E!?e=%5G}G3`2*JVx9LRXIOa}+$pDWwVAiImdCG(S|aci`MTXYf9Ci5mp#)T zn9o9??snhUg|YW~PgV7+UH08|9Vd|RxgT404DHEGGgK?Hlm6bw&{0#TDwO`ULx%>on-()levEj!}5%#sDeWEUG{6oFZ zP@Th<6q965!iJexA)VId5x=}t?zX`CDw!Pe^h4yXDtM_+ z27f$jd~!@@^XYLy^D(XbX_-UdhtQSVM)E=Y@H%!XpA~G$xbaw?-}i17_a4DNk%*LA z*cs$lw+Kgd5C?$0`O9YpAU2ZT0`Ow3Pmv$V^j@w$bi619+$iY4+}J#Q91%Hp>w}h2 z7weOaIQrV&ZsAm`>gaA($71|^O#=DN{Sa$90|Fk*b%*-67&o~SW!+L2nzz%s1rF8+ zUI%!66~+?A2Z}QIPIYEl-GlnB)T89^cnHk#ADI?SPY0Sb`O+<;Q3>Gwz z^}gAXB+B@i)86u!&fei!?yd5LIzqJlZ_?3Fd2^wDou9?!9PACnc<|S*bdqf6F*RL7 z#)2Inr11_7;#x!|yqSNC6&Ut&?HU}i-L=yHTPSjqq`t@or;zfCT&)`9?8)?A5}4)mE#v|2>3; zu|PnS@=OjoSZmzJWDQ}9)ko6#;I?fej7(At~uPhl?8^M&^bxQs&dznDKg6vqF)abX(tUFV1#0Uwe5soOlFVrpK(w9IL*KmDF z%84>CR-bBs5*wD&OnO}4pNQ1xaTu}rZFg7?!+l-6GO=T8Kb;@9u&k2^`!1wq3x*1&_wQ+Iz*DtqS?qS}TsPhUVO? zKX*J3Kyd~lY(oL%104n!@Z!XdITs7{;1O)VDU*;zcB;Ved=aDVT*~UR#|{kVSnFke z#Y{4{rgNrv9l7G+o$`xxx^_=Nn1J3_}bGKb)SZQylSmH)1P44+V?S{UJn*60wt?{KrmifD(2T3qDsu zRmtI^mQYaWTo@+>aX6M4qSd@turOL?C<}HSYO^eESEY-WZmDf0Uu`sBmQjNp2j3Iz zBBfyKH;~*mJyHQjTVg#4uKMLZB6vxBbFE;Lah*IsNcaKA5>)da_70wf8R)Z{mo@a0 zH9gs(`%h$W7O&9yftem2S(8e_g)2QY#7vOyoHfTX8A`DwBsxH?cLdT%aDb2g0RRfr zbLDR0yfy=8G4HA8C_})>G;boUiyNdl1SBcO- zgY~%YCKPJ?3+mSK8~r3k5a##3V^&QkAH>}qLk1{KJ`1edlf5xDDN>Bh`03YJRWpdi zzRKJVB^<$1CtLBSCq^ZZ8Nrp9s4qg=GhT|k$Ttq%eA&&sh&V9g^_@{ya>n-=r{^=o5MzlALI zZ9fjgdk(_1O8`@nVfj%UyuIAp0B}tN^+nc9cRxX-fz0OZ01eQ+x=Cx=bwVPC5ff&P zOn}+%1}>70=w5N>M|>N|SD?tZSs;b#j$z`IsrgEI$R%U18O-E9XjAU}Z*q_P#8TZ> z?2rx3=qcyD{BUzW;>bNZv=Q)*mhzJwNPumMftA8Gf%ykc)#i6pa5rS$xs1 zD2c=uh_}*?Ize}@Pf#9*@(0hd<;_&8Nj*V5(0~CcTdy1%ifnkw$5j3FlV7rcU~H|a z3?7RvEM}xHY`UnPu?DogRIX{n*S}`WzBoHneSxLj!>l-G#>1x)3Q&pa525OKBB;)H zhff5I7llem$SdDuwLYl4Y*Xv&vm6k{6#x(_RIGR9qUTM&~5m-wJHw>MdH<;Hz1%W#ob*rKs-qAnt@xn zfT4Kxf!XfMdr2dK3fvrgE*=%juyb76u8vPwIc)fxvFU<#@6ED_QA4SDT#(Jlk5q{86wJWFJ3pssRrdTLK2HzU z>Hd00Xr!k379YVet%USPXgIH94XHcjHyJA{#)!DzJsr?9_{VBv@Ed3 z2S>4IAKb@0Ox}B96{QSd2qw^)7zH z)(`p;q&Pn&%VH}1O}pKa$?Kl#r{TrU*4f2THvGyBU6)eJ;o+l5tR<~9?-;^lHT)2T z=ZQ>$O6NMJLe!swPMYW}yRc#Ex;DAM`dA73LA49@2B%>-&|vXi?o{mh8u0azzIWef z?-`s*0-m8T*gPE{913qpE+u+$MfJdkT?M8cQT1ej9&p1nmX|gRibv(uXX=?LeWJcK zsr^5U8lI(YI#}*f?VWCH`=))9B=PM^$am({u^P0+rZcaBJGSyo^fc{ z!rm+uQ`^jw1|S(O;J-0?ALmJy*;G&G@qJ&?2guS}3N_Um@@alYEj z;dnFe=ohSWP_M1NQz_%kZd@Rr34Q6`_KOVCkE1@s>9*5hNjKn)>lI-rdfzYZf^lGs zTEdg!3F+I;J%2}D3zd7|jO)n__Lr+yiOfcEvpRO*Flr@H4Vl7{wmBpSOny6~9R&r# zE9E0p^R7v8nd!Xk*^j21&f;Wfzt^L`&_px;m-Mf!{xef7bZKL~WU>T>9(2tPNnbdBgv+>|L->g~;qR16LcNUyxfp!QB6_~xI?2;k zUs^(|#tW{^ANG=BQZn8ytx+^I?_RqobliLOz925&CVoqSHxK)5>6&;xAGjb+i93vc z_QGFrW$&eJn%EPI5I}{`Z*ZHU5JW7Bi$y|HDA(5C2yM<*3qHsYO01!tt9uls4jP#x z9v!X~j}%O%&@=Db#>xMfus63BLe+PfR~V+6$&cpdefF@eRJ%BaV0D;!F$5`8vA{k2 zGmp!cgSXiC`83LB8|)(>rm(A3-)}N$X>iiFCZquoPIu4vH0m;WcN;J?|R3i>Mt*^ObrcI!Cl*sl$1`J%EOs_^tFmI;f|m5X5<^ zSr4GI>hr`zWyHa&@qc~rD!^vz`0xtVKB1D6o-gjYQU(G0vwYG(rbt15KQHevlOc?r zcVN~&Y%{c*{_KOfA;v3IHJSGroCRkI7?RQKho9DlVEJo~x)pI(2{fyXPX}#duav+Y zsog12sc)D0{HQ`m)d*w-!y!7i*$-HB**^x^`4Z;FFwiV!=zPVc35YkIHWR#%n%Z|fOOLNL*{lNK{47JOc?QRsl!4pNAcqyr1%5x`C0~jF`z*cY* z8#2V6AjveK%3ITDO-}s(X6Rw@0`}Skb}Ps-u6dU+aqR1%M2?W8P1(6uU-sqNEEO8t zXYF4bd{ashchH3DYzA8zG`Y)W^2e&w2|5{w#@x4lczT9S46H1Cg{tsJ$rCz-#C^>*&(QiV179Cd?J-z|;+FUW{0aKIw zQNVJTfaCEytrN8^0WBMylNR(wHyd1vhWfZy3$j}evZfnIYDvrS`ntdR9AFL1OJ1ux>|7%L1 zMiM~@i0D9L(5@jasEHk(CsUmiv=R#WIo7tLMi1^!Irn@VeY%^|tY&qBAOuvVq6Oie z6(r}%M7bQ4ZMOk{ zaeYl1J=8JMbstoX1X<8uSt{ZvG*8;NdK`C@){;s;iQx+xc*T{VP~p1@_^rUh2A@6b z|H4g_;(hPLq1G31StEq^|8mv$1;$+Jr*JR)wTJ6Mr=?Y|MKMsxK_OilP<*}mq z629Wbs-O9;3MD7)smJHZW%Plq6_iK#52a`eIKaM3&SU_lJs?R0q@+%xhU| zmQBl1KWh@r)l5wAzNRCH4Ut(kcVY{x&-hYi-g+%eSDD%3iZqk3i|J}Flb&>Wu&%zr;j3*sUK{6cC$aaQZTdc0?E_#bt~F5_QBi~5s| zKPrxz)b-zhawQ+3c*Bm3ssrl7p4FKtmQ-Ok#J>8-lmCLoX9j2NdEx8rh{<3F-M0$m z3iFDmtAIRK-nw<{T!m2Srbk(3+E0s^KaRTh-8^9h{Xg+b<4s8S@C`&r3wlKG=Xj|I z8`QX=f3TkeI^#B(2Mr(Lr~=}fEpU;2jfdf)b+UDEFQm(W;I zc&>QEag1^y{#ajZnv&W4fBHbda`@i+8|wK9stKWhmZ57lES=&k-L|5=MQQc-oihA= zr|8+#HwOnx-`3`*Q*g-(#RbuqhXZ_P54Fq92VpyU?%Dl` z()W1(fLR7!%Wsx{xAi{a@5OW~w)alA33;4GNr1S^_&#x_*1F@ptZ~&-eT08a%YLMz zmtb8bHK+@3r){>}Obi8HztaVn(HHZNAhYt%N@l2>}|vg)b=csGbEztQpzP+kYR69L)6yV`RLQR3G!-Uy&f*+V?u86n5f( ztBX>towz6K?OQ@SyIWJ-@6J+I;igN@{n?!NeGKa44|}P154Rc&oS1cCFQCR19eW)g z6@q$-tYqIdM4T2WxX2EoSRw;w1)u_nyp~^^HN37LAG7at{tNNr{z7~OD{z_9&3ah9 zhk*FNP0DLqhU@U?O~?cgnoqv()9VyL-+xXMvdrw?$g60wFDw}W{ThRcn^BrPVVnu+ zwXSG3!^Svz=ig8M2O0r)sqH!_*5Bpe-OspWHXZua_50JpiQO&eiF&{Ei4*@%2#^u8 z4{FIdF+)XPVlR20PSV2`t2G-x*X!wEdv3<|I&tXDKB?Ib|81?B2Rd*}Q~RL4nRMzX zt-9O)s9#`mg=)Tg$yUBpV_c^SpTr0r@6Gi*4BXxP&TsO;4~6`5G2tG& z2@mb7p*{J^OcB?;-%qWE(vavVy_U}^L|?prNQ-5oA?3W5dC$UOX5cW5&oOCJwEoi1 zbCd=#X__1dJ%nJNq$>Ru25U@-H5k-E%3dc|r$Odq@ln z3|1rArU%M~n!p0_bv*d)-v~eg0A{u_4y94h3)36&fCuT84;|#4qf^9H3&&_>a|@nD zuMbXdeU`<^-hQ!4b*cZBjVt-6F~$SnAnS=9J*=v8Bc#`aohyI%x6X?xyQv^j{UmwvO8~DS?MBHEF z!DVD+S5{VnLBCT>x9|N)46H_VtcVIU&;>UaR7lE5HTj*^;FS!0`m_gZ8z-lybihm| z?0duk{*4x@l1{wQ#|7()2$>L5713`QG?och`T}mBrn50^@gW9=F?nE>3}=;JDpZG) z9336)9v|CQvq|$OQ2yQhl_2s9g;GI0QY6oTK?m^TLdam=zW~2EQ*bNP>E3{_b}~$7 z*ebuBEihZupQF;GEqrD_R8FndYB;Q4GY3$EqLY`kEWRs~S-xpBRdRL3aRt&SX9)gm zUZMe4;-!s6*W`lt{*mM!08aLn3$#o+GV(HN|J(eQ?M|4+Nk{{4Mi5^II4^9Cv8_EBTThZ-!&s7>&lEX_pK;BKZ1%&DF z_&>t*T`toWw)9xIr6htAM)dSNRh`OLxvl-k2zI_kjV<&%9vp@>c@Q#LKOIY+yp3Q$ zo8g59)n{KXw))3%KW@DT3YSiu^4;{O_g2J6VFeCgBZPrsZ1uInb<=unxB)Twsd8Ph5EENyQNWvDB_??s5yFRx z1!scc?b7*Emyw#fzw`xpmHr_Ja2XNanzb5FS~RUb$rY=`heb)&mq3gCwrCxX^ecJ1=(H8-Z=bo{R$&Ac0xOA>+qnUTd=u$ zP9tB<5y|xPJ8m)EMTnqY9bJP>|AP4|*r96Xq`f3kqrkinc=@lBGwK+%y)L_{Q-&u4genEpvLVC4crLPF$v zwK_u3BmYyqul%pYHJRy(`Ha{o(rZ6dRZ87c@}+HXEt7C(Y3s~O7GfB1Rr?C ziKVEhIEEW-TK9^u0_$+43tcSWf{aBon~3|Rc;Jppp86b>mS@=YU2PqDMiae(*lpJ=N!z(B11&W12rIWi%Ogy|r;!I8xabFA2+g~IOmE%~fR zHNK%yoz3_dp>6nd-G9%q5&HinsPtO@1{`Y!?>+Ay{gMo+vyXT6@WOy)Dz?wGdX=BE z5ylH`-vffMXSa0Dhh;d0e++YCIABV`@cwSLqtOf{P}NDm^b_Xfq*d~eE}2ye8ALeZ zEk3RHqO`QMT3m^83DoA}!-skiOMoZ~q_V2-^aVVPxaxVX* z4wQ(<=)Td<%$HIETO4`Z=6bcNhwVxopO};*mCj$0A=ures97a?zyqvqiYY!Ds|ub6 zJS-kN6StL+h722#uYw14e-*bkiy9Yz)LrWZ=fy97;l^ic&${o&(XPiFRlryJMsmFI z_XrYzUJw@JbRBQ(#T2VP@q97@;qOox^N))QYcA$a$a;`!E}0{d7zJz$OMS-`JwWFR zUoM)~orz_Gq_AtD7I#AK8PkoIShBr|n|xcQTP&E};!W<9*(xE6mV>FYVGfYbMA;*> z#2ksf4u<0Aecfc9p<>d=)2l(sJiNTUfJl)iZ#6x~S-B|O8smenuF8aDUNdR}0H|I* zRp)aFQA?v>4QrY{+M1)S<4TO|VKz<3_BX|$crrd zlHJ4nZg;QaCJ$uJWkCIU^66gWUFwcc&NqV6L3WT?l)4Ws6U{wBo?8GFlS@6frlDV& z=*Q0dgwV$YQR@yb`k*@VI&u#4AREcR{Fv|;hfe;JiJ}c9{K-V)5Sb{6D-9Rn=pzKe zcC_-C;sywNVY>Poc!Cl|DdUmAXngntL()lsNG;pm&l9CTV)`hMTQ6*$cSZcdv(>y= z5@+hb)SSLX*<>xkXFEXl=1Y-NMYqqx54=dSj9>}VDTv$m4FSGjFxA%m z#Os^YJBSg>28{&%7*%bxEbLVWMRAmv#y5+b2g&rWoZi$4zx;y)L=ma7c&EymZ@@V! z(29G;ZSiXod=6L1r|bM_AH7{F`s@rGFk{tDSm5d$@sIwL;zO9SnP+Ptl^BCji@1?E zHBFb)J^o-vmqzxjvs&jH!B5MX&rHkW^O#Q^^}@9>1R4XjaEj14dO`6P|cVX&>UWVi`7R2L+^VN1Z9&=UTSFDnO$OtO5kG@rlu~2-)%i zgxU6oh?g$Jz%A&kJ@=g%?dZlX(vJF-@ed8)&Sz=-cj0A#_hj@y6x8m8=ST)ROo*&;INg zgZ1_ycy3{!w2`1ybmiybeYoDmx4FAzekP}heSC!QT&-<$=RpZillkQD&_PlvC)F_G zo~g%;6|S`*#LX-YYS)W{Q{kCX3YU;zRWY#2qH`P5t&josASV_Ab0IZ?ffyDF`~ShP z5W5HT^zO|pl_)W+xT9UH!bFp=b6W}cPI+B=g_AzX8b2LZ(aOIEZA8Uy zyK-kJvw^DYXnarB6gFD%QY7H|Djr2q<4)c(pio__cj8-LWhL=htH^!uL!IuyD2O-~3$FY^ob-tBuZ= z=qsItjwPm-v>a)INRsid?rr+?ULLYZ?6{#v(H`WEt2>oc54+XiGbS) zvLE&?`*2a!_DHbLu*oPsk;WcX@N_t0sOUT0M&HUFJA(`Ob0HVU;~&wA`$xp4y4;gJ z^MIP!4kzR5^!Y}eUaa+L4jI?n!Agz1w{c-V_X#k=uX!Xooo-P~z6mCwK8txq1YdgU zkU?*EHBqv6b-aRdhqymdx~nhR*@XIB-rwxK-GfS#X0-8vb*&;@H`GX2Z}CXZSdBeO z+E<8zi?0`;HTf6!c|dtI{pxK@MnG(0qV|3Q5oweX+3#xn(?gYb_=IPZa&XJvcp&nZ zj>{aHCP6?L5Ib(vTfnp;fm!~7SvBUAzghMSorI!NlvWB1!xj}adLp*O#iRHzdBn{6y>jV^POMiq~ekCTMq@@ ze(Gr6myHtmp5ie8OD@Alk3!Cao$mAWxe=5jlPzRIq}ga3g}RjbjeiB z8?tfW#|h7EaNg%K5w0O#B(#N&AGM76<+=OdduimqGPD&a)90sn3|}-Id+)DWS6w9? zf&Cr7i3x*c!~}0G^Xqm(Cg9p9dk7JHV_w#qv6iKKN!3MSfkZbV|DCl$RT3cW9P)6P zq1eR#C_6BI_F-U^;1IYIu1NS^YbFjqN?_Hh!_)Y+bc@A{7Oa@y$Tux%eRq=BE1z{i z2_KgMi=c~xfO_&df&tV=gdlx-;swo{Gf0T7YU)oUy~pw=BYFOkeD0=XfCuRdf&nkn z=^|1^_FqBBN5W@khj21Cll-3f@0M=sXPiUXw2ZUb3aVd=N9eJb>i;h(04t7vQvfo; zxg5C~+eWzsg`vW6sL7F2I9-hf@u=s@`57`W6-TSE%efHX-6GU-;JlC_`ytRERnR1; zH(Og@Bc)n<`^CWg!h1YszgF+{rd?5(BOXwJ8TjC=_ao)#XIX3eY8*xB2$JY%bTLQk^UcDcP`Tka^3SnHbxF^UPCoLhWxvNe=BAZPyb856-HJ9itf35vSyz$Y zaHn=gq)CfQ`gI`PG)g@+aR*Og?6@wTayQ0QG0`-FFF;z{C<@ z#K8fNlPiRJa#0M=OQsMi-S&8i?0ZAxm?OLYMHV9I)trA2(L;6MHe;rsi6%bsZ!UnI zex9y+iW~9lG*4zmo1Gs%iH>HzRxh5RNv7S}C)@$As}DSCyFKzFGm z#h16y`>B9Z>HMe{?%PxisBQX8lwQw0igi_tJ_4_l)3wp?HdCjbgbk z$t4N2;EJUu9wQWuiNA?M2L5N9z|PY6*14^@Q5z?Xm=F6b!T3A4XAB1q`-;tENy0R@ zTw?Kv#o`x;H1wtY`kgAu1D5-aQ)fMC_>Dx(N7Mx50tic1_KSC`2fRSyf6%BLI*afs zf;6WCDE4xJK=1`ZKWaSf`t1RV{2^v`5uw2E4kyED+$yNrhGGMcbQYs72b+r@7APx% zOPB6bJg!myK(tC~J(qGrLJ;)0FJKw5Sos+(bCMg68U~00xpct+Sd-g1j?IuEd+T7TkdQ>+ zRY+|kKj9=j4I%M zSN{5a(q;59MDLU~HD>@!og}D8{I4uQff^0LTzQs4_xZ8Mf5`4mxH~4{LE#-IK=8*~ zFA-Y+rgtn~T~D4O;CR0-iJ?4AngE~ILfmBiK27qeV@AHc@%w6_}G~g(` zGIR~Kx(6oX ze`k=riG%A_D`yG9`xO>4^en7*a0ZA91oKLCX)96=w&%R!vUyN=pFLl8Kl{mq0Hef% zDJ0e>C3Up#3PqkmmwbSQ13x%6Wbdj=F$s7&UKB?$Su^$gM5t@qSAvA;ddZ&@93j-= zZop|p*b))-wBxpK9BI0}1cOP{#wFi6g1ncBZeF2sG9XjFD8h7(OY z{t1lFU;bfx`ai}w-6UaYK@N!d)MDcSh2u5PBm*xyPh<6Y+n?64uE~?r{f|UJ?oVR& z;>i{r%6n)$0E?fXbLqU#!E5@%6YK>^{-5v!dI}6+kKDC)VkIC1d?={;NOC+uCj;Xp0)064!%yCtLa>tkkA6NwRnXi; z$JCK_gjoJsO%bl*BxBPlBuY0eTV>XRvFqhyXoNdS)yotG?iDraL=aowXLG5G(CL}I zUTsfEv72Z@FPS$7<(J{3It}uq$!vyHe=P$&jmi8;2xai}YHj!O9QQx01=CI5F-P6q zzG1O=qNP6<-cdI2T2IpdoPHwJi1(7aqCj9Ikjg>t4ZRAu{LTH&GqpJRQz@fk2Ve`` zqyE&Bb&k`~<;$l+#7*!9c;JYf7!y7}&@>~wkbkc@yZRg6t<&ReukqG!m3!cqc))Ke zfy5_Y`)>p6GYnh3A2&$=GVY4IcSU=F?m|EaGHwDCjr?CXX)>ex%jTO}avmgc`ah|p z4-r8YrOH%>i^s67r-2Ygxk$RK5S2A|0sbgfb+qLGV2pne0`cENGGZ2j3=;7As47W- znEK^G0`8tPSx$X}qiPr3T>fUHiGQ_JTFZj_mh{#3`}n4NuP!Huk+**!fyxDyy8QEx z(3j4=@c^OwD1t1p1-gnM9-+S*b{yu&Vv-f^u zt!F)f2S8SGS)k}nFy7ACD!?*yAg|Vw`7LR8{i9loyjkd`<|L=CqwDxtq$!TKk~?hR({34-)}nE&?v zfIA_vftbS!YKHzva<<0`#Nc`WF;hp8izj;o;9DB5=bhx3$2(kMr#5za5nv z5AAdBDFAHU5Gvq50HPRlT?3&R%-V9zOCG>df0PblBOV!=$AcmQ6R-f+cj}|Ozk-21 z<|yU-+v=}ffRLrqx=%2b=RG0C#XTBsQ98=-^Nm;px@{W3G{|}fvXL}iXK?*1LCMF> z+k+T(Fayttf)7;HQ#}R%I}a$w*#O8{c5;2`ziTh)KdLTW%SEj*SXnub6eR%*peT<; zEfU*fQtl7JE+%nfc+s`(U1B!AC6|tj6n+vM{?G^j71^#^J|A9r&Mbj2| zk>U}gl??^#cIozV?hEG52U)@2@YF}0)~g^(m>tu?g`5|7bK&y1xR$b}25+&$(Uv{~uX*NEqc9%@YLTEf)_<_}$cnP#M+{ z@x=2@qIy-yeRIA=Csqt*2kiN36Y}Cz&>VwM39Sgu8$U z-~Xd&B0*#N;k5qwy*rKJL_iv1d8?kIefpP719>L!U*iNLU$Cf+{v|O9^!m(pmk_Hz zzKr}Y=JdNPK8aRL3w*Dfb><#epnS?}9h~|#Q7J*Y?%=FNJz3HnP~tDH6Y!-b^42!E zJZ{hs;0$1}CIbt&;hgnH-)TTT@i6m`+f#eJ(DOGoS)c2>zW1vYw63gKl;VL|xN3NH zWH&B#GCYmh;_>scmk)){C@zL-c#30Qm8{r;yATy14qYR);zFmcxckp{a86G*;clZ2 zN`oC-2QPUL+o5nh0v{a=tYy>}BsMk@h_(m#J8By?;D6(atZkK^ueu?P4|2nd1x z;lIzU@Yvnq_#W+zHGx`q5r90kG}Y5f)!GPw^;dZUP*k9NlRLHVavoNnww+{FEqKRk z)dMcHf_T|$-A{Y-PY~b(TQLON-ePmkPB3VP49ssB=F8@(1s$=RmRcfrkd$S<0_y;a z@nA6^hzWXL%gkZZ=ko=K^}p*ki=Y7JN#|uZaJQ4D2Jfs|BM3;Ve1bf&8~u-AUs-~!^ivf8!bke( zz0}Yh8(79L7P`UQ`0#=&U=$y8$wjV+5v#^h13tn-s~vb5S;@^f&lm%W<$ev&&LbMi zJ(mAH040hv)(Py}0&GRa6TRLgNDNq$(OrG0y^;u0w=aFzgJ@_dDvoMD%_2fWL`laL zaODn;Z3{^Yum4UdMX(JKj3WB*p6u_6h{NF7|2Yf*k5Pj^Ro0nN@{?V+5UKb)(dYM` zx{7H$?+_E;*o51|gO2m!6j6W_Z|~v;^6T4E8nME1ndeF$rzm&vH{Yo zVAIQfZ^>Uf*8_^OZ2<&GE!-|5gs8=W8}R`lEPnnYNEVXb7c>7Yk>Ce`!pE%>6!9r2 zcYrkyC3;#y3%EuT9;pl%gY_1H(_z>0)XE2W!9`9T#g2r;HUeK>*YMcCDQp` zTUTX?>r|CbH^(yoVoxssbZfot@rr=XuJEh0*@g)6=vkY^Qm%lS)Bn`pY^ML!-*2TG zSGRNc4s!&RPm1kF5X_K`@!F|^u$*Jh{Y?%U*OnKjvsvN|IWr(yncKGuYbpENUdu9q z3gRqP&i8O)8XErtD~eK46JYra%q9mP&}|=qCvKp{+CxEXDbP#U)+^9{7fmg3u;rBx zg-t6xw5}aUD$I4a0A!7wIf%y?_-Hd#hED-qULN$CM*w;_q2eOsq%|qGe8+0zSp^C{ zL{C`%3y)Ov8#OQ{LS|8h@P*X(hCfR6OH067qoZ)ndwwq&&=+aiH?1UOM6^eQ%-CUSpgXKk2(R66<; z=4CfbZ5V6c`?h?p<^0)|u)Xu`RnZ;Y>fL9Al6M{tHQ-oEOMvgHC+vFx0;(4g&I-Om zTqpMy!*u_QCv54E9ElY-n{6i3upNJv#s5|1$OYRtw&4~0Rjs1eMm33fDo-FPxiSsU ziCV+HWH9%A|8;~0QvQ{01i)i8h`l){M%C>?SLvW=wg zo8#jx<-Mh^B(cQoU7&2i-&X+HY@f_~G1!cnaY4A8ye3?+A=KZj4!jL!xOC@}e~zJb zhP=d%wMdYZ4oqDD{XkrqG%PZ*P@_B&FfZwmy3sg`CeeB{s&M>n zVIuOvl-t*ES#N&LNzb?0_>^5#@dWU zkA|KfEQJDVPA(9)XXvofPC5J0m;gr;Fieq1NJzA+4RtJqD8&OQKpvNzxcArihEfFb2g z&K$@E^hS>i1Qhx=l0B?|5q5F1LjbZrO9+l)M-=~kiL)qqD|5_^=%8mA1-9s%&-p?2 zCu#n;`1s!Uk3iTt;caWcHF2e0O&|E`8jTJHSRj=g2?Z4U2G!fV0VwoNF?zY#5iE)g7Sr0XsqlH^Ks#KOUEnGH48(_Ix%GyWk08 z7yLOmNFd=fkpW(1B&r~vJ`xyp#b!DH<8DYGiBY@1!OdCT3i(WhPAu_r`_f8SiMjnY zMJn%|_7%6^*(EzRY%LzT6LbP(4QGfYTl? zMGL~vW*RXwfB)d}umcTzuZRgUgzkMa7Fe;RB|mrFR5_0 zL@D6@cUKK;%Dr)=zpH~`ixfTKM4<08Ugu>I3Nil+&RWHEN?&qbu*JZ{?yL99EEyUW zttsG)Z#kHzcp@DL9QRBvBnpy}lkvbm4+cqu=q_=@T#WfKJ&@yY6i#5UW?6tLd*a*? zcspLIMh#NswN5GzQxl5gN`MG{2sMX2x@B{1E&nt9zf|b?kU9(SrMN-_!ESpoIzMk{ z$(KmVjf`+Cl)#T?7otQ1i`5m(6DeR2Zmht6-2bHFry?W(1%^VjRv9F0eC$r|J8)O|D_UFh` z{XgKg9udBuzF{0(UdqhXsFaeEX}!=|HazlKKQU{tT_S37GLorL{akz9FRk+Q4+iUN zfvipDV4wOvv!7`O>!iCY-G2OFj=jEiyYR+sJC0;5sNg!dAxy+9EYAuGm`L?BWbm-GB_vTEKJ1m)ld2^W{`B?h*WYA%y`4ATjr=32 z4}(z!1AbC%B>V}jKQnX_bqn?T6WKxx4$yF(t+*t&IWvr#7FMp|9DQNkm(D8pp>gNLQ2(Ss## zufn-KJfD01(Z}SCwKji3*ZOt6GiM5fN}^$#1`GX!zWHtlYVi=MxtZxXy&{wY zwk?e>KTCD{)+Jiy;so!Iikrgo$x@FG$tYFm*fTwv??pPmKkqLUHx}iG#Uy4o2wN0s zVtVr5H$Uarc6CN#gG}%6Z{x^F!iL|~o289Kofun2kD9~NUWKvzmiTRz>h_&qzuh;r z>p_$KGMcogu|{G<8rms*? zXQ**dviktMGxLEDT7hYbggd7!&R9baWw!L~__5asH6;WBDY%MWFZ86(*)ARnLnjDx zD7Yw}k2ay0IQGL|lTltC7o;!PuE|mq@c?|q7Pnu-K}2LvpEBQVNWTETl{u0(@gFOV zel#S<*2q%7co2uN`f~*4eYW?m>}})c&qUWe$r91=@kHmul9H0^iN*?C6Rxc%sNC91 z6P0?LN0IDb0=eX8jFG_Z$Jg<8XR52S8=WlHZ?`3Tav&V418YK8bX(gK<#tl4+qpi^ z6%4rL9VG7&H&wUNI+>R}q!yys!alA2b-|mJHk{yp$rBou5c-+0|2}m}X7?1y`WfYp{mwpvmHP`x!_{rYV&4O#dq@|W*!0KdMZkawCFGw$zGOf{g z^NIg^=2++OCFbGDKtLQeS_TWuVXr#O(ygIZ=8U5AzyfEyw30}q?fb@RJ3HWdMz6Zx zOtPQ+hGW>MEsY-b4%RVuqv`wz(H(+Z$zPteh?c1rmPddu_=K?&4;&O@#L9& z!ru0LIeY7(UtV-IuhU}8eK^yLZP`9hcBc4qR@W&`es7V6ak)9s6SJE}g2fVI{!WyS zG<~PllwA8$Uye42v~_iLFoOIh_yLLiSLyq5p0!u%<v3cr5+dxZtIT@$RRI$`=~N=#|MN=s>De2B6_ z$*|SC7FUTrWp95!wI6cz+kC*ZL-W3&m5O~q9u>W$VGwe~YCT{YN=8l|+hJYOaa`=O z!}jum{-T;qvRPl{lu|^L5XM*{W7o z=P*b2_j=FWwn~(8YnYsqu#NpZWD83gFTR(jUR2qv9F*O8iF&v6{^4eQL0=c$GkL*0 z)RW@wF%0FJv%$9xOX%df=PIu&uMcoE`f|vnC_-%^Ucv<9?=y;YiAFAHvrAvsue(Cq z&B~Cz=z1jRc5L=`k%n1LM}OcvLWu)r`!O(thO0uGlG5?zE8w-MtE?zh&%M+E^nt)0Krg0rPrPh8K#vvs7k%XKkgb*W^Q2Dc7b z+sB!uQHM&f*0gp83~68|Cw1n!+qPLVA494P>Q?8<-3l~qUwNZBRKr%UMugwI*@-lI z;cC`bq;WBn_i4^@ejx~1^@CU<*^COe^Sr(W(TSIb7GZxTiL_kA>iC2f7Y|!(s^4s( z#LoK;hTWUB5vhw|Q?ibo`pqoA}#73p{>D~leF)Mu8yxt3pCQYE8uJ!#LT zEB^{m0pbj1=0`fcQ3~4Sn5`j&_!{3CrKl_(GQi4_L%5u+v~b?F`Qbx8zg&gK1`+h} zv6((TrxKCdTpW0s)1*|RL}kQ?{>fo-pn=tWa{eN(LfuSg`Na@q%lN_MnS+vu&^}xn zc;(WB+73KbQ&XeyQXrhJGSE^eLu8O#pY0cD_V@Rr0qd|aBL`9VGFO5QnHN+^U=7&JiKrgk* z1hw}>(7>OUTMRJY6Hm#`W}gc(k`8yu=;|8N4fUxqwDtgHm_wbTeblwrN^Bs#pWx>P zkGD-LgsnceJV=tu{*T7XJYO|5ddcm7iCD(x|46p_BEsT(Md$9|IgHR2=X z@Y?P{Dz7@T9qkLM^#Db z`GeZ$xzFK*L;*^Ng`ruKDSm;W#)qI+sES&S+y0DMYY%^X(ev)4pOao9^d5G zvlhzkmQsG`IP;jh>)Bqm)*8qO##gj9ql=^);zHG#S<`21z?E2oA=@_Gp`aqi#F#QX zEZx1TAaBGY0Y zKhb1kgGId^QR2xVg>rhZj7~Y<7*=iJyg8Uo;KwhEu_jx`TznD7lGdFwlDsW$N%+HY zp1IGkg$t`UmPqoV)k@HN(-MD2TcJZD;#YM_WislF9WootUFa6$T`M>$Sx^YQSkOK> zXfB5zGQwq)-N#dW0qY;R`ccqoCz8e^S!K_0Ng`G4SC(dG!KgS?Q4GIFbHx)UiLbV|F`foY4juYIIh^GmaLA0%)t^^PQcYXsct}ry}@9ge12$Y<1E6NYq?r z!E>=Rz_T|G)vF>$$onwwc=h*%0{A^Q$g4XDA_yKz!x2>uL$p7K=ual<1iSt4GydZ1 zm9#rSC6hY4-|gLp)IaD3@Eu}xKXz4E)qk=WLR$1W!Xuvf8!ehqXGM2;LckYaCk4Li zYlRX8OGaVWI`K;SC6{6^`8p_ zK0P?nVw6_nT%cx!rKn}Gz&;wkh&6bHw_XSt8CfOZqWqD;tjE9f#f3RP;0Panw4+6F z=clZEIP(3p@>kDsVCW*{n;n1uM|yHN8PKN;Wncb&mf|;noQnl!tqLY3YEw~AyLdS=v}?gjI$>LcE~IbfV;Psoaz`o$3)!z3hk?VJB5|1GJw zhiA-D^03e+j~6l8&()$tVL4QHE_R8Yo z$Y;#(Ox5NA<=_?RwdCH4<;o)I`9Ukej7UQE5|?Y)m~*;HU4ID%(W&e(XvgK8No@4> zOF;HQ;HjA6V)VI#QhD9L(hxQ_Y`zQr?TKv6?yI48;W-k5Y-{**i81C0H3io7PwTw( z(x_f#Ngli7IYmuY*dE3EZntf3LH${|47SdMP=U2I`%qp+=Wl~wsH95d))ty-K9xDK zHBn<^KwYKFPZAoW`0@BEoOZ9(Y_zK#;sACS9gt@011zYgR%TRcorict0?zKYQnU>= zw+Q0=&Z%RSXte4x(9ykpu2I+w-Fx=G;uJx`Q6}1AuX_X4Iqw6qi?DV0*)eeNa+4h@ zURDbE`dq~Dlj{xl?P4!{@;`+fea`grQs2U7@6FWoZ#oc>aMwnOv*%AG!`vsbTKV$S z_7ZqXw*f~Yy6};gJ9e^eO8EaK_ym*a_JArGeSO2f(91K)0*DBJ$x!iuXuPB9-OLY zp;4+yrO)q#l&isecrjrNhT=#8A~&z5nniL%L4JkFN2Sv*Z|s~CtbQj*8(I+zFyhm- zhwvt|>QVV$98%vzo^=jb%uX`En8vdsRioP8H_H4`t#>H!#{b^t`CImRm5#z21x5a? z5!7MBW~#mtzBhm89~rf{lU;@1b&VsLD6S|Al!qsMDkI!d`#BtZ9<}z#Z94*_d2L)I zlV0HbC9G2g8-6-4tAl!8_>_2`L?%wUr{RV9aFs!bTa$?yynssujf}G?Hqk0|QJtlY zt~wct@A~NYSND1p`ds}zQ^5}>)g+GI*jt7(lN4=E28c1}m^`aYqwpc8y>c_~x}CMt zHeg5#$9KMuHQmsfcQGF`WHWxso>8aluk!R)WUG&BVbd=(8rbf1)#F*Dz=DBEcD6etb_~i2c z>R#y#KHNn?)U(Of#i}XP+UYSbH&89$MMun=pvf1H&m4ZCl*y7T1LDHfAEP!_ORR+4 z&DFW(;#v}0^VOP5k~&Zr9|7wXtTC|GX>rPc?45t-hT)mlgPS}SuOh=GnjuKFDyLck zIvTj%E~NhD3X3DPN9x^ExP+-Z;|4Eu@GF&JL!(URTno74(do1K_r*fTU8Fw+{0-cC zlJ?Tn&$pa(1NJvpfcb+M5?0zXv4R+S!}bIgSjKQp6xjALx9NwNh^rY0W+Hp8ITeRg z{z9<1riX}hpz%ky*IpE&F2o@;yl?jV94AD4th5e{UU1vYlV;6+4Ee5>yV1Fp%4FE{ z!0DlUf%zqm=7zEfT;`VFQ6DEz`l_q{Q)?0wxY_k>?)8t{1GI`Jit$!ab=o;5rGl-r3~gOrLh{~$MP_HcENBm)LU*9==>DzS z?$h{QEtnPdTs(4D@L>jYH;V{vZVsm>XLJHGn&7wK?P_wFQSRkXYkP3*Jk8<(txV^J z*1O;cTyW;nM6Yupu1!0{6Ho2@8hHH-$s--AtXtDN*#GW=^csnkKd0}R7iyIWRd(3n zH{Q&npQp+VjuV6dqSu|{Wf-lZB3dI-^1m88PNf;2J7{8ROq3p;zWyM1zc4HKLDU1S zJv4i(JvUi|gMi$R)!p4w{yc$lb0T~3+6+$bRiyMg$trbH{jUUo3yb6sFNOLT(uq@X z45?VU{p`GA@|Cf_-U3-jbroQ|+drzw{R0AKGQz6vod)Jr9T^8h{$ZAB(sXugTpR>#l5Dn zx_ifi^vg+961y9}gRj6vs;j_EV@cm%?)DM|rO>IZ#CEBYbfQGO7;&=;L7j(CWhVZ4g31#No&|~d-yJ`4aWU0$V8oPfQHvASW&%e8MsH?k zwd=luzDEy%NqvY>OYqdJcwwvL=!$}3D)iB5i1K-0fqCul_KbiP+cqk$qQUfUfOEs$ z?_6cJvp4rxTEtj#ePdwi*EU}#37{)=0!xTDtNn_@AIPI`E|1qwLTnq{4kDHHoQtv^ zra)6mMx=3mo%N?O3Y5sR^~JR$GbjAL3t&^-UkC;o*7cJXjUI5GQ*o6qAybP7WRUqyzb*e{H$e*Gs@|H8TT;9Te4K9)piyeg2dI1x-H59@ zZ;C5>TYl(fknaBqckqQH6kjLQJQ!mpH<)zYb%HHkq8Mo(FBeGZVNT2KIF)^;>OFZ} zXA~ljasEhXms_T(!_xr4U>Jik-q+)cxM%rezcDR#o*ozvdT{;Cut2sn+Koqt%r~2hzoZuam7(S$1q39IBI`+UV}?vn={e zznNuvx(;!*`MG7fe;6k*Ye5#jHdFJlFRUsXQ8;BUg$h9_-T;=E3T%}#Y(yfL8&Ub5 zIT=P={h(YE?bPWfzpvHODpszu>&_tceu60#?po~Pe{MMasiFIOVy-5|_vMnOzV3F6 zEU*}oTTFS+YB>uShxg6NBZWy|U#8lhF1?`FX|ZivrT_J*sIgF9Y$4@)xK|{AT2QXM z3*H3?^aS37^|z!VTytdDqL6i1*^OI}?kq}Te2P8kKMrD`Q^ZJJJ?csEeT2E${cWFh zqUD!FtN$rk>A5qm5ikLMq}JrbRjKuG^kZl;qZh~XDpQgL&;5Hx()aQM__7mULRs4b z?h_uq%%pSwDFsa4I3@X8Jby564+Vjt*}w7Wv%w&7SCaiGL9HBUGbW zQr6&y^YanTNV_Lt71XSB_~lkO#Kee&1I(`Hh3Q87YR`n|A^9F{#)2|i=JwxB0FYmN z_4<_!f+n0V-E zf~dw^9#dE8*R#b}Xs{8MS_@c;EiPY;dsUXwMN8#XA49+*$Pr?X;!r z0eH+x_abIe(3vg#7?y`u#P@98M*5)H@yt1YxVQp9?e?-4DTh&e1ZcH3r1#{H0=_p^ zuTBn7on>zXDO|S*75b!JF=;P`{ByNRprZJs%Q6OP3Ot@F^)7oyaKK zN=xO$JdG=QMS+tWH3J%?QrpJ|7KID5)^#u_qxZFnbdl;1Z|e=0iUbXcHajc=n>+## zZszMFBR99O z@EL=I8&NJY10-NqD)`UZ3L*1w(9Hu0>e6J}u zU2I!gLC+MswYU9@MoLHh6<#d2wdMsibIK<>vn6!UDB(HI%0^fWCA8_+nM=oP&}Yz_ z94txd7&w{GrN*WEkCpV8rbgv&9hCXTJefb)-|DC_gICliL3JI!te-8R^7NWC*$D%z z2Y<|&^843w>cb7cR*At3D9&&G{hlcs&Q;+aN@x82+B5-Yr)j6XU=mK#V!_7)CG5iI zufVDeTjthtw z(kd!gz-1&Huxi!;J!gBmoM3NnFDz<3Xob+#=M92$U51WyM_CGqUggRPjzgRxFFYI* zt=Sju8{?>S_;t$45_Mo>Yl}PG+xzQSm_rQ%C9^fl8~>tqkz+?SRs>J%{P-E}TB|Ks zX#(dPZDT&X2#NoywzgLu$~;&yGen2WwTM$Z^z&Og0jHUUC^hiMh-qWYDYWY5DcIem zZgN7vIG*e<8vixqs_6IeU|Jcyb?Qm+1#L{slgY5EL7(SSz-u>}BHLWXigv>`5yLR~ zq3!+oMzYEb$0Y8JLA$kC(&l@YFxd(X|N+5bMRPtgQE{jHq{H1h<%rc6|y z2j2N#CZ$-S=Tbyf3OLdEFW0SrCU<&z^pV#=FYM2BLQguBB*8&)R&2T1d&@UPD@yGp z%=*pli$k>~hRY9@1p5ye;2rj9iKSV3)9<0^b$0MYbqWz*d|(!i|4Wrp92tIcqR(F( z-QdY*4KFgj)Q*H7hE@n!O1hbY?fws@D&dP>R_VaQ%iCR~nEEO3))x_84rV~1EiErR z_vS)Cu14&R^~igoT(N++si_1*B_}2i{1GNSWRhSn^U*>n=m`{_ zzRw`xhM34DwlDi^hs{;mDW4oXAA;bEfGLV(`mV>?)MPuT5!< zc(AfCuTjU9QT0cA&_kprJbzTERafp*Z4WGb#3;Vv;F?E>OzOEjyzM`=QI6AnnJ2eYA~U$-mT-17$q> zNN~-$^yTjZWm?GkUN5WpSV@|t7Esc!3HM`HQyTZW1~=qtEzZ^;NEBrbN{J3+;)5^Q z)&%;!s`Lk)8gfZ=9p@k{Fx5SS$e)g1W9`e|&#)G{p$cQ2;#_XzKpSufdKJEZbJQRe zu;Ql@^L_seRyIFSksPic@kt-=;oia*3T{6fFh9X}yP3Mvw!4a6?PH+>*o4*gXHT<0 z^_lr;7E5zbRK86YwnDa-m6)ls11?*@4Nta<#}{P5$%j71J_Jrr+rNJo0*TG`63_!1 ze+f%x)uR;=q4@lIR<$c>{;0#*-owC!3vBfMcMt9pQhC)66405l5GT9JyWm0+rvfiM zR-^Vqg>UtGD(4MxCaGV7*5FglF;7>6+H|kKV$l-s%iNMdFen*Cv+Es{aQIFIzp!==!nVf}AG8X{9akP8wO3NY~ejAYRm`igWn&EN+0)N&s$qNa`VQ zBC2I194P(p!u8qNhCCMK3nY29obcpV1~jvXE`XfcTt%69(luQ6o=0N%j*fIsm{><8 z9^aCH{Z%uU2ueDXB}S=QS zb`W|U0(g3{Z66Mn+hToBch^R5NBWs8o}jPPyoJqE4b>7ZYl!rBz?xeMQd!{Z;(=Xt7^mZ@HG^m10{%PE9|USQ0Ag z)dHcNgC-m8fw2Y(=(*YWrAk82CI{1b8G(;?LD^cfDIX(PcOwKvA!|pW6^|j%a2i%A z{)wSA;7$~4;0UjK1gxouh_H6O`Y8Dp~;P-t4j&CU^ z%GXmUsHpcYA{A$EJU#o){~Qeg0qg}{Bo1}o@H^fk@X&-7&_!`}aorM?r|N8WqQFh* z6>uh#41Ij-X%D8?;am!89d_}d3pR1V6;@g~B0it2N5~dieF#8$y)<9~OU@GS4?Xw4 zc+=C@NBgqT0SyDA3%tE>vw~cCLorUkr`(>YB)Pl(1K_}?U$HE^Hxv< zk`xy#Gzh71GOY8Z)Md*K*@vCKHX2Q%ff+X0A(wun+Wt9b!hQ)#(V>QZLc$@)J1!SG zAA-EC2j8!7B4lF|`cq!;dO91%xTMm3vb(18!RfuVLj!mOSqc+2Mk=*7ACrMSZUsn2 zZX-=dNQeOJ-K^}Aeh9wQiPQ}k-@A@roL&MK#3R#nI(AT9OR_z55_VTG<)o$$mZ{evovpdX61zGsZ;wm=?0 zD=TzZr?(RWzvDejIs;n1Ia=Pv{`mY}-aeM-ccYp81?}gNn;fWe@1+0alX=dVGe6BO z5UEM5f153Hq>>IM6pkSVQzLdFm z2GHGc(-=aAMnLyX+YYWef@DldGnwl@;o-+|pK`%Gz3P zxj0gUtt9YLMgeDBFR)yd8KyTZ<9VC$t6&3okfLE@6CKMMTBR1Hygf_KuPvvwSZH+A z?+9$m;$^>-MXk+m)V4~SOm40l=AgftMxPvdjO=|p}vJHbd6SQ)z__I#z)KnjCY9iRp%pU8GaoH_4I zm!~F?(#a>t0G9W7y^R`;xPoS>ayMYYEzH_Q^bM$(!;zX7EVpLp8~B;GzvLQ&Ea_AQSQaRQ5LC z;`fhgDH9-9fJR|f)a8fDpa;mAM-|Cs3wf;m{>>^z_f#rf87LZ{$*cnqe5Qt3OiJzK z2CqLR!20d+!^c>i;4qcdA);(h!_qlU8c%`1Y>iSl=*{SBlZ)&pi=v~#>51dz_sS-j zKkr&bJJ2Tl{P`2zt$@^)8ZdnD(vA3^l7dn0N!i=jFx+U-itPe>b|Lz7bHEW#Vu2|n zC2xZoKf_inU4vT8A9ph5E;EdFB$}l-%4^-~#1@CruwAVyysu!8@uP$0J++q(=qK<} zPFL6s7H;iC?mnP%5u>rX{tp)byubvM3$G7C*5MZB$e=BR_vl5^A_yWVI$I|Lb&4-O z_z;3q^$yVM2ux}J&-4IsM$n)9p2YzY3p}Y}{aSM=r|}eLyJRT6CzW_0n}pKYn}Wf@ zpu0=P0V>6Y9&(+#aaXT~VRFC>kW5#N?#Rf%OA)6}P)JiqF#hTpUHr4`ePl(gEwhM_ z?K@F?X7CO(Szr*=4^g0-VQk1ek)IJE7jPnUX>x$$!@=72SfLkEqlJ|j0)2+2xribb zy|ZO9R6F|=OxRpZ92~0j-zHWR*-|sTCqZ!1-(7sTq9bP2tpe{bN)d=H2K4jj z1CQEh4BiT<*qE3uV9W<7e})-J89NJrz}=LCz#uWaI@MUS<^mf?f`xAf6?f z|Cm(oNAOEN=dk>ok7c@W6w~&ewVrpFq?9}lNosoTW#8D#14K*%V3r9vBA7MpORp^T z4-)_0Xys0dsl~7TJFR$9Wz@vb`_U?%-Q~$70b?#5H7H9qyOaGcgTMfAP*2(rtq20j z(D01p!nQPE$sN7c9f_$ZSr=XOC>s0Avh5f{idq9_Y6I~4AAlH2B^2SKCv3{Qw$N8P zVBp}8;79e4_CmSgb93};IP%C5Pk4EG)q8Pu^ozCO?)P^AG!EN&_Oula1%uRvZ~p*# zdEV`ZC`$Ik%y}B{5n5ztR8lSt_4T7-SPd+-jzwYkiSoyZEa_$IQBNwq6o^)M9xT2y zw<6GyQ=CtIP-qWkQSH%fCS=bL|jRv~DwL*xw-!Rf2he{%uc}W0EjA9(joq+FX2}79n0>85+HA&5)1nPALGsais%fD-X zGdZJTuiu-S*7anFpe6v8s_OY4*T8!R1C_Njv zz340AtE#JIb)ddhQ{bBJ#dp(Am*Ljv#o51}2BykK_vK2l6(MCKKz`Xnr8Wtw-c0#l z8V>H%GS|=IpYqCmD$}c>vNe#v=MKV`O=AFuk)*6!VW8bu2@tMemh8amnO)A9iBpst zYzWw+1%M$u!rJoBN(b1RwmV`K{RO-1WV!Sx(G2TS{SpiG!wK78i#SlW5%t3N%yl+n5h=Z~7B#E>iMt!pZQ;jMZN}>PMo%d~5?JWX`uS@GW~%>t z?l9wXcWC|1;%@Rnl$8E^1Nz-t4ZtxybpH)WSL;2t!h0d0eY5okIPo0)+z&!ehay1e z2HYS7&B(MPm~Uc%D{#<3n~#t9FTC~|cNaF(WBNFpYdQ$o^UwV~cIW9y-CLPN!1MJ6 z=@-6!SNX9Pnqs$y(-#CRASAZ zs%?z-8&F#FovL>cz&zk+gnbNX#e3o9nnKZh?kXp|KpbU66yFl7hq2Qi>58}tp4b?Z zg@XY%^TN~I*Y;^SCpHbO{vf@ z;p*RTPk>Hg7?V)ZOMk?0zRwf`Y z`PyH}|6=m^2uxnlMHrGt1@3}!d8!6>Kp%S#(*VN~**liFscV7GFUD#{ZGp;B`1L}3 zt9wHFQQ>W{jQn;Fc^aDbfa@n<5+a!{-yV8Z5K&AC(%NH_I`jLpg-Jjsn*9uh@pCLu z6h;@`4EhyDP4ZH&bJgwfMg|8;KRUgS9}q(ZM%7$39e$!o&S030XQ6t_{5nR80!NCn zyjL~;-+VFRh{(LUXd2L#BUkjac)5t%8#aCe9cEWR)|7-4#OU>--1r+fV^VIQ8&aa8Z93vIXSPm;VoBU zWMV=y{^G82u?m_>0_E8WO}}|}LJlK+ZMkF=WuvW+P`Bxs7I1mY4F7FK5H{!$gbhXb zy8gQdopsSQ$p6*vgF9NRmZ<=j_z&)XOBS6GsfY6|&)>NA#8_OV#?Rb zkVVHu5POX8P;UoIp!7(mNC}-Dkk%CZd}Am7XPHn{@wo zcvm<^$xD96m%P*<0T@5v66fy&9c=8g*cBBROX`<%$_SQpmJ%UnyG-@}iyeCAvTk2C zeNhDFogWfHwA461eD&rFLDKPOH+~wQwcX3~O4HQ8Ly3V-!$r6J<7Zqu?HQSM#!D&# z!cd(;Uv!_(_Ld<>g%ME{ik1j2(nN!XC=Kz>vt-#;Fbg0k<)q)Vxx8UEN0+?ftUXl5 z3eQ-hbJ;mlvq`I2mU$tbEF^+41ff)Ie_Jw&Q-Oh8S-fPQ>X4#+%*3P9Ao5H{1X1WG zcQds)Ull$b$T4bYrJXb!wnZ3pUGecTE?El^v%FEM=nZW7N({EPNCKa-;^1Q>fWHU)G0M}syVU5@vU z3*V2V^p|Xxp&f||X_DIis^f3~ibkH0W?Apty zmt9=#eS>aqt)@t3UAlQDx-%c&}Z`Xoj*s`AughV`;}g^Yl-No7_52!aZNKp9=>EH7mb zo1uD)QrPnu3kyqIH}k$oKtKSSVFQ|g(;_aG-91FCAr_oy`-6;Qh+v_8deE=VzthV} zKLeb@qP7;DtzmGkr3Ci%{lI|BNaa;Sc?D0??q)w*JdB94FU`=!p6L1UR4uoIkSDz2 z9RjaKDYv(F=rqfE>7hUi!&goL3tY$#U-d&v@S)F;Owe=d5Pu&c7QoENQ1e)3HYQ^{ zt0J0_OVMZ8FNyn0VE(b`SCsZ;kuH3?*8_L-LkHUzEGlj^gF0(GKVg6hmSvm#sIr~y zBYSw|-dic)9PU0JbP*PnuW|cjd#+pSWVYdzXdF48%qIBbw&JB=_pMFZMA=TY$MYda z;QTM@-a0DF?rRsN1*E&XyF?nK1SCYdyFuwr>FzE8=`IDOK^o~4P#O^sDQWh)^?iTe zx6j^tjQ!s^=MTqlpxn=T*1gt@YhLr3a_{Xcv^&s{P7mT3(zdm6nlXSRV0XaJRjd8d znDMkouoD0PD&oWX_F$H;YrSNGZn5t>5SOI#1DjtQPn!QnH~BdO#4%)Wpom5>&w-d^ zyqgsM5UA!-iwf+105M)qr09={HV2R8j%x{ZX17D*@Pa$)H^U?qrriG%d`%-AHcs_e z`<*LJssJEj0-wbi7DJR?Xs_Tvwl@xBO&8qv(JLwnMYF*K7yuiECxEgB11k`E~rx48tib)Q$E_b@UAK82r^av@DsL)n8f8 zf3Hh;BY6v9HeYM zR--H&_7Mi9p_!jfwxRY($SITlhJ%^34@|}V`z8``fo`$a{t8*-1o6W@XB$veapbc^ zmyOL2YXCCNRhn*4s|15A{t=LzaP^>MNL%so|Iwn2Q3Ikkc{+K84Kh(Lf+mlN92+xZ z!;eT5;(l@P;VOmJ*ufzdS1&$D^Vej=l4vMRelDhbSCg5~RRdZX&ShzwQhZnORMv0P z-^Q-A$-|?aIpgyj0)$Dxdz}qV%JSP%?3Y5pp^}t~=b@7gUInI|ML<8ecaY1!RRTwm zmjU68t%cdm6(XBq2LY%|D>c|toaK5Fx6k;yT6fazRT>A~bVA#!S@VUaVvy|1I~>6n z-H*f+VAzW+{6{((#RhxBV~f+>AAN!e>J~PK@lD&Z00ePyDXmEa%%~5RvZ5QNi*NJ1 z*2*#hMZoSRF)AHKLuxT^h#+4^RI|*A`y3DAS<+N~xrLCC8@pH_Rf;NCl3-54Jc-;6Og$yQ$H^~~!7vGDpDFv)N^uFaGyS~gSS!$77UT;z{vTXBGmzP3th(YO_ zTFdh%`XV3jLAf=uqAG&<$pzN6DjW7-xFt3)K{}UHA=Utu#BF#h#tn+#`TCA@iV~{O zv5I2*Jp!eH36$VIrc*vUj6`7yh8bcI%Lt@Ft`aJ!jdZ$c_@Q`behbT(t-{#@+Ddku73Z-G%_**csd07B`o)TY;C2c zqJjba=Te@YEzZH~lYbyZRI09@On5MK8Z^njHeV z3<+SCRQ8lq?D(I#a!h%Fot@$$A|fHiH1*POd*GgA2)dM%d9Fip^9*m$5iZC>`OOn| zju^qO-APA?L*fz4(0fH}R7UT4>@1Xeh^CTep%#Yi{6JCS05TWXcus-9TvJd$ru#IMe7m9LD*aimMed1Km{f)%ha6|=#x7bz<+uE5PFj|=(_j_Uk3pgj4wtElH{kO@LaH|(E0g8_J^#bI*Q!+ z%k}oG3rR?Sjuhoc7}a5vWjqq1Iz!ccdayRzOoCX9s8^eOLVgOEd4T(ycoL{6@g3S& zazV_&Ke!1lY{g5ONgycD?enNOlI$_m`G<=Po~AU2GmxPQN20cvG8uV%2|ZIhXvJk^ zR$MObxf$|NY)=1M1$H>V@g}hOMwJmL3B462NFE3*4%wB*r`H$!@XzH-@NZQEsNtqc z;8)ebeCFR}{s?@M{N<;HqI2Zklenqx*F9FzmYs2?VQvzrP2o`iz?Sb-LNx(y^|9vB6!2%j-9TniQa zOrd);_@5OuK#yvOv^)0%D-sSM6NSFk2*V#57g*5~up*i==X}6lCxN)tV5_XbU0ON? zmn;RCl79uz1z|f9)lLw~b--h0*r>@caG%3~4?+zbHUM}e71Wc@0|WwX=(-x1!F?6P zeU1|Z?uWT2ouA(=+V5_1E?5od2B7YVFhJ%8P{FfdzP1#TlILeYEB5sQp&xW+uU$rY z&EfVGz`B4xX@vaA;^oF}b2?0CSd=7kp zDvuY7A{8Py%okITQG;q5N^-!E16 z8hokp*B{Q~0c!pCtNh*B|Ls!1gt=Zor@$s4U|?{%K6l`Ixl9C*>~5f;^Xp_sWpgwW z7iiH4c%L%qHrpbCkuSi|tO4N7(ZxjyV9VQZ-v-^Xz{|{4?sR7C1S4N&YK@FqgO9Dj z_F9t%q2Mwc#b(c0Xq@5FEcQJBD_m0PnxEHlV7$CKv%_Oi-;Mt@v~(Cx?gS6^G6hic z0ZsqMj07;`EGr^9=rjpQ_NeISGV1Dh{4bZ0LG!M9r6xKkPzkv0;qA>;M*~(s5vZ2c zH8$eXL}4<#i3GcCV>-vjXX(#1H__*`08TQvvDsPlA-(^M`fSBYI5X6lb9Y9G5{4`Y z2l$mCL|Tue7|0aSWdwTT$bHWZ&CDbQy~81(3I)|c7T&+21jF3w%?2=X!~+Z!8SLh& zAn_icA2j3QOooqp0S_IaNTwKx`@7pG0iq;iWHEv++Y-mdid%1hC=Jo$mto7(EImcET~_ZYz?QbuUH=}H785FaR(HAC2$qwaT`mh zxp#(=pH@A)`nB=Y7fi@PLP7#Mps97Ikah%pQ5#Zu7+rF&Ih?I@;H%{sCSo$wzei~> zHn0ju9_-Y^7ywQxQuTs$SrAcsP(jzXgALj#M>jW_AUMQtJ3HY?^v~9TI1-aq4H+oR zghfOkL-IV2Y-gZRKc5Vhf#!uwyZ4#n&S&!a0JXKAP?;@UN?>w<^_=RfvUxrVDJ>lx zVZDy*!$Bzn*s9s~XlCJhBqnsrBy@oh(bJ7|^7(t`CJ^8n6zFum*!1KG$}+rR1uOfm zP?9RF0&L;dSP?g@4$8#G@&6LOAl7|nkD{liSI;?pwATCSdeVNeff}G8V6YqBYa3AK zGrepBjdcZDwT2fzJMYcOz?4$zS_zHVnrdKsQQnmZQ@)Jp=Ef3 z2VH)=Q4!?7d&ZRcch3|s^2332KNUV?2#){h>>2js35vmm#-@e||5Mg}jt$NY3ta89 z-WP7T2VdWomNKSI7d6YZR>-H7xKXuujH zYvKP>Sj8O_fc3XZbP8Jz-iFLaYwL8zAgmkriyq$IGuXl-T|evBPV1KHr@aXQ#tCa6q*8vQQ) zXJ?3mn$&XVwPA_N^i-KivaWXhFFvGJVY(Pb!TWESBc3NfToO?1I`aICt<@1%De}tQ z^92sSjGIl?X;O>$;iRV}ynR&m%)6AwT+~ z%|8eyuw{R?{w;RG8DdD)K?V=lx;-h0yawiH1jhH}tlG`?X$x}xvb&?=%6w`J-3p2v&cG-JYE_+vGVyCvQVMP8T+Xcb7M02izNTnAd2}IYM;NH;LWBJAwSG& z8xp8bZKT{U1e&YKX{*0xD)jV)d#(E3P_5~uzWD43eZ%*yXo1ZUO3Gvwj5MW+H=oUT zf=+S2`LvuiZty+|4;(gEE9UTe6pr&0RE8uzpy)>{Y<;I*X+Mtq_Zt9D0|xsxbOa_e z=ekd>Epow*F;J;2np+rPIxM+89o&W0?pUMC%DT;k**WaYH!-AtY}gU;o;#^_K*a## zzqR1xhEtjzFLdv23n9ovrS;_yKgkgD3KIyw`i-6w3GUX$+N~bZR42Tl$bFFEp{TKL z@&Ee@M1-o&i_(-y0w2zI31gm__msx}(^AXu`J>}GkuOp!svtu(=t;=<9bvNjZ4-3b z@|ry9^Q?-=3Fm!ms#V|huT zD1!i+qBvgpR2JHt)PbF63YJKnLjyn>UQbIWTlqSJ|Qe45{q2!ZW;4 zhc2=DvPec0bcwM&Dbi5D9L+SP4+$1|w0~_JxV==E{~UV}({(X$4H7V6y@pC|5Ce0= zUv?LI>w2YM{mTWAsZY^oBz&M=X%dIM+AH%0)bf=<&(UQMt<&mkc&&+p4v8g!rlaFN z;*R_I`gNheZ;7b%Og-$N55;yUa#WoiuK*(VcG4(LU!Im@CwRtqv^Pz2n+N9PE-n8n;%x9aOdvM7ll zcvJw)CPxLSG5GQX5E0?`>=a}MzJrq01LEz=ztaeyyM9bV_2VJ3&X*xpj>B+}B*x$- zq}wlj_{nt>ekRv|@TD-dvd(sqZGXWT#>3DzMCQ!bG``q=QBLeuTB)ci;ayA~U#nVU z9KHP)cbW0e%AHC={}-YjFGfvnW`-uFN6rU^OEz&!hD+?UKAUQ4hg_7&yYOBhD26v% z45umqnK}h)qc&-G-z&WE`_(BN-xH_XJ;D06ub>@QUx?DEJ9RSHLQNJ0B*Floxu8&P zZS&%rg%T-}LlG9-2^0|ExYCS?$o~z@pp*v#!Q2m)+D=$7q|X4ldW?{~0)Fg6v)OHz zG7EhcpkvaMVtAq%XKF-WL033TwlrRDz(}f?-H6g0b9QujqN4A0gx*ho+BfwwNugvj zRS9S_MciiZXOnKM=6V!n4b(T1%3_>dRwv050NJ3zj)=?u2VI{rQutS%60-(>t50iz ziJG2(@Irx{s;K><$AfFr!fCebr6#+eyWn7xughraH+c1)%yJA$6vFbh7Rk9%E}j_V zm=As|4JIKjI2|#F=sP%WZ?bFa%u5Zugyi=s?`>fWJ~3~#}x(XYrBiZge3?nK@NnZWMWR*VZ3*p zL(?PU39ME%A+LO|Zcwyd>C1fUQ?)r{rFDACZ2huI9c*(-R5s{u|JRrEWdv4nQkgrH zb~6dMGQ4qvWDss-!PvW$)U z92Ii1sFoDcpP(E`0QNh%m{nZPLgz1-81&eBzj1e<=>ng&omQsNPQZV#9P;w^!`+-4 zNF;tGyJIW4zSTN@ZWPZc)}8(S6_5Xe z@NXLn_$;so$Bv}E~Z5g0~1qW5g`$n7tgJA7uh2zhbrT{ zJETGclIO+bzazSTJEcGUzJ&I;rd{q8VQ20@gZxXT*1vfJW+})UBBCJp$O&#rxUDjp zl_4HOX18hx83UbQ#e66U{|7;})W%ipWJA#-Q}O=wqdD3P0T&vf1-GuKGghugrl<_D zc`@hj4vvn7X!nKNFyZwd(5dt5=;)d>sbI0BRYpA2`rPXfL3$|K_Tc@YA2&6aI1x(` zl^FcAFxif=O0UgOo#&C=t5mL7<9uVZ-Gj(&@~pL)RyDcuPM|wh!iqsM*!Z5%`VJ`+ zz0P8u0PTo8kkd$Pqq{XcLJ*6#;=|HnQ*UG=BbSIZ5kUyM#LzlDx4$kj4Z#>reThZh zfHLK?S6Qxi0Ph7NbznBcAG`!I5wibyUZ>rKCmHH| zPx{_2YPUIazuRAmDepF6(kM(xQ1YN$?p+kMa@@TzK?p}O*$#13ZJl|SElQXAG`+^4 zXB|Jf-r=`q&Y}y!`=2Xe(H|R$I*nodMv27X8NwLK)H`v&n1(#lfZQ)`%35Semx&U> zo~JOHpY=lP1Whu?#84iqEK45hw{n|SQI6VX2KTqPpOD;0$(qLe)J|d7K-#iR#dQLk zIBqENOeN}q3?M%jJb!SjKh8HJ(EcAYyC}P*`6tW-#>e7$9A)tNGt@jjlrcTGuG;+0 zI}8zz%)SRfclR5dz6{;H@YT=gFsV_s7TwAPrL-ZZ%yel-t*x$d_T*c zFPk4G1LLPm=Ccek#9ooWNy2>-p1|yVfcEsjvU#G;u!wJrcSU|3R|g>9{~kFghXX@E z{)F5-7$algB0q=1M1{brV5tQAtmcFCxzU@!L|SVwOk{2}oUsQX3FKA+9Sp8PU}Mq8 zjtjp>e>0xOm?hEp)H{HQYe`*xgOVeFs%Q2NbrFxpK}517Jc7UJG`BdD{;tBDs^f5N z2HwQ16lHOyt11Xfh0e+U?kbcmvylqWFs;qMA~#pe;=JxJiAImh5n%fasLdK0e46j< z7rCvD$;d?A@Xif3USZJDJkt$;U4;c(QuS3Edxvo;6*n+1j{=ep$I*y>xG0^f$mdUA zq#*F_wgpRxF30+NJ5@dvb)j5Nu|*z0+6VN1?3Ybfil8*Zn|}qA zgj5|W?LnhliudJ_F$-1Kd<*KElLQ3_6a7B8#rsAYN1nx_Y#uZ|^T!hL!AXgRp)8tfe|{dpxK#RmrZpKQNX+jSn!%DA zc0;*FXx@{BMvW?9-~mHP6OWVZw4Xsqp|>OV<(P!sOo41J0MHXkZ^6hbKhp3cf)x<&HK zoqVg>yZ^Ps)cQY_n66YpfW*BG6~GA4>t@QCHOLO)#i&?3-yN)m**&f;3~Hs9dt0U5 z33n)U4RmRuI)_SL=6*1{YWc3+V2k2@@Ffxj7FV^wbLjqH(UoxLw?Wq(?KPL%XLZ*f z3+SJs)3A;Qi>2nphf8RXWE@TI5tjo_Va^=(iXys=n9p}MCjjoF!+5E4beGRd(pMMOnL;LuP}Cl!V;MJ_@agRcT7~BbvrTuZI>|UNY*7=o_#2 zFrngeL}5~{noVC7BcHkte0hHyzuZNA`&_Sxdzn19vo%Bcx+Fr+4*?*0Mf2iq0pS}@ z&%1m)RWg4ICVk?F9d(^-F9k$~_bH!TGxI>GSu*)6Qt?|Y79gBqy?F5gs?7m4Em)wk z-e2@IK0(;yB_5kL*52NpCm?tj={z(FLAhZE(a{}&ji7$1XZ`xoZ{$EMu20bf17~{k z^^TWt(&Je%U~=P~I)7w?%cNP6iLG(iv-IS8_i3RRXHxp_)8-T1FtD_6s?9Gn^gGhv z^06qBgl-*>%$c(L2!h*RubJRuN&iW zQ*ly2oX*tzTlhLfYPVr5g)O^5sm!bB-)JqPixMY6lSbZWnUW)11uFA}AvC<;*E#13 z?I@t%2OUAHV^|m*uyxJ$q1V5~3Z&(Yw|m$H+&u~VFXGeI;sV5GYt7ZH)yZ@pRmm`J zYr(hOye?R5fERji$3FYPc^g42AZ_n?CK;buH=O-q3*5-Y+@N{KsA5k8GcSa79eJR{ zkUT;K{W)|QA=)@_d!YK6A>zejA@U21z=nYL3YnDOy$E;_z}O+8B5^`-&0l~0+!}65 zfzBpgZFlT=Jwt+@HX*ga=68J~(bQKko_i%E{3mh>ivdO+M-AX8u$^g4iTJ@S2rm|x zY@`ilbBYgZl_}olkUt<=`+VS0R$@rDmYnu2p9lZwYWCTM_i6W}6rt*Se?-NMcO-ha zS`wA16vHXi5s8QG^>$xWH^(t!@_8PN=`{@;=xI5f&zNj#u^vs2mNYfUv(?C{e!Cgt zEYqNVaJ7Uk^GRX$+oRFgxdVZldw=DQ6SB!fT5fY~tgIQ9py~8`DfJe{rM;{-_N@W+ z#-9;JV=|R?GF>ObE42hbML7Dw@1I@MpGcU8;#KRDNEpVnpW2P5vJw)EWk>7|4!On+ zA~e>$>jnKGbyhn_2$!Dgw?1!Fr)@L%%-CJC=0+MmW?HDF73@6Zg)K)xZcWL_K~pVY zaclGWjR8>T%_@d+=HsAYX|T^cGCu za^KbOxXfUp*F79HPkfk9tW-7w{jUpbEFzNEaEK4PdxsDseK1VB_kU^gy&@(7MJd5( zj{=KZ1@KM?vVX6HIK0y3$UKcwZ7CH<2g{j8O*+;Y-otTbUS)r$D!dm&W{`IhjI3ORT+-HAV|9>?|!AL5Q%j5 zE>yv_dUVS#EA~VlviwOBzj!hOc_17-Ms?%Se+BS5Pb73B=?K}AK#Xxb!1dWEF z3N6B2Qup4jJpQE6*>XJ$c(S&F>29J=QK`~Bd!fkZ&BnyWo7 z3KMYIL%JpFv>~-rA&>5niRzws`@sIA&cqLzAA85aoMi^w53as^e4}*znMiaPwp2ww zao_1Cg-E}{6@weMWJ2&muC8faqxc76;)(Ib4T9t*y?54bY0Fo@Od$vxrJ&sK2Q@7! z<;#h-3)o6{(gVeHHEMG0=_&C#F%%%8myrHHp=V$7)X zHTr!iW#u}~BmW+`1ZKGM_UsldwUVP>@(R$E#zBluA4W)tg#z$sqT2NTn9f0#zov7f z!tclpgeez^5}HFL1vOI7%N5Wg?WZ2w$4)b1tlzb(0FhRknz%(L;mHpBdHiQKlSwn;PZt<|(6_irX91lYX-W;Z zUq0V=45cxSmuN%R4@(L7mE}tLddc3(L`ZRv2Wfa3;9o}pAWQ$X(uJU&AGrFa>XM;! zFL{d`s@7w|=~?;SzU!dDu%T>__sO9-Oq}mSXkZPhN>Z9@XMba5OwC;M*rwkV=y1X1 zam>->MByR6?kSNpXI}iWlw|LG5-0uiAi(M5iZv!%1O>Fs1l4|InjbF z`E=MNb-)j2UvkJROO&9vz9UCTQ_AcgV1$CR2M7%c{Ik_YurBF`K_#+}blV5Ff1#tw zFq*M~GCLkf+6Us;?YQ~_h=6qIQe%0!r5*^Qh?@8Kdd5hZiKfP}Fb@M{ADyiuXSWdH zvuJ(-$|~Gu&RpB$ao4gOew^7es4&TvY?8dy?|{%9$@$?@1dj!)!tiM^&8*E=yaH7x z>)EMhf<@1zN|7mTFZcBpePt3!((R`q~f3n{&k}1ibyK=<$(LVk65Q2X+jCkV>yZ#Hx z(FS>2bzdrA>N}qWinj!$6H$&MqyWwf!&WqLZ3c?D7Kk7l>^8l=DpLJGF;BH0PJ~|w zU?FyIcLPDk{h6LZd_;nhBo9htQI%B6q+RVL=Hcok)jT_&wLY=h&P&N3vdvrGxkgH$ zEHN^{Iu@$K&#YADS)d~kn6ESZKnV2xIBw|x3jotax$H{{#M1rf3 zPWs&qRs`$=!xM#+DZ5HLxbO}?UIa#SHHX-K@s!q)BWXk-iNO*KT?;TFM!2=cw*NKa zLRJfikyUC4pIJGlDd{{hXsrRXkJj~1mA4-eE;5UKJ*_hB8|vy3#^XFS!NI|ME%D+7 z&cp>l%U!u-NHAeH0%$)1>aY{XeZZ0rLii;y{ML7X)3g-(Z)ynw>yXzs{Cq-6&t<}B{NQS-+of1S4g?o5N!B@0Jc)E&#SW&6pW{T zP9)teuq7+G?ajc7#%x1b*)Yz;u1<(W@~~|B<9>t=;GX+DAWhz3Xd@b=qvnSY)WJp! zGt3qZ2`hkphRC0xF~FY>M__g4LzLMhmD5ILey3!iOX(CV3piA1@JjKSh}!TVtQjC0 z2%4}Z?H=E$PzjzFrTShT1ML#At|^Tl*gP*$R|5upDMPaMG#u^cNn+w6o@mdYy>0&t zRM;H3w@@uVarCyeXuMF}ou7t#5SP;xy2<*2eEflh5p+IY?R)JgQdNQ#4DTVAZJ&WQ zJWG9xR#srJllv84S8Gs`2{^-q%^|&b)##nNXI;8N(Mb5Y&?O1epyzV)gzJX`%NZFl z`L6xWYpPnRA(M5Fd>_n1la&&;BXVIJkRXj)qYhm^s+jFcWPge+#Ee&fJD}ias7Y3q zW`sWQKEEsT?KF|F6PtV0UDmDbOS`b#>yEotrD%Tb_e?=|Rc2F2uU0z>ZbKE3pY&}W zp{1`3RA6FI2uJ97yj<&xOBV3G!SWV79X@L7bOIM61rsz8AFmBJ0{hV=ntefG47Uhz z&t}mZ6C^;sG|(jIG?>ZCDD-YV%zec2h+LEcx3u5VdqX@~seGPUqX8iXeMzca*CHl5 zFSct!zOzkvvM|(XYX;+#axe7JkN1||O1`G&P%7=ym+3KtfR_lKE)x@VTpI~yR17>{ z6@HGlm?Et8QeP`S8F*)fzK3e#l6qPBH`E=?Jtv8iL(Ql*WTU@uMY6G-bU*Iu6c?-9eDbbGp3Fi}<*oCN^-72Vl#z3)nb}+T*$= ztnF7j2*KWdHL|+j-YU~C7vbYWcf9YWJ^g8c;!zsJq|qRtoTJ=hJg@5c`%aXDVuc2! zDF%xhB_sRS&4-7KRrz5aw9e=Kh zO3TP#C#0m{HQCK$0L2wqPfr0+1T8hS;KoMY^PgWa0XNIj%WDnjJwUuDFf`;BXoI`# zR-eqom*M~Zeb?mEaw;7wKl@j-&I#3wR$~U$`MD`s$z^YWYXPajyrzZ{$;IQ{l@(2# zTpp79Z=;8ebk#{5IlW!0?k(;cELQ^Oi4mBI#e8-15-A)SBq-Uq-!>0Iz~shnSCOO( zZ7#fdq5)xfX`=F3r*8YfDV5A}WA=MGoIlozD6-7Jd`QaCLGCc%t>oX&K?MXd~AY>8nhDnw4vg2Shxcut zzwcJz&7Ru0x*D^iI}qlKG?+PMl2*zNjDC=e{hkG*rlYsv<`p^cDj~pR`nDWb0qYI; zIzE9Y<`9oo{qgA65r+EdFNEi7!?UE;W()Ay8#@Irb4iG{ACbtQ5=xp!JWi`wg1I*7 zur93*b$e!IytSmHU1$DiITuNyQAf(!t?tb$RDUB`&T4y{c_*jc;K`2O$&t_KL+Q0^ z6YubWMi8wj;eeTpJs-cr*I-zwc9Z#e)B;!vB77d$k&VZN@k;Zq7Sp#6Fu#A8f3+I) zWssZbktq|&Om%EC={u8O!w93-lnY9nok$vKdg5?WZ4`_esG(6y|%fSOvfsnHntc0%kyfVc{!|w z*8i5})aCHOv~mewXU&tF#DBQ}SZp7E|LjT1d`3+-(2{{X9KrHNGjP@C_!OltOOw7z zIw1WHXOV96b4TwrDBf|n?imM8s1{_1`0&Wao_(rm{-|20jk17o5DP2%pyzEex9$6? z*s0>X?#Kg1$J0&hm`D;S9yvKWRas8^7uFwk@L6@q2HunR<^}s;lM#munQ%98sP-ri zvQoc$cd!_y^U%^%bH*N0mwA}R*%cg)S+;2;d!ogp6*Rme>UkP?UboZrGDpBg(it8F zg~41++m)zaHa2mvg!shDIN^XQN$J(s_D`+t@^nZtnp5M$yTt<<5xms!16OgOMj4cv zRR%%Azh9bdBuS@m>S3UNd34jBt%LEj(LM=Y9n>E-dsBhC1?*ScukeagdQcJgg9$-{ zygA(>nxjmOeyg#`5{iGGat6N@cgbhN5VdQZviC`qwS;rWd3=D928REj4 zL%A#Xt;3(j=NDR>^e?n|Q``(FOG~bwqgf;icx=DL5IP?VH# z`u#!HZbpxU%7YQJqDi|1($vWlCzrwJ{7U&B5e_@d(tSl+YuMi>V5#?53tBENtu`AaP-Gdv&%@Z}vd9$vUX7 zPdZ1$E2%IYK#gtwwk8lixJc5{F({&YoYBk88 ziYzr-5*}}j+$#~cgCT>@%tHrVz3;xdSd%vQFUz}_thPQJo@ITysCZJiQ{WyerH-Y?)3w1I8<{*J5$+ zm^9xKF~ntt7-EPrCs#D5@y`uZGZNFC=d60sN2k*i&^44upQm7HZ@>*aF;FA7M6x_J z%rAJSo!o-Nx>HRPq*37SRk3+=)FV};+Zko9>3tH-x3!~Q^f{ec-t`jB zu!DqE?TC69LjNBJiTzqR!qQ0E4aui5yMt0!6tnCXWdG!P3Gf zRqq*er7ydsUmvUp+=2!flhduN}9`B_NvS#a@KF#MT6uwU)lH`h<@=D!% z_hh*WWx{q2nZAOr_;-b7O~mx|d~#V9@kctT#mzO5guXPaCqO{IzX_$=x_prcab^Z| z0KNnr#t+f;NUaq3WBFlS z9ps7I?dEHq=;@JyA!w43IP`C7YcYj|g#if!35+;=0%QiW9$m8_z6ckH8~BO+9AS~} zik&^baXmcL2cbo+U(wQhI`kQ#@zO}hHXcufanNh)lCLqtzalR~q;aIo!6Yt6$tmBj zKbQ}^%E1M?%#jyDf0q1`>!-c)qSk{rvIJy0RiPVDXX1N5n1n;DvQFZEc&8q9I2cL$ zytX2)NH0Foe#ylVGqN;4mvL@?Yh6il2S_fYD5Zi_uj!FpbP0M^l08ooPghXU11wVB z{434WS}ic%duQK(%o`^K0AF%3)`j(>c(=n=n^@7!SLY~hlRG2^agq4np?fJBGb!;6k_@-F?5f8l_b0Q zj$YT7V4|ZxOZJP#)F$*Qr@c|HVSSw1$ULQT3!pVvekhtf`5ADVq$9pUz`G&DaE-P< z&(i|Y4H(>~TBXf>adGj+^ix!e_ZdrtW;H5c3M=Lc;e#MprbsrH%WjTsZ_9OS7{3XK zt^f$QOnk)rdd1h%=F;sRaRd$?kHeqgyjdxCgE*Pj>nG3d6S0Q zo97P$FBUxI$BXhU_=_1IOSiVx$QqRE=kK1S3Q2=TS93Mn@seW;*5@{DAYqUkmn596 zRA&sL+gt#(c)AlYuXBX$u}?G6_7 z*=^yMUDHF!AXmH9(5wLOkXfU}vmVfWkdNLYq_7&cfxaeU@FsbrlmtIt>Wr5(u@Z`c zkslQpR^!GuY841Q!6MvN-KZ>;^Y5A&aMH&58ZOWy^g1x|YJw+PI*>?yWE2MK-cg!Q zPnV8!J1CQ(5^^B8(E80(sA?oVqThBSGL~w8BP}Ru6kpI3b1o~YTHvd*hfZI^Z8A(Y z^P)B^l$W;N+yYLsO8)I56mH9z6^!49;uqT=au(l`{VrhB0x54ApBD$nZ~enT==!zb z(}2P=iA-}fXnM2nr86BP;|9=X;o{;71PWVc7RRTjePEh%BCyj4h=?ZBB}#M|H@COt zzJ@@DjLWzSM#Se_QJ2qm`5xK4*?u@#7&CPOH!iS~UV>N*DzITYcw9e%#hGK>o?7I~QYC5g=uxYy%i+U`JGxPN-AAaB% zVcn$KE7Zp14caetSdns2wkrOrn5!ajbvxyu&wlag%eqE1_9H(yjuQP%9`D6()AG#b z$z02}wulq`+SlA~?Kp^Yr|SuM58%f_VA4wYGNUpft^yD&wZXZL*!^NXv>*$ z_jc#~UyPi!-ygxI*Xj?c>G&TU6*;p2tr#;~BP;_2xn(PJ9|OWF7*R=4luK4iT9#5$*1 z-d58dwth9H2inqp$zDg>nJ%6Znw%5^gySL%q@x|wn@_+=nNDU@xg&y2pS<=9(P7U% zUD`AGl#}Xs;?cVw+DJz#cVNdyGZC!Njq+rJzc2Rf#vm3Y3n}3vQB>HqyObc@L&_jV zmHaock^E;03M%|4+=9#9=(padQbRcOfMP-oa-6mPYSK>jY-!7ha)Z)eN0aa@lUkQw zSu(IhV3kPui>s=3btaS87zbeE97)%ex32q@$)Z6#OMja?Q#mX5TSV28!&sWCLbD=j zWd6lB+;yp>s?IT(a`WWf?rpCB_ysc`1o)hAM_IUG?J929BpSE0`M6K@=DzjhW__#y#NfP3Ozsr0C!+&y*) znOG1BAgiDHh;f}RE(*kH5))4WW3{K|AvL`}|Dk!zPyx5~Q~@`Ih<8Hy4=dLdMWtaz zZdgP{fN`NxP#IF-CP4gAp1?shP)j`00-^mCYsMuF$W?B@^bv**_D!hyOQft~E(dJ7 zdUVO&!S>8&wU*yUVnS{|F0}Zys^qwn{G&Gr)xxwjG5sx>^O2d_>`{+V3;BQw-)cds zB`cVxnIp$nHIK|oV`V(BdSI>I$=!$k zJ(}Bp$+K#)C2X5_=21u)>0)=AD6q@JCF=V=IOnGJGeovg3{yPqIqiuc1QhYSfZ?Fc zb^1O`54A&y_4*ovST5K7=G3X>5$7fxG#$6)voF1|s2B>G>lL9-k@*L;do*kxw2xLN@mLdG z2`mjCcuy&gjj_)ab$PuUsp>X?{C0swXzR1s~641Z3DZ!|a`Z`goeW`6e8GgndK49WuAGgx}! zQsnvNdw&2yGA5mdw|wEp+%IqjZ5QdbcrNSMXx{u6EVe6F_fcPqI&UPp!LQI%XRpz- z)$n=L&}C*ZUILF(gyaart@~BocU!5kg}w|DZv4nEIQ0xp=tCtTEePti>XECsTZa^Y ze7iSR**&~W;-K3U6zhlSt-?q5@Z{mshw$u?r+{wo@HVt!wvYfQ)Pz0@=Sb9PciWkJ z+#t`_h?}X14ZAT>X8;cZf$q0O^_!d~9ln>2;@@GbX=$j)b~xxvrbZ)O4MfRBFT5_K z2Hv8NlqfFe_(mP$e#3mZ6;J&Wr0$@Wq$V43;RgY=P>+>NBtmU4in%z1JsOSP_s8k* z-=Yr>`=JA_2D!LlyD!QS@3YGz4eLcdP9XyFFCKlMHLnA;c-gDY?w;e6$XuzxX0k~D zL}-lEF29#WK`tUYaGtyC_aMIe)G!%IX?H=W+BSgJZ;oA|E9v6X3=_u$Zv+&KFeHl7 z_m__6Gi47k_K|{kw97GkZDwJ#yLT=72T->~#SYpii(D$ikEWY95OAaB)3pPz?D*|S zBZ~m+-8ao6m|w>kfoR}0Cc#SQfj*_6P5|ys8+DHof}Xo?j8I+3ff^HhvCStM&D-XS zZ*_ldt_-F@uq6BV%p#s9e@X7jJL-g|Sknq|4A019?=y+VK!E!3IQ-Z^Mv z(>!B-wc6(Cct>5qR~|!Q-~iUU^f~Ih{EIAM_iDF#FptAeI=xCUu18#-Qth-HPtMV$ z$D`5)OQ1{(4wwF96m8Ua@#||t9OiIIXAS%3u!&C+1w6P>k}YpI8_TOHZkBHf%!V_S zj$8e_G-V*e7DYjANQryl0+xQ4Lp=^^Fwx_?eMn- zS7u}VkJN?6-Rf9VhjB%-MRG+a=bG4SzP5$!)=xs{-}3EBN1~EUG#-@AdtUC*pR&1@ zhZx#gs(Ck*`z{^}WO!m7j4r8;mppkFJW=eTMWjpG)#gGt?7KHpO}pA25Z;=+y|%s; zO~gwb!kfM6a(`Tfstn=iA`)#P3{>#o`ak=Y$Y^v_c0p3uq4Hpr8i zSz05#BBTW9O*leobUbg(N?RC6!+NYTFy%{u#HR86n%@!Hao>-}wIKc2x!cmg&w&YW zWc3X6^iq^Sf}(vG8Wm7@=rV#{RITwgWNv_#V+72@aPgkf8Ag|V3rf&`-C#A$TY&)! zxfyMiD*IvUkA;lWZA10I$Nj<#M_p7em307~+=>sqP?BMN^pZED-BB}a;20KiXcXYs z--#Of^5H(01$&pmZQEwakRS@x3i6zG44@&O`Uu(rOj>Q`t-5jTY&QP6(H6=3na42| zQc#VEF-?Iz+th5k$mv>EJXMM0(U0fn)3ve(B+d1Ey-dQ=6$2?v}g3$L9$=dhf&c?!nL7~D$O@71}CtNrKMojR-mJa|t+oSrypeo@b!L^jj%HOAN(VqCe06#MssI zuT^=$1W4%|(M%`?W0%GckX34+Q&swsS$?Mzq_N*+r~jytIBZ2?L>WYa8JZ<_D64 zV%_QAC-N>YK%(}G>5_Z3Ga#PRsN>t%$HxLrR|4SXJ6$eq87U|7S}CL9lT}|~4KR-9 zQGsk8ju!4{^LzgNQy4nVYyN!Y`#_V$Hc>umx8PxY) zfg`{8GZ@+!P~!OSHmblvtxk(e5ls;!Br!#d@rA&w5d9#HT5fgeU7k}EljccKvJA6~ zpddxBHRiNmeur&)IXf}kK&X$@`bH}KT&^SMW(*CK&B1UG%1*BX4~ygs+6NL1@?}L9ZX#oHe&SE4bxVDm$&(;QtszG1zZ!K-q z?`J?vyVIGyBf=C5c+F1{@U^c|29u$lPvdIml|Tj~r`w+$-^*p+*KX<>mcXG&uM?*fI|ZpNQ}H zr^FVkR&wmw%?xalXJd&8l5v};O%&QZT>jwm5EKZ)bnk9l4bCd|GKhGvEfmtbE9Yyu zXdDqR$i+jD+(;(`caq1G&3S)1oX6VZ5Y9UkMRVOd@=e=C8Q8g-+%)}yidxmr%#FM- zPoTIaXTb?)Nw(UFd#liVOw#z^YaQjZS!t0>BSGKGyD9A(wLMBY$`2tNejlKax+%^E zd)oM?Wjr&sTD^@AjqamYu{`%FK~~?8?N{1Uw_PdsVC`I3ePN-f!!!Q82S}gSdG_Nh zNyXQQf+|f!^~Vm1aaten&JOpntyV40!9+r4pMiW2P=klWDJ-H0YEyw((15h-G-$7P zz?8ew9kkB;p#R+0KNb>|H9JHCl^j0|$>B%oM;B^!I9UYAfhP3Sv@aB$@EfIZ0~H~u zE#CViCn1DDn zfy{|y7ooaDcXw;z8BKP-GMda(2c5cuE}}}l=&hvzhzGmdcD>40+k}u7F6Ji_iMC%=EhTI7rdnZiIPb z$lP3M$gvltXDzDNNjy;`A`b;M;2zGIc!cx>S<`k?WYtvXGaR7zk3QesJ2_SN36m@| zrULY{pcD}(HGkXPLQZVm0u^NTkMF2l*R`Qa6wAG4|Bb~-WOj4zqxSjP1-Ns+{mF8@ zr$paLyT?~3uhOpQMok$9lKQeKgwan**#fb`B@NsCu4TnMxW_B%5H5oCOr&}rn!)iv z#4k%GFB)K2Hv!I{oCAAu`o|hGBgYVN!vVcuDWJtbo|}~P8VFGqIByLjV`7%tGTGYN zLgM##x7Q}t*2tWkoE3w|-=`TDzI@r(8cBblABm~T4@DG|-2aQ4-J6_6g7?M<%nN<_ zL6}f97qtwZs+&4&kmG~bHG>5g$|9Y@L9UQT)apn7btG3sw}}d`XBq#4v$qVZvfbK+ zMUfDc4oT^5m~;q}?gl|Xx)JFH>F!oy(xG%nN_Te)NS6pm!@h8>^}NTo*Z%Py-#`B- za^KfIt})JWh9i4k1SuPow?Q#exUGE_^KE1!Ovgvo{cZ23JsP_#xzFsB(a@3n6kfL3 zMsHG?DaOl=G)uJ-KmSlfDHY}g@C(70hTv|FN20I1T1HuY39EWO$RZIcY@i#Zc4`#wK1+yqO}HGQuu~ z!lSxC-(By$#|L3q`RGHak?XcQ^);A^BN?Wb-auK){8n0G^0e$;8~dfJ`uU~5^zH$%!HnK!Uz(cdD_0m`3_ZwF@e8OjDIZ@q|QA7en zEvcHuC$8UISC8X+;$~3rm{Gq(r6qJx3?qjib#723E31|u036}h&?R}5#h*^z(~KDT zH2G?SExwqj(CEmX-!%ht9x|vj{AQD-8c!V7HkJO2fA(;pazGCK$!Cdw=KY3?g~aL2 zRQ`F(h&86kFDPk#(R%)CFlQYuw}v}~V@jbe)jK`$%Xm$h9w0}svm3s7HRSz+mOZ_b z54s~9dr4)yxO-`3Fg}5=qiHKM!?oUJkZmM&ECbD9&SFiUz3>JXvT+D1v) z3Nsk4@j%FlZ>_0~G}wSPN3z$sf=TVB?eneSF#oVO{9Uaz*yBQQ2l0c0zC`*UUr%2) zkM57+xEy+4ADxvc09cW`A#ce12?d?SD6!_#f@o^(>JEG+vF&gVd) zP_G8FKY=;$HaPnJcbe=b^xfIj7p+S6)v_-KF3hI|d$I$s=Xs<&q9fi{h_Ns@0MH(Z zRLC1F)0|zOLVqkZp2u+CM-f-A3VO1F`=x!4+pc2kJH|yIboKWXVXOanun|t`IjIe! ze>`ZP{`!eUiMUrv%gUmF_ztZaOPuL4{b=Bzm?a*LDtOg-3zhcdy_+pEO4S>UIOcdjQQU>DOYFfK z!tyz}`^19QtW-vNzL#M0$waL{?B>PkCI%|>cUvXbz{7TYFqIQ8a)G=5bommxLH2!w zaRZAXFj2lM47($bf^OT;O5rv@MG}0Bg-y!yLBi(lwfLC6ujmD9u+)QnAfW4*O@{ z3Rt%~7>Y_;BezkJl=D8X6dyUvH!n2`+Zwr#|DlevJig45Di~#=YT9?~_V=ck!*~c% z04_CDCZ`}E1;NI~X0gEu1(3shTUvxb7}xvF!IzBMmGHpE$9#H!fn_9Y-L;V9p>c~Y zs;;D~F_E0}>4&9jyI4LqoEv$J7)?Al3Cm5ChaGeSG7g>JkF_@AtH-VQMP=bKiaU|j zBbIr*Ld|Xj(>5W>hu+ot$NM!>vE;75Po?w!4AIcx{T=9B=}N6J7tZX7krxhY@gd`Z z0r3~3Sg@V5g_&~V@pNeS7?z||@no4QDM|q|^d@Ku3F%ysyK2f(kK#XEfE~~|fU(;5 z3MEgsIf55!>j#kaYE>Izys#D!G28$ZYErnbK^83n=``ll8gpY48p>lIWj2aby3#}f zk|zS4W=QabTzTfx>pG?gHGN{_*Pe`4$J5Dqq>32JhL&b~1^-dGY*?~7HvmwPR)y_T zXnqo{(bn3!oc0?Fj?k85c~M*oD+^UR{@B=r4;z@FRSq8Uv>j3jq)kp+xJz8GGhVZD zar(z6Q$&3d2>WoK5ZG&3{5A(-;^PIlM=qpxd{nkZbKNTt#Q>zwFDGc+Sb{V2D(EB;?!u zoJ*-x>RtV1km1N3#c3BJ*xs;m-=$GG-u%=?J%1@ynQwbQkb=J%9!C|nzI1(#gc{l1 z&D8jdKUE$B%M50xhys|Y=<)f(Vy6*L9Y1F*$*pdJ)$Zs4|2gaTK0`%q=ctI4HY#?r zwi@qr(E9k#0Y5az6@)P&00jnC{>a-1?UUr&4@|I#ijZ`5O^Tnxi72Y3Or5zqC##%= z+`H37p$KP|?RF@%LexrldwQ+%M@e0F zS%W1C4L0c8>ws4Odu={a2Y+`{5oXr=J)=;wfEq9l0OR2<&uU@zxnxcMy?4iI--KBl zY87TzxZ!3lTcL9Evn4w=4m^Y1{j$_euybbe@&2^f_#%*j^XA=3jsy=(t#9r9F=|p1 z4H(BR!mKIWey_Beyi6*UdR1!?Y!l5awb($Y@s@8Oz$MZ$5rcR&+D9h29fTA75TZv7 zj>%y1p%?X^Ka zE4bG-RsBrhRM;i6dr{ZkTE4x2v+&0{XDef6c6)8DCn{9_~;TyO3k^(+N*naPR(MMzj@0(rVj4<-sZ(>vU^hsq-G^F zLbMX!B4Kj5pRb)`PBG|mL@A%TUWmzmdF18liV*d%_;0y+q7iMM+J5r~8~(2P)Q*3-=(jSjbVJh~12CwP z{v19p`T`r7tRb91$0e3|DOE&adu8~be*4_ul+Z*?@(kIH(m3wN1t^GyI0DT0K(m~) z-gy>SNWf$LD3pb4p|u8gA?HNB#rHP5P#{6J@luyN4Xa8!I654C7ugPg^^h}oH2`b?@-sgtX9L#rBupXs3 z{`(3nd)I6F0CD*q(9$RuB=OaL4Hfs-kSJ98S~_WRx`tKz-3^MK$j4vr^pv26tqmMO z`<)92r`^g^&9asD&T?f+(IB_Tpww8Bt9i$~L9mOzZ)+JE7#;3Ks5@Mw(RTRJi%e;| zleG+;KADEHC(C>K{cj|waR}NF9eXAfm3#hT(y%Cr>yPxW($>$hsqLEnfPh>65f&v*%gb8Z~83jNnOu_$V9s zv?$}@a(znfQj{Q~y`z}`pVL8fE=uwbYde%Ln~|dqKi&ftO;Gd#I(@V&;G#kUuhw>| z@F;7>KS(j$c3(8c{~%i1RQ$L%`<2U)bm`l<2zfd*ND1+Cl2&s4ZLlD>jT+is@<{tB zZ+L9E1)@TR0=Zi<-_Nf5?l1h+LS$ri%U7)*1}yM+>V2YxH<^BBTwL>d+J^)OZ6ui7I!9p<5&krsl zGO~yz9{8w%Oe$&p-RB@HEnhxeiuLmPTJ=)k*xKm3FP!V2{XGX%l45b+d#`ve0S<X*ZL0m}hO5jH<>QU;bn^k)hE6rZyzE>q?dKbw-;Y_a4QAYWn` zY<>hN&R#+=nNX_%+tUlo^5R~*{uKVesq3JzuD<-9{H{nf?NzQ!;f$T$`kJ4yxzl)O zP5R9CWzmIT&y>roqDee$Pck3$tf0+nzsNn_Tsv-A0AOlhjh4ioKAtp&#iS05?chVQ)^Re!A#E}n z&TIqAYc-enCXPHZu(^=IqSvFv>g9y909q29Dy51j$XhW_y4B;FoWl7m;?Srn>An=6 z1FItSX6G*$+v{>KMMO^%%BI4+Q_+pC8=i)I5(p+~l3l2hMq-Z5qwKD&IiV9X9=iGh z5)EI0nK(@E$kaAOPs5aTkL`kRjuJjj+e}dF%prRnY5|E&1R|t>3rs64G2?m0=tv3T zAq8RZ-B{ZEzOO989U@Rn)dtZW;=#2{(itIS0qMONeT9fq^HdY|m;GRAlcK1tQbh4( zA05pAu=*(~D1y)}>TFlUJ9D+cK(|k5zCf%8x4u1M_=&e14iKAVcp^!-h`@BxmeO0a zvy3%C4ZpsBY23FAWyt}byg`-?cgVP1kqJ^k6q@Mojgk~}j^s_um$Ds1S8=%wo*(!d z{t$$znvKY=@f$6x^!HY>?m>@2l?x5vz#htfe2UY;n=DYpXpQwd0=dKRau@g8Im*L2 z-ER)c2+8<8=cR%EC8Q>YQmPV)pD2t|dW$jVOvJ;mVIES(NrG-yH|cx*arZY=$2>l+ zSTgEX3NNjN2}N6O>5iHaqt~{FryPX~lISqjMrdd;ovcdCkdGYg1YS0^rT%A`4z?FD z-{Wa~^fJN*wr}5|W1l*L{uxcq)I>G5UECfpH`Hu(k&Psxy7CzMLefaYQLyzVU1}YI zDk3qYKP~P3`O*DlPbk%;$8w$u)-)|BcbGT*!*0d;1zbYzP&=&gV=T) zt4gZ?2Y&?(z!itclMUl}*#UNPN6!$P`$0=T3?}|;efqP98id8hG`@Ec<2E&*SBk&o zXfEN;R`p9R(GZ)3Z=@${8e=;}!pY3)kJahba~Vn4s?)gIBSLdH66DteV!4bBXZ>XE zLK*4EBF6ivm6w@}69_G*3T5KHs&xHMVY5SShndD$TQ0%qyePC*npjM@LhX;nUkmsg zlL~p=%t(j5UeloRC(az4IHt2VvsJb%{pL6Rc^t_q`d4bJ6nBdEfaB7Sk13`WMKJF}Tg+Xikg90t z$&x<)r$$ldIX#y@UGpGyEY-%w+Vdqy17{hqoTQgXJ%h+=LPA$uG)DCOL9ar_$QLn; zMRh!$P9r#1{b8BDR7OkMMza$gCkuLw8#zs|Q)`PcRqaZP_OG>F1yE_sv2cU4~!;xN%9g)2Zf|D_~e9i?pKc+S{f%F z(NFx@zeLf}!Ot;snIJWe@3pSvX-t%P<$Hr)aBr`A z99s6;*0Ckff@T*bQQ1^=o?rTX8X;DY%$XxP#y%BY4h?(i@2vqzs&y!?#$f%UkPp^H zl{=^3!s{K*g%C~;gI-WK7ZEKMc_CAtD`Z~3d8U;{#-0uuJH}9*%MbTIhSKY{m-9}z zKZxoI?-)KaG-bYdH_uSutYpzOxfeDbz*g0AM^2L)=XC#0_*1+Fb0~LStUP%?@c7ELT%}X<4Se@eKFaClRlp%84W*OHrgd+eL_x z24kps%k_R<6}x_2<^QxH#gX!u;)*y_WA4R8dVhyZui=2ANXhE>f zbetqM!fh}_q(z$=Sn+tnl(v5t!)8|Z+4WQSE#0mXmqpq>+TluA~KYmSu*N#{s%u;nd;&`a)^Fi>M~ZUe94Sm;Px2B zw9n6rmvQ(;w@XFPtP&TbL>|;r`?m3m=agFGgqz)0zlb0q?lv2}sZTs0%-PmC-OqPD zDTMi4tP$-rJsb}qG5xq1-Q@Y`bMd zI?b=DwK{0BSgsMzZY7vQYw{AwV3bDm!PPHKXGRW#QilxYqwCMf#hS)u+OTw-_Y;fF z;(PfRG^&ww1^lIXLWP5$MrC~n6vfYP{#tq&9_J^!rI33OiYmhP31JRaVnI_qc|Fg- zXp^sL>Z%H|?5WiHRg9BDQCZ3S#LGCy-c1ZpUSlmUR?*%1VB~uBQXkkC-`JrYJy_~q zV*MB)xa8Pm@RapE;+Vuj9X#H(gQ6{1p1Gg;p8Hv)tl^vho9&l03jQ zF5hfo>E{!q7n!IFByR!Ug8}5$C{>2ZV;zoTM$%ILjproa?FONkq$o*W+kjwjHnkjy z*I^@fkczD1MuJBrx`5c@g~|^9Sk(@=+-OVi*0v;?VNl_`dYru<<}>O2dAF7!i1z@B zdEnYLxt$>7P~;mNblXg-nyn5>?IKdSlOXf{2Cxhfzgtp2g2GGEkk`yD+Y>qAP>4FM zKEgGGi2~VSWA}Lk%CSVaX`~b+l*bJb`r|ejZHHO1Q{LF|_RT;|jnb6gexB_a9( zf}S0;SUZ}j5DVTfF~@Mq@*8Vx_V;UAwQmr8`LbxFat)Bbd~ePPI&%Vv1H zb#cf=du6vy`iBv!8#BV1La+-H@w;)oyCM8zLI()pHtLQ58ifeV!-(Y42Vz~Hkji*}{`pbsA0!;io$bCHqzI(% zp&T@nD45!>1snck-B0K@q&=o#k(`_{f26OeU(I1BdmoIgE$M&#A}Aw}Bws=f^peTw zY`mYKiV`NLP`i9UY3D4S!B4tnDz{aBoVLT2$5I^1?%frR1K^iZE5JNs)NOebogok; zF~s-&w{u)?QH$VJ+te}+8tJ`$==S%JS73k4wd7_xnE5bQJqSFvdFu;+{9wh+Gw3qL z5%Xm#j4{(JhNh2o7@YIwG#rix9i~%YlKdJ=)%qjJ(~86JejJ90;I0PwJ#>5wDW7lm z)9<&rp}*mh>aDRj!M0`~d1OUbNPtgQ1?ALbdI~HR`Vi-iKAqoI!0h!={BciL8HCV- zpV?}7g``WF$S-C{k@hQQ$jn4=9C(g@EqS}=91{ID5{*=7R4fONMc?2gYUqI%yijMy z{z+m|Pq6k3AG5YJI6T@RsOJPOO!0w3B`nb-O8u(<9^mUI1(L?Js&|gW{f;dcE_^it z2I(3@Z1XcXHv9{;6S!)&UtpX+fTWYYj%9hY?l1oZ;{iwaJ4FWYC=wkV9q?+$xmD0_ zaI_F`KMiTwRw*}lU071`uvm?VLGFEUotVoRl7jTzg$Yn#DUtk(-=JbXhYbX;SWi?j z(b`LsS#(H@yu@~d`9atIo9uVIc5AY{!}_L5SRtbX;F&1rO2v{=g2?u7$2&eX;(6Z` z-tc1o4T6B(mV|xLCpoVj_8%lVz+kjl=($2ZP_N0t=edv$S4L9Lh}_fk>d-}yg+Z~tqFN&mKzGw#plg0xf%Rc;g< z#(+ap4Xtu(Aue}9jt{6)XhW$Scz;OdWs5$oomtU*rC=3!l#h^Ks8U3a%d8*LOSc{Z zOZ9sRt!e}te}j=W!GsTVDiZv)M*)w}e0~naaMncEI66>!mh{#B{ExJ@{4tkIlg_22v$$Y;Q4H9DYS` zR^iq|4KIl>K{UOo0oz4)K3I8rG^TgTL;;AT0ievC6ew!dn!XG|#Sha6VxlYA0Xpwd zh-G9r9UhfSWX$Vp?){$A*_{+DZbINGmVK2+{(QP`A-133)>d z4d{zN5GMRh$IbiW@8X>13y;u9yyVS@53oM!0=6AcP~SEQdLv%(pLdkEeXX9kI4jvc zYx5#jDsz7Ob0C>iok2aXdPz^r9Ykt2JczJy5#Gdk9qKhAz8lM)b#WzyNk}TcIZ7VM ztN_-3{Q@QW1w#2yxvuOw7ObY+~tK_E)k#1mX#ZTCIF<*s*Glk$SsKaVA}E7&>HQ zK;wJS=K`gou~ziF`9IYA;@8Xv_CTG@m{yAfe8O_Oor58yLD^F?)E@vfJ!?u0rJ2ZG znkl_gw4-pQ(`r!nm8G{WAaoN;X@$y>k+}o;j#Br?@d1sL402J@yr(UYa9TDLET}&m zF@JLv8so^8JfXgl*}e+O9#f`IfmI&Eaave$#v&trAxI%2%@C*TFM0p)NEU(6Crjh( z4Q1=5qPED);dlW`U&-m_H9+7SbX)YxXmgSQ?N+WD$3a606=J&}_0ejp<#P%Nf8;c^ zA^WJ)D_~Uk@y%`xtNkD)zT;6q(vXhfg#ouCp@DQyXar5>I|^y~B_G$!ug5=ki~<0K z=6AL%>yAalg9iez%A=f|B%6t%j@BHYW{u6P&i-p8?nx^C)uS39^Nm)7)uo}1pz7Vfx8xliLCeVPQ&Cx zjJZSa$tAe1^rHWmN31F{A_3yL8t39;17J9}{V{vMlA34KO!StOOu z1b}^(6TGo=lSh>I($wd^FV7&;CXIpuN&I#^+t&?U-`G4=t66q#xT`(~&%nClLWG zy8hpo*BpB`S5NBhAWsaI=ZNx~<$%_YlxE~p)^BG(IFfQ{sr@paH;~sV-)c9_U_4Rm zb_~eE!ob5Wo>H-W6CTyMu4h1#MS7p-)XBFckA%RSGYiw>%xO247MlvIZ25v7NnAJD zhF@V#+W0jx^Fa;2l%eU087sk*6%ryEBBtU5`)tVA5n))9s; z&|SQ{tGt|T@?QM0$;O;PG0d`#DA)h!TGEpD{Rk?~X_iM@kbRlf^poEPVSu(1jA6DUj3z z;FNdfPLq__YFO(*B8CeojU7{YfhK0s{Z8874vX5v> zUR7jTL$JNI7;QWOPCj}gC+-{h>haGbb+Z`Dmou;F4UbZk>4fFZv2=Y z$uA0&LR(32A+*2l#a9YPmC>p0pr(nmu@@TyW^Y{XJS~w3@Iv~kXyUCgi4dOG<(!Y- zEy`5k!&80ghN@iiqVA_2E=P zmtU`GGMGNDegBK-u3ACf^?pa{S;K6aDog$(S*0t~tvQxV2!EX)7a+d=Imr}4URNQ2 z*IsXby~zRqhe(>r6vk_xArksGxwO(RY`#DySEP+QJcXg%5!IDNx~U&#tF1YlNoNBA z@AW%i&gJI}=IiByoKec#CbvsdxeTtC+((Ny5|F%ygl3@7V{wL6@>d($jg|`suiQJ0C6)XGnwp z!v)ZL3@nj4oy3X6?@KL*ir4xkXdYxP!!-B8e}nJe-!9;U3ZN zQ$J<&*)3^TUWDFIwZNIlo@teuMBwHP9xKC}*{B*?-FoylF2pG~9jfx}EmsY*UmjjU|lw znl)z?v{BD8?oQzO&yNC51k9Se&LI;K1dDd8iL8Bv8w2TRBWw4sfk%SZ{2O>UZp;|W~|!Oiz%I@%(oJ@=aWN7Q(7V>;|YBuDQfP1 zea9r%{er5Ek{Ut~uF0HVnCRraSMD?d;c?^XkF<8bUwxu*7!Ko;LawtlNSvYn)QBCP zHS{`Uo-nW#;UO+K#=|M?Yna2_fdUMmE7_OF{7v`&;e#1|gxxyhYE&?|+_5syz<^t?=fd8?$2$1RZ zt;3|O>6Nk`g-RI(MZR9Db)vnJ%YCf-qtX|ijLm0EgGDdWNEstRl*OdcbszH>{P>^Z zkkC73XXfpND$*B{K}LWC%o$J+P9rWC>LG~~CRs}wSksIH-h|rMS<2`-*bu9gciJ~2 zwY!eb{L`^!ZSd^muW%|X#C-8KS^h|#&Y@^m8q`>6bm&SFHu>Dcp?E%de>FJ6*_=8@ zFkSMzz+!#Otao;hD5>Xx#}9nptk-n>kfnlsUA=#F1L;LH7EiT+({u(Y>G4+NcSF_9 zDoqK%(_=bq*ohxu+|)&d-kyDXVcVO`LYhb;Jr|HE-?U$5iS=>1CjPi^4CWqGKpif> zX5zlOf}QEH^9PnZP{YriuR^#o0nQkS<+ppHKiZ~41hQ|eF;yX4kgn})Q_4{Rk2_Q{ zotciIg-Cd;*gKn|E%qxrjJC?_AIxDv73IYKR3zRz`D0iXXYS|QPhxi!pq#|K-YM|U zveQt=IxQ+GfKd4(Slt;FpI}3~pk5RZF1tnDq(de*ZO{sZnOG&Yy@NgB`*R3P(ObTk z*I{&{l0NzD%~$WVNxgYF-1DQwUm50#%&67y=x$E~W`EoLp^KWWc1TMHb(cS6*%{Ze z1w96+1VS?2dW@6$93$#Xk`eH_QaU2uiCbKCvMJ9<5n(Mt0}>6^`BrdP^qODAtA@$1 zIY_Mct;c1|Ryz$r-k^;MQF?vnCS#QXPKcU+q<+2Kq&^U0o^zB4kB@tC_sjApgG;av3jg|AMp`Tf}u@96ks zmRg0?M=@#EI2YZ~3`0QziQCidr$H1zNwoFT&)!sQ)xawB8jaMbyEJgNWh-VeaLiT< zPtW!R(D%U$c}jhZ?9e6R_fET7;lYc_HmwDUhkfp?ku)}B&2_s`-Y+`lMr+k`lQcee zo?2@=5xDY%4@OTRVNrp3U$BIH?mivblWFWYTOgWwSYh|-KdQTLL6jwwY?Ag2-|o;+ zt~9pq?9>a$$bPw^3z|q{b~xO0_LsD1J@DSXzU(7t!mI+B{qU0?eJ9Vk)baefsMSO1 z4$Gvh$0tW~2St3IZ_}5!F-zdwjr$=4CA{qOOyS*~EDgVM+Fk#?di!&rs^$}F&T-(lka!HOEj*}qj}`LFs2xQ4^rSouCf)!(QT&fI@5^i2{Uy(KqnPhsuJ+qF{QdQE$ z1_v~~Lk=n0Gy`swjH(0B;&arqyomzbt`4&nitaf+qs__V9TK~RV!BWJrCCM>qHA(L zeqV<0U_2MTH~91d4ZNVL_TKznFS1Et^NAOz+e^d~)Y>AA%|c9SGYU2sSRQcqEv|`{ zs{!b^gcVP0oSyGcg;Yt_<-A+alajeY^3UMI=W=|6iV&HdET~INZ3qm*%`Gf)J#IEX zH-_+5;xu?kk{|9mX{DxTiC0PB8}fyA6A0C_NJ2L5GM|t9qQQu1P*u>TNw2*1#x!kV z#8L|Lg>50`A*?Dq#9c~x>8m=qx%#LkrmWqCbyCN!N*c#tI*o2{abR)uH%#W);Vrg! zq(gI3Yoij_WRS$IJf~x_s;!4qh!!y5TBp3VTB-1F&#pR#`=fS?lIh+eXe#RZYuLy) zM7X~5RF4sE#%G2v&dO^u?(osSlhw2ioA6Jly+&PtDcQ~QFWAx)# zyM%it&)imLu~w^H4wr+1qb2hr`uvT7GOgpY8>1T~^(*zq{XF4ecno1Pc9<5=M1QbB zIA7UIKQY9 zko*huXT16EsBqdcZ-j%TU07qMr0N{FwLd%Q zpHtO)bC855F~J<55XzD7(XW_jg%4GXxD!QE)rg>uJ;` zyffkvne`+6&!4eeDHJrnFja7ddNeyTLg-r5Co2&_lVUojZQW1s6?nfGVwKyidneGT zBS_>t-+3NDYD2!L(KPn{aE%u~npl*qVKEo*QQpg13C z%A%sE^)+_{iEYT^%M;c4#w#Z)*reV3OBk{)g!CM^q8xbe0rMY6*a2-`d0FaBCDRS3Bz9%()m6h zVi~GB9N^*$jwM`K>wb%sc^fkSyYHUb<7yw758p9sn|w?^1iH53er7r2FY!E5%`l#p z<^%01I#3DFHktw+H=BJo{Jv0mdM99CL90jfg;Y7?Z}%<0UC>S$E)8h&e2mohK3^(9 zEOxeh^mNLW0I801Ai22%`ez36{OQXtIo~Q2HIAEMQG&B(saz$)hN{!=H^8VyVFdcvBrWI5fTa)rY}B8u$lPM!hG~i{*iP zyt&EOh#WRVV|tks>DViDyL0|tN!nG1j1ZIOnj{Z0FWkSLK$fpXVyk*R12Dk(Zu5P& z{%|*!>KsZJt@E9+OMJ(4fw!9v^$(^{E;oQ9T4}||0f8=Drdka>1NX&&7Fa`LM!s}; z8-x~%q@;0i=+*X!QKYkv3ciI~FuHwF__8}&WkH23nJMh!cfx6<70KqOQG@Gxe<#+! zl`etC0ZmVmH>Nv{>%lEL9ex{<6P+iU*tz&rcBj>Ai+^?gEM4mAf^BJiPt0XiO^deS z4@po!x=YqlIWxl9Ovlfcw%bJu$dGjjSa=KaRLvS_a78vT|EXK-$t2O;@a)OpLkJ#h zPOFy08k?@w$WO4Wm)Qsd@C#Q|Cf^fHG*Wk7iE6^F_MJdNjF%b8CCUdbpLiRHt2QrH z7&1K*o-vyGEJB>TvPdC)-u2gZ8#k65ZZRK$V{U{rEJH1m#A|G+kPx)lVzG)1Pwv`- zbJ37~=|x&`e|Zsg4v`}7c4|*U)R-1AB2o6G-sMNfY=>ZcKD9o8DeeE(FFXgcE(S%J8xnhQXmJw?N z5wF;gwf)+u_S|K#%aBGg?u@r8%Sp zWREV=JL}Y}`sbDj0#R_<(>tMZ&hHDXk|yZGDH=b<(AbeoT92zU9g=2HV)ZIKR&nX4 z+cQ?J)pxGkuwsK#N2Yc6R&r|kw5XrEcd%5#AnqJY%8wk$o=4mD3(zV?bN%5mggi11 z3{}BUj?S_(nA!?IlF|A-gzOe*;*8wg%vZ9FUam#WHj)&K=miX&@=mgBm?`&EIRtCe zgKP8{xz6EtrF6S<(UDcL=-REkx?$Kg1NgX=o z50i(r{(D-vlXt$=c-*}Z*#S(+R=G#eY;>wSPVh$9jJ`g}*It-twF!6x1`-Xh5ln%_ z>9x3ridQu&Rou)p$hX|JXyNRmiO0&X%_A&5H(vyS!0SK`OR2Kd;z5|u;`LE5Q~}m< z9Xip&Hf2H|s`E)g@o!ny0v)WnSp}U{{qI81t(VVso&x|19!5pVt)|_&>J$2P^h6Vz8lq6NWdDNo2w$Cf$xm_p`_Na-=B8krD*;buP;ch{AN8h)H$39%tetWI zW2X}DEDrYyp|Gpr7bR#7E|UJae0#uQjA4f>5){5+)KH~KX?s^mHD$<$=@vHV>UG~V zNOb>QKE;5WA#t|4-2>8j5``X`aeKn@hRZ7A$%00Q{Z~Ba0~8uIv#Exm@{HYQ%4oZH zQ|mlVn*wih@5E0!D81c08(vv%Km%KJZ)MOCQ#-xou z4RdDxKm%+*qBZ!Q{5axB9!I{@s3R5^LRR>Q7cPJAQzrxFp);4R>-6GI>~pgUX*P<( z>=saw`_pRv|9p{Qg;`G>_Q}QvLXk+u8k{X3S>s zicF4Ed8NpF3^r<87H!k!ZNAd*%{qf3^15Td3n5&d?vDOp*f>MOKe8*vR9(#MqV9^Q z55B@Q00n6}1AJzy{W%ZT*@h2ps3O1$x=M;EDV3%V{=?IMI${=0Mgm3h8O$GB!DX^K zjiy{+5boOH*cxkIp-pvFt%Ta&cwK5W7^=?q=0lj$4fMC^2UD73#)pu{%)8Q_rx*(( z0?UJr4l88PvuSP$3O zu!evrl$aB|FY-W?K1)cbgAS)n2tbwScDMhmoMTjffXl1LA|D5(S2^#))0BwRhyl$t zlUVry&0wY61oJz;^y7;@kf)s;xh&Y&J~u>|Ayk6yWR4Yv&5T+?$80`ViUDR(s8fOM zaznUT9n5}pTwTuoRAg{2yhtbQv3?XY%J&zOGx|7m>G+4@2y7{_3`HM{{XAo&wmcu zKHr-Pny5bB<}kK4MH^aw@L<`&Q_+MNO3!&WZOe)D!{`3KdG%BR_BHNHBHh%xVy$eV z2&?ZqrPs0uS+Q3Uj*o+95y_{pn)mZX*hjCU6A9VU#PJS zd&70tx$G~=HriwA9rA)W^5al_?Dnz`HhGR=Zn>lI5<*ccG@Jg_zeYx3 z0C>E#M?0eei1Bo(V7R-JSQ@@uv8lI33L@+P|ZC|kC!ev2A;QbJkHm6dYT5U5OAze@4;~!=jUgtrhkS_l= zj+hMQEZWlKhJizjBCA95p%V#FdVXEB6w{7@e?cclWw(23P@`w>1Wf!G=9{}RW;q%-0HibZcefxb+U ze_Fn4Uv% zD)E01D(5x6z56Q6j`+|)4M(1HKOnp#hVh0Hi(+1&#Z2I`8u{;%mtc>J!=iy*wnB-C zrX2r$cGS1?B}U%lH!lX6TTBnKsPV>-e^4{=qIXa%3{fn`AXPpb_0IfdeuTGtk&lF3Fw3C1i6Net^2_!Z z8&e}9$>aSY8l~nKH^g{wL&ZZy%W&cHmd91A(sz{q3=u1e?SsiCk7Y2FHZNZn`PHj_ zrFx~eW}jjm`p*AKiL;^bi3x`nGjsRbff@%5CqtE$8MV)7|I3Sw_5+(T4-|FmynDe$jXzs}$jQ}jup0O1f)Opj!}H_~Dd&W(Z)ay6XHp0cW~}l-1DcAo zH714(OsdvA+plG|hJ^_3b@qoDhWB%xjt7glnL=JLAu!N(RIC@Uy|2gd!o`p_l0X%` zZQ!af*@BaEI{gmp9w!8CA%o}>){MVyE>Y&r!thwa@`NiFCugli(rRBU zarT$1sBataz_r>xFox@h6sE&bEOq9-}ASS{a# zc_K63+!(vY3CI3ZBhImuPx4ZIMITN)_KWYtK#=iwQ;{6<|2oI_s-Q_p#e5h8d=rp# zk-eFy9AB#&kAw+W(T~rZ6i>Y*j(CF zuIyGW73!UDsi!cdjxMf7-}2z#hJ9@gCR^PkHs>x4e|>w#>J~)kzU%z=#(>$0I(?}J zw_?n<|9R_!c|AF7euGrtt&=&Fb%Q@IN{j4Xrxj1S{R`I@wSK^Ad_5oUR}J1Yt`~&L zrwZec!~#qTJQeUTdu<%v|-0Up(ZpVk9o)Wgy1-|;&iKKD;feDDG;ub-UKHPEhZ+JMTx+Ll9;0k#fKq@U7vMb9&ppFb?#JEo}eAQk&IPKuRD_E z%GawKR?{gyM@M0NyB+3UWAy_VeTNA8yu^(+jdM*}KIRU!E1FKIYUX-|M<2i)8k(~I zLt%!oKpj`o`6-#=vOwWnu9Y(jm3}nxPxpTchW=N5r3`~8>W60~sTdUrVn3jNpB4VY z4g~)kIA!}HOGShEaa;$hHss%rNF<8v`!I~CO3j)UOUdJ(e=KvJh382OC!Du;%<1oP zd)|P*r;_dW!{u~1^4Cv<1YAwI|A)7?49n{4_JsxMF6l;)?hZk^yF)_h?vheEMNs0V zJEWzhQ>2k@kd&0}ci#H^pXZ$GynFBS>3sLPyjg3mImYzQvT1xlAv}$Eu^BZ$k5%L)1*Q`PQ zch}|zfx^VNs$8(n&dx{!RW*w>tdyKT%wfL6%jryB@nb zx&pud=S%P_HkN8PQZ|HPYi*}Poj$pO-Rvtj$ZkBw17;H!>+4)#Tm*kBB`UO$hFA5L z{pa`Yii7^eUC%n>8E*d-bfmhn?dR$j0ni22#b?@)pIg{}U~{5aJN5rJFG7sSa_oK3 zHPT#z#A;gN&UBUo3mj`^T&TT|IsZ}%Q@qtuBin%Wryd(o%#gbc^r?myWQ|(}vAojh zsgs}`2p+QatMtBk9vpn|mh+^)|I*eH!z{Q*GmYPmw@cuD+Z~S;$rGUI(f_{3lD>b6 zD@^zfZFSy%FBqIKg-ucZbNFyK|A!Y%Z8^r)cKbGXhW&Q7$Tieey)LuF44NyhmLth= z3oQAb97CCGnF}X?D9@Mw)DGyg_{3AS;;Z|jnLOr-!&L6fZa5c){|snJtTZY>)~SHM1FBqh$xI?=buqYKj|^7cY7Y^w-*?G`3;JQ`rxLSg zt^@`+^kgYVIe;);qAHbp!&My?z1JE8Cx_3y!a?21kzExpriPsQy2TGo+s^9iLLgb* zTmIE&(F+7`8&Q+8-v}rXp8g2R$e!i1P3NqZa}o$RMoHxZ+{lvw0PQss+E^%z88I|2 z1sw7BEpUO4`BLxSpI}>NPf7(So>b7{nZnV4iL2`Qw|G)Oi)ZiMpL0D<1GGP~R!KM@&3UYJ3% zi1NArZSY8@Xac+IUjp?s3{Y6j3;-GgT;6!C(cUw$nZnOAiRW*&tf%Np)%1Zvr@X3v z2nMK3Le~x1!oT>U?@qpLtd$7;1<|$>eB%1j!gX{29uJxBK1n_8I|m;c$pD-`^}i4K z;j^4g1umEnC{0998Yl!UcYja|Xoe>pr2zCob({O5ua2!qZG@>OzqZw=PBg64+Y z&2iDtPkV-2OlKO|gg<(XFK3ZRWAX)uV+cAIuOmp=3P2=f@&1{xE~* z0XDZGI%c~{<|SOFebO0jd^Mv^cXR^o&(jm=9z-#HXycPi2(H!0KZL#TyB{K#<|tYb z&QJwfa^NZWr%zjWOr!qP1?V+R2rcM4QoLH9ClSDWn=L>-O9po#_1*b;&^u*Dv+9jN znrJJky&K}%+?hd<>PuAT!t=YznJ*qY!ocS90-u(98ok>;UgaGjBQatlx2?Inq z3Q>!OR%;pv6dw>pSt`qC9-sNf3f50^BC3cQz?`gf?( z2%CA!#qOp=0v{-U>1@=?Ls>Q(?y-)o5o5~nNxi=`8(zfI9N%%*A9=wZhw@KTJrAN> zQq8Hxmm}_9DTQTKEE#W)E#uM316-9ik(~{V#jvgzCJ!X{mV80(f`R4$N!0c}79?+rx}{@5h#r6iXH- zt+E)qEixls-dGZ;v@8_hjS%jWN^N#?cY|3%t#xz%XX^L^XZ-gUXGBE!scX#c^b6zl zs-Ln)E}mj3ocYK1cfR}$tWUA&>_uz9F_^Aq$Y}El+F?ayU-V%9{qqVwVQ8Fd= zX4`jn8C2>Dr;yhN!#X>rKAc|?)!>`;EwS?})&-j`XC!{`{5Ifz^s)|L z+|Fk9GY6UN>{kwQQSZnXxpZp>En$G)N5LO)4gO@I_mqyV(<4+!xhGAc>$-NezMaTf z2bYq%@(eLWquV8_AjT@KXj|7O18YQpZ#d*tQ3{K4+H*)`2xq(!NcU9nTmU%acK$q6 zVU`tltPAvP$-U+GmQSMjC_;z#4NS`mDcDLpZ4(nJp4Hw>fON5}H>VgjY)Xk~2L zitV^lp&iFFagzQWsLfecW7MZO@4Z5+$V5>J=t56#p=1Xdk(C(RUNj#`WK*qe){B`T6WN~(GXmbKEkmqi`mcru<>+;fZ10A4$}e-lcV>kSzrLRg=|Qg|q^h0%3`$)k=Z+@yc>q_C(;37_uX|i?FV#MVf>HK- z5;%gf2gspYW&tJXUV_4SpX!G3W`8tW>XeMkv^>z`v1(#H>k>B=oJ|7FrtM%#4G zo9)&j-rwkY0fS7xwt@9f3&Fy|L)i~?$HrL+X<}(od+k0mEC$9VDC^~8`ufKx%qevQ zR@=XTA`m#_VH1@+gL-+q!21BAunH~D-Hw=o9AHU@PL8)=CJ%7mg3^e7&y9sC*^$R}4H4Isgl^J5>_<%6B>-=690AW&mEF~M$u#q-*%r2Xf_FaF>k< zgmgJRK((pfKt2$z)TUFOc+kLLYZAF#+SUAy-9Hi)1jQvf?21se$JABJyy>*Ry*H4; z8PfOIQQ?j3FKzAp#2>JO;)k(J6uwc)m!&&Ky**cqjwYi!;hY|8zarpE9HB%_toS2v zm+LjN-&TD)y!a!7Z4$9e_vSBMa8avI_x6$WLP_`@?xlg?RG7A*GXxa`tHN#4AY|Kg zDWjy6`2NB9%Kt!J>-W&X6J`e+@DM(>o%nx3qM=hi2UKfSZ9|Mu%Uu?L!(kyfUu)uVEE zucIT|CV{a?JO(sdAsxduXTm7 z6}UUBK?q%u;jxZp>9tTkBEFKOM}(U%pnXp0&^c@txUZG-F!9w?A|7yWCCLiGnwxB+ zix(gnO%gBh<;5^Cr=mM!Gk~?;DhPBLklt8g@mek^{WhW+0{JWaPr>%k`WMm-r4buM zq2sU^NOQCMu#{RU_2*@P2kC+a)pw9`VgH%e|DNsD*SKTvMdyGW`y^Ka4BV98q3Q@M zvxz0u0L_xcPjLA_L$I1@z)_@LA(B?0m#fm{31#vlCiMo1c_l!jM z%WIyYLUC^voOi&k{X#qfF#3WS%)CQsHArAO8ReO%6Ra(HWjl%k#2IIh!{E!Bxe+o` z8D*2>-(rn>iBBLO5M>1%jyBVa$G0P%YXww9A6wAjX+7N~V?otb!PYIGc(%5j#8%aA z`El?QprX_o&Af5^9Wq3t0r2az`djPzx!Ix5WjR`o;3p%&FK@^Ck=+a>IU9vk;vC@G;yAh}FFzw=^bFKOWL19_Btub^9xmC% zcTipOf8W0eSWtth4h-EH(5oFl71svupC!MAYV)XgrS=RkaZkPh{WTWa&3Q0jV8Db= zF^L%Y+!Y4UH|k1RCJ!MqO(&0nb=_{;5%`CUqJa==tXW4#G2H}V@j1NQMCdoT*B~O ze5w+Hh}$@sr~489LZe&aI7*~uAcH~5IISt~0#d3u54(ARP`TuxOhr%u@H8|=X!@)Q zO~>ofT}J3@$ysE zJ}{qkx8Xkdqct^U{PFSs>S?D~ZP#)ka&($8KIt7ULMJMU%Zd@=JRT6n18;!{sy&Vc zq*cIV1oRcCNmyS|>yQc(OJVa~VghZFq^29QKDT}F#>*PnWPZ?s0ck+r2l!$38V|AD z>sqQDFUdPvwJ*XdAb8k(?oWip#?EO2> zfKsTYSI3;x91IYQOn)2t&jX_iNdP0Hpae4lX_S&^Wy2erSemSX6Ny*|Daqg;dhUWp ziZJpCQ)qB79B4Gx*8Ae1+h=PmM`Vkb^}o=UXqAS7eP;B;p>2O4Q+60+Xnhfn>L`GY z+0b9qZw;+4#8VaMZSce4&8dNr8{e~iAJjAr+JRII{x?DUe%s*~WB@u@ejIpG+3Ab% zg`0;mm?6GC;NC1ioD=Z#(bqd;^Yt=dkIC@2cS~0OPWy29mzQ00X8dpY_Jgs~=|-G# zT_yEXO2-gYjSLX=&A*!*3(Htpf65OSof~%QD^7MLTEl-kYA9oH`eQ#BM2J#SGa{_p zr5_znJo|ip(*DsFS(Abq3Y09yLT%0^m&GX7 zs~R3woRtlH>XMLu@QQ;L%o$h-x*jgo;L1AHt5xXI%1fd{W zTse(D2yEf&8Xm@=c>acx!}u%uaBL%~r)^1o2N)WD;Gn3aA{WU*(KpVC6pmL2y)h&* zun9A5!H>>Bmi*=ArD``W-@hKI9uzm#`_(fARbW6L@_R7W4d*n~meAN)QXVI3YpzR@ zY9Q?Th7VMf$l6+lS29aIq=m!5)sbV5XtN}jA_T_x_2)xAw6v-zGP zks{q@bRa}HRmyghV__!gf^(sQLO5U^6&4Y}CMAvDpRb>QETI!~w|Bfl#3mz)*&Kqb zPnPPib8`o0WRN4PEr1dMEtKz@?(8UV-@`)3{Q-8IHT5@dgi-LB>3^}l%qmjLMQ9Vw zMiV>e`t#ff0Wklxj?xYTTAiW5e3~S*_x!=n-z0>zQBt4B_d5)2R7Ui%5uow&tnr!j z;R5=k#A<9@8E+Q>0jlU}6gY$GT>Zt%AJq^mU>zT*rA7s)Ic?tdI7NQIF;fmma0WAW zP;0Y`k7$Gf!Fsvrx{V{FCYd)U0*6dpw)oIgHAmdO5vDJJillT;e-8^aBod!N5jM#R z7*3oH?+B-@Zq8R18Y|RN*UFB--tf-;etMY-T#^cMX!Bfz2%kZV zd&vO>Iup}DuZ434+;<}?JExNAbg?$-pU5u&yblQsV3(_`-h|y21}};B;{z;@he64N)=2io5YSzT9_j}@^Ao}k1969;5siM+rR^Kp6ARIt&YJhnpU8=>vB!3=nR3jVT zSy|`WbG{h%^EWFfxiywESr%ua^wm4{@=w5&DBDzgqK@%F+iv%>Wi(0seF1Cd%VWKn zelv~OrpehE!#^xK6>no><0@FLR?Y1Lo{02(oxL+y^`6L}fne0^(X&04>wLT>6&xJ= zUZUK3;zv&Hc3%v#Y&x`p70-{HbHFhC5%@FbCXOkQ0?#MU!Jj2S@9CgiPa~_{lYfpB zDOBq%8?I#V?o*aULOC}@u7AtuUtxQ{lfO9ST#GfW6hjI+m*fIaaF**{3<-Q&Q>sp$ zDA9Y>(5%=2o2f-OQ;&!cml}?;QR^i529Hy0U~Nyl z5EsnOA0J7$l18DjRIz%#iKAnj{71%BkUe&}9w%yIW(F%NDtdc!*k<*k2wS_{P_8!3 zVd-mxcA5SvxOX($itT2r@vgf6|NdT-+@EtwhNW^(Y@pTSzhI<51=6pQQ_y%^*eO0% zd%+$ljdPapFZDQ*?po}Ml92O}(^K$O2Cm=mnSJ>vGVs6X+B5&7YY$^qr`NN?DL#~B z6p61>{-F(3wN(M6AGRXjcDp8A_qS6D3eYZ9<9YAE5Y%Spj2H%9RM!?67t+1GBQX0l z{5V;_GG3ksG9G2;b3W46;JQQ4IA!y$yZ+E+(5EI_k@6WXRJtCn1TO3j5S3cw-_sR_ zIaX%Cce*)|RBN;Xxj7e@p_Uk|HK7x!h3}-R8QM zEm`T5Au%xq7yV>HuP3SP=KYYUvYXY<)TZtgc?1bC=>XL6zv*?29s5nY zfRI~^;_75W;y)tsR&0pmvUj-$w4u4T8damC)2h&iUn1uMduauT4J75t44XM5ez2tS zcDhvPLG!+c)0%^gZaS-82XPI4CNr6-e^zd&Aj>x(m%{BMPCDP}&p~J~Fh0V7(hVAH4 z@cLEamj>!UFVk;hFd!s@uY4~+kZ;}Qm5YywnT7)bMX=U zMJ=7g+NpYUxZ=hO}&wL;NFD zdzO>m^O&($#X}k>JS+bqZeI6m@OArw;Z%>&>BSYoCtS(w$2973e{X(!7hXgN^iATw z@aK>W4!8qI5g z$-#6CX^kgpxunqtof^G(%V%jKczG4ef3yH;ZC>zTMMif2v*We*!Z&>obg9KTp3$tA zN&qqru7T7W3N^b~#Rzac%QoqF+a1tU`V1pjMttcw)7#NwzZ`hGSPMg%2=N=@pAm7DRG=<&^| zay@hagS~h+C8Ab!TOpr6ra%-=Q@-=JJBm!iR}&H6`+b5*H!oSz5}2hLIf#LLB)*8h zD2o(74Vsm1cZDRz2;ditcfzaVdY@AX!tkNY-`JN|U`o5j)b<*Y=GsR9weD~ZhV>kG zv<^ZQVJdS0*X3FznvZ>+W*-L(!fLNIq))Ko4O7j(x0{R-0?&DnWUldd>wKoP6m-74 zL&F7vE{7ZeAYsO2YvbWwtX0@r1re`b5X6s!>O4i5?bES*SE~(g`l3mLi*X03#?hl( zxvEdxyyyW~S0L*ZKR06+j2+?pJN9AFS4gO$Y`3-7Ov9rb!?=XNh6 z*wUA2u0D=pCLD#wAmNf)|8iK&>-ux&qA#WvKI9g^f%3kWh4~act4fl11sT7KW6np= zEY>dfSNM;wImpgEOB=Q*&%Kr6XYjm#qe1z^9j=0CiQ*5m^yZGhW^2OVsn4r3GCT45 z&-Tbq`Do`ZnL)s1V3u()06cbIy^%~6kgTc*))M9GpLH{}H-J7mi+61SN}pkInIvjN~7ad_8up z6(wt@|1a`#D;VM0Y-@=8+^v!zsWd08PQ(=Y)Krxq3AZ+5AV8p;&U9Y zcCkvHr2xu(NqEkkLQ=6aPFgKkTe?g;ri911+!Pt6c=xca!>5EP zea*@eUJX(1hZ9ccTm(pWY_VhU+u|M~rnX^tzKY-EW(5y)Z`%#wa4w!1;y@_;no+Zo zvUiSu4cK?E&hPyWJNTgIGyFLCAEx-56Y;;$Hw`JV7%q~?fhXS+j$BV}P36740P;rs z>@V^rerzVSF~`_xt=M%iQc7*+cad zv#qE=Tg?8=1rAWAVb6U6Iy`Raw+YceGbX3Ww!M1>Nfrq}jt~R*y~+BN2p-WF+jW#5 zj*E{$s;s7--R`lDj3UG;mi)2e@wF1QH1S1WSl-jQW}1r-Rbo->78>g4;71lbJ+xXs zRrDht-<$^SR0ds^UO0i6!T0L7>CatX(D7PZ+lo+l&CZ%c0GMzA1Xx4gQ#od|Psaz_`p zA84LDQM)<05FM+se|A}6AZN6$V$}EXl8K$Lq+(k$zpb9w9-TmlKri5U-uLt;w#UIT za#-U;d}3nWsqSQ{whRbHXz*_C7_u!N-@1#A1rEO6*&|)U=;pwng2!V8QU?5rZeol2 z?(g{=pLZ{Z_knDEr|qI!*`dKYgU^R&B*(8+_Euf_{m${CS)#daIEiBW%rxrOHlsGo zpm*I`&qnb-g}dJds!Cv}U`u5>4YGgi zgF@!W(7r5@kW-`i?=`3qv)+*`Mu!Wn@Nge_6hta7MmZukI|2gpV`y@6UQwOD0eIXt z@DTdL&{JCtD0)6^^$P>oNZ0p881sR|-kXcV)s?3A<7E-Y!IadJsQ`RtpR2pU0zyW$ z`oBGKrj0c1!dG+!l4rtRr*Pl_1=aT{YSJ6WW{66jP7KtNaFI4Ut%}cJt-u3|A{f(Y z3}f0NIL+lvZ(mzR+BNyFW6S}2fpIOj^HIOEVk$2Qg{WUnBL=WeRJ?rFDe6SStQ5o0 zVgl&d$^~0|s3wMMi`8_x)rnbe1&zxV5eLj_M^I}5gHrle@4P1v;CJcFD#SQN8+z@! zGgr(arD0wFF!e29ZAH4F;bx_GNJw|%SEvifB>>tEoWXN4LFvvk;hTv_C8A?|w(Xf% zJ}Hp+cXY5QG?-csCv+bAV(D11)reLo4fM+%QA!|;s_Se5xdF=)W?#QfBAvHZZcweD zQ5h0aPS%uTUXTAn1iYSFk}1m7DfFM;PEZBE90V%c3w3q%J$A((*6!8ZrO^UMKY&Jw zJ@Zi^!?4w2E)ThIQ{4A>XW)p1`KseZ6VQ5_{F(z<-@I0})LlvV;i7RI%|Gu|^~?`f zCzWV&LE;mTHsG46%b)b!x~(l0~kpP`!KDF7aRRQlUr zvN%aEOu}h08)M`U*3wt*+d0O-UZJi4M@+x>>Cv%9c)hib*GQ08jSi9q2xs8{9z8w& zzo26L$=cuM`@QQ%M=h@I$~vZP)GE;bCXlKoST>9afMuiIliQDr%F7;?Rhw6OWzc-# z{!Y!ofnCS7;LNyb7+OPMmLPkmp5vwVqrw0cY)k2Jiefm`-Unhq#yJ-ClRSF{8puJf zRJ(OKA5g4y099}&Ae4)o>b-6nk{q6u^gzXP`4_8D7xfg5>Lf!_?bI8grfTXB)pynN z{;lM=sv%IwfeNF{h!-$F8 zC`~dIbmMk-@I&qDMejO;Oc!T{t8?=3hFIt+?Fm+*t{2Aife*(CtZyUbcX6+>N@x^(Xvp4UiPQJ)Wn~U1@qWRBN!Z zBdTKh%ZeuIk_ZSS3ZgT`AD$l@>?0->vsU*PL=XQOFGo$=H&nfg+vN|qA|13JbpCZ{ zz)r!7aKN=_%HfSxpyDQ0mD9uS+$;Ixwg#a$t}Z8>CU-2<>-MzDuz7c~B&>h2PmcLl z#WcmQ`pSSlw^0iQlPm5Qt0^Q2#b;_9wrXAmNdF~TyVM!;H)ZD5 zPXN|dqRtFt3jwPydH%Q@E1iR#)uX!uBX(dbpuPxe57?(;3}iux2!r#=c8GF#s{73r z)T!mr5Y=9FI~`djsH2mi*O&G#3$}2EuNp8B?mJ8k#&(oEHw_@qWrt?R>e?n4e1(sJ|q|0EdNudyA zA4(?1R$6~ASB?Hc&VUOEZg9Olb%w^%Hl;Ur*oTt5x%FcQ-tE`}{!q^Rf%a|}dTDfy zkPHX5A2wR3sphpsxs|rl2Yf=Fuu8nMeykBG(VybYthC zdlDhW-$8&&=}8{X200K!z4d9snMAefxkiv2^Lf_#hfE z&iyN?#^T9;Fz=aYk_f0KsOcAM_sj5v{GJn_-@PQMuN>tI9LA1UgSvha6R}*cA<+^b zH0^ZpR4N@nv2ub8g@9H zs^X{U!3PUyDxxZcFSEVN^3+7@voXw}=$rP5Qk5$63w)fK zpD`4kEU~QyAe9L}fu;2-{&aLFXvO@ODW?a$$KLXbWm~?{-Y>}KR?F2Q0E7*PfzWCu#4weI!t^j>W;yr8Q69#p{ zDUWhZH^Y}8gy)@4t%<|_(HVu=LsYnYM%336aPENC$$5Qh`G?UA({of3;3q6;{?KO* zyMqfY&x@r0$Ng5siGN`ZyDJa9)r5NJ)EuoRN`{u1hh9H3kk7vmF`JnDrIYP=%Trr` zl?%w7$O0pXy5Mt;46Jxyl~a?GlY2UzS9X^8`|Il}Ims(%(|zv)JzI{Et&x$jACP6m z-&|ep(8RFhGG!YBL2}+I3ZJo zIo^h46XxS1iHZ&pY;Q)+$?4A6f|yj(-OFOD3OkbNRyZ8)FnCfSQ2hVOQb4Y_|W6PXpK+ zQFq%79xMLf8*Cm*prj{e=2ZE|ha{$rtqSaCW)o9cw7|Q=ltQ^gf3T>5C{4pP+{OZz zvk1{vPy8^;F41kIkhL~%ZBXr%z`XgzW{U8DRim=q@(IHEeo#j)T@Fyaq+u+-1!z-A z@QZLIvN`T&B$8mInk%XOXtlxvTAyi^9PQvj3i4|bC~P%rG4sIs7Z}*9%dF^w)BIxr z_*m7zhO4Rr3r6Ev2HvYCwjh5#zvv7rMg#J`Z_1iNa^V8sYTuG>Di*pq=9G_2@feu% z!~wFQ2`2y^LE_B%Yhn&Cb5GY>8p}^#T%B0Xo=N)AfgHh~U`D)_&g*S_L+;OQ&Zq++SS;KA5dNvu8T(lb` zEPlj+7;ZK9lNoEQ+j47H_a~g!Q|)R;)M8^x_NhpT|Crn@oThNaANmv_s6@>BV&;>R z{KxuN%O1okl7dRf4oaQL;o^eWes8JMe;&)(%E(uJn_dnZR*1D@)GT5@$Y_q5uvGa5 zmfGcg#A?yCQ=e{g5I#%;&3HlDS0B57H{+R#P^6`7CNIA@NW(Py5*hY7OEc&PYzRTl`_dq%3M#CX2lp)I!Dz2S>VhX&t0 zuV`E#ul1jH%*JmEu4mj=8X!7zz9j5m8m+`-H`@ zdL7Sbr=#|RyRh1w`_ee2dz|mnZj!7A#FM4%y*)R!$~xZ4wTvHC3pC|OMf~MAoOj|s zvDx+6{2a-|^dY;UkCD<6l=K-cF{<%N-A>%?v>e5#ZK=p7up3Bc;wv1b*%}Otzr&p* zITR+(l@WAi6nQJ26l)~D@G**V<+ZJKA1k>OOLhy%d3J__NVHp3XVB4OLmgQnJ8Hi1 zfp)EAfdGWgxZoO^O~VC&hN~uPcnJL{1G$EY$ZNdmw{vxtOtE{<--6Wt&W=U$Az~hh z3uO`ZPHX;Yb!rpwb}RiA?($j5b~!Z-xmoXrueXSn7@1O+@m{KMBNOVieV}3 z3$L@lldUWZ8E>GsZ)BWF6pkV9`D%aW;qe4M1n&5&BATLVoAP51U6H$A3>Px))ubY% zS<{l3+W0iHi&F1ZXN42`;_-OZu3KEOw`OTAwk)E~%jRCG8l#emUIkRjjc=QeiVEU< zqR$F~g@tfq$zfo_OTws$;bFl`1|>dGt=CH=y4#s>p^c#A zha&_j!L3BQH_bYO-nbm?LW#9Fzm%`UP}{fk1#~qnH0MvBr)2e@1+lV{{GCkPL-zpu zgwwH$@T~>geGaBlni5=JU4=n-=$TD!(iMH0@JX1VSxzAR`(6~QW`?BR)i+};1z2(u z>*GTHL@Icr(lG8Lm_MfXQPsBReCff)s}iN@Ww*WhPCEHB$TJlO|Cip!D!bD}Rb(9R zZ=NC6mz=XyMr^+SLH1#szlo>RmFznZ>~sb!p^%Dt^Y%EkBJghX$J12xZt}5M@bc@; z-{|{v(B1J~&wLez8-6*gTjycDCQrXh9CPfvq3Hx?l_nzqUA}Q?|3RoQ2GU~1`?b(J zh?IZgYr*=g@yO^v7VWgWIs#pbB^n3GTbv#R%FWkkdyD%{HwX4*rnmww!_sM8 z38ECPk*x!w_rZF&mO%^8e-5A+5+`rFRFhetZmF@RwK~eT;|-<@@>R8JoRtX5kNg^M zMg7`$nI)gk*x_gBL~&VAKOu+Mg# z=WyBg(PI{Q1zG#UYri7Za@gJa;v|Q*Zy%)D7V|y@RX2dMRecHj{q)~Q>x-sX!cfi^ zQsZmx(G#FynCg321GOb~j>V}XTx zK9HxMWNeng@5fqr#9~mu4NFi4_Karoen(6u?wnov@M65>29slO82#cv^zCAJP*JYI zCW4uRT}&<-9ENu?xMmd`1|MK&3JJr8v|LT-`EX>T#+8jG~{jP z{3bgLR?sP5-JkaywVguBU8JM!-8bVy`}FR5ZT4hqrtTLd!YPONJA9Fu+Sc{}So)3Q z^czg4^IKZH{>->^B@&(C7YiG<+m1Hvzbga*b-k?rK!^3Bsemj|{Nd~WUJ6#aXxz^GB8|G8K~B^0K?hf9fKl^%E%nzFpAa>CJ^1?BsF(1Y51w>`qy?dG`l*yb(`1e!4j+ z=-9uWk+k+Q5-!N{nUud2VGg!^zWE)3sG|~+EhqFUR2{~DeHLbgf0%$KEYSw0`(%r$FM5*C~f zJ0v`K-S=k@a2LqNsuhf5Y0XsFEf84OFP~KI{7gBSA^(chf;d}E<6BbCWObjITB$qM z8NSd=ZXrQ7D~DI-ivBL+J=u)_+*{46!jaXAEw<;V5os!gxgJ^OTdiny%2IYR?>>p} zPdX{3Ga@av635IFuOBBA>T+7*ykkk7c8Y3c-AzM!uNYZaX*({>to(O!d(ykSSIq@i^s@ijB`- zS&94{o=>#AII96s+*Aj@;f34I>&M?iz{HWFAwOAF%yF1A8R?YzTvSE$3!ejG7&EZ&%RXDzW zKjyo%e`yW9*WK}CtujR#ERmi|U-vM2tMY8M3xd`5MHf0xsO#w&%`dWc4fmsRy^rYH& zq7kFl4nK6!b@^)>DsWl{kj-sp`$3Fxvy&s#2%;%ol|Hefo>8w9yYEiyfNQ7UU=yf9 z;w6g|M)>~1kA2t|;en6mEoGLN{6AU%BMIpkslA<(TP}gbmn}Xq_RSL5RYFMSZmFe8 zrqjiK3a5NL-6p>{7W#4?8SjZ;1=%-a{`Ml9uN7OS!njTMpU2-*rJj*w2)ABnjG8|3 zeC~i@D3f3UK4Rw1p)x%tJ+PwX%|zs6UBiqvK1w9{myHNXW(Cim=5`h+ zve@tl^no*=p!y^^Yf+py!F9OT*gPvt!?U8Yr32soT+HxmehyNgG{jTx~4Q@uB)_d{gB{cWj!qJmTNMA`q@N@yFnF;7mN+} zwI-XCmO+gbf?%Cv1XuxfWZLMmA^tOdeVc10!`4o_;u`lesmP^}OLkfEVc$uP{znj0 z^Yv^XEh~@?B1J^0i2MTD%fXBmEF5-} z@0qEK6}-9nUBx+)A@VLZcGy!(?oYj4cIV`5pwE(qQ36>Zl@U#X{#K}kH401DX9qzU zi)UkwMe8~sg22-u+Lbt>sYwt`A+dw*Egf7Tz0vYXn{i-o{;4m@jAZc|^ZtSWf|7|w z7;jrn?Msd1IHyfl9}|^>VDI+hdQR#9SJ8{zxvj(Q-4HfD2q`XsAsW)=Zu@ zwE!h9JviN6mOPO2GMV;Htr;N8D|`vzHDzv&?_b5k#Rq0f7Oa3fd?D*WMYI(`{}S~l zNN57F#L?Nj>-^~Rk2E9*N!;Fkqcq5`j38A?#2Nn4i2g%2O6u+sdU6k zA*rE)Gpc4n>U4g0a?r@P#+O_2-lVc?!eE z5N^q;94YpmhXmA*kLEW@r-8xl22ZrmmX3)pNJ-Dz-P~cP40H>p+J?Q~OQ5H_go)_{ z=bwpW`~{3VMCwb27=&sUJcsAhG<9&bnqC`z> z@#JxO1|IK@W?8hrgs@txAyGMl+VIu3n;l(!M`@((VwOXp`(BsZRa2D_ zG>-|LZ(7*D2eO1Rf`R8rrON*Kcvj~vcpE{IIR5e{mCxqy@|Ou=ZSQ3 z=f~dJ@fhEt*Dx%?L?h(4xzp;IaXT)&H=S4-m2L1=kvX#w^@D+w zrweqm7Uk)y3rdXppPc(;_E?YRi}doN$&{8`968l?tlYO8t!2V78`NO)e%dTr{ERxC zL`^UCN&}@ce0!bVpa8FMA=k1eZjjCNzjzNd1>$0uwkQvN z^ML+h#d`uWs<5dTs$83?`^#Hl%A}*(M7d`o*Hs9dXY}69+@sw|TR26sk)DQ!I|6Wr zVa82oWw7F3-cTN>3o|A%y(_2ddOr>s#nV)uk=*gehga-w9i@jdb09K1@YloC@9x#I zv>f{LQ}6N+DkVHw7I^i!#GBPHiiXgH^mMYWX%M@gH|1nK71v(CouDnKECYpu@?Oy| zo72m~dmU^$xUrK4Ma)@L)2ecvKn3l>Jcmusb z-q_M%NBwj3hyWS@k%E)yynu5y3aKTjpH7ZNXsN8x9vFAW9D>1AMd!Du+}k3)ww6~J2>vAa9srEWuVV*@L`O$#l=F) zHCyB+=yPsmoDRQc)ym;VyU}wdPF|Mad-ZvmJEMXV%}SBlksag@B&)}%hS-L zA{b-5$!iLI*h$?8g|I_V?*fk&I|zSmgxz40)7WhhBj`{Gou5=OOnPOFBy`d-O8TF+ zBP8q3tgozEB@?=L^k-X)@>K__dHN~0y%ILj3~d~yeg8Qd3~vH&mH&=zFGDjww-=zb zN#bN7pcMJ~k7l8M3_Ja`_*j`&LS5LxsGk+cDb@_aE;moYQX%c%JP2Jj1|zt()-PXz z<>aMk6c>CdhJvy@@LxidT6`~*Ype2U)F_!4um}hcZ{H9QynFa2Kk=b49Cld>CP-;n z%7aMrPkRGK%YI^%qIqWOQCE|BdCj89w;G@0nYKoLJyXs1HxR!0o^&+j$s`yo_^Qx@{FU_v&`&)jkJU6AwiR)o}!p&euO`z_WJG^b~(AB5m zd^qo{Mz2-Nu&I2}`O%gShcBxLAvpKU#N$_yjiyfE3MNlUi^?J42fnRD%oP`rRg&+2W39}q+;Q1^ar*zU_Euq4wq3ihAP7=|fOLtpG)x*q zN@607bcuAQq@aM(N(qzh4(Uda?rxBh29fS{P4w}7pKq;o{A=TP%PkM*ebqR}8G~e_ zX;o?8&f)tRDwxeJ_6@L*gJy+XG)YebmW$WFUl*dEC7QD;Fk>JFgT71Kyniq+x)sj~ z$08{`tq+vQ$@meA6`sQJMKV;+KA%2Z2Y=wGAu}%zeNH6?Uc~FsE4V)~@PXRvyhqGQ z2G6kywqgyuhP=V=U-A$)AVH`HmM?Icutf*S+uNTM0Yl~WIWldCizI-dTX%9*N(3Ji zY2Ry{3=(y6*WU6^ffwn#9Ym@imr%jL+;}E6(Y5^^=#sYE*rF2^=7PkVHORZl| zCjygLwFA}f!ic%EyZy>?w$U|0C(+dm^-LdilsFxAutbiUh4$vHGA5veIM6Q=3bbT% z=j)Ly=~z8k_n`M96s15kj#(=5z5`2~73?g`0YPeeud&7+B&)by?W^f){X`rwO)ol9 zr{uGoBIcst_FnH;{WvVWSK35duGEE~m-D6qX0OL57nej^%+N~{jQ}rH`tPk{`(jX` zy>vq^t1ntVVtprabP=__%8ZMRJoFSnIxXfwu1wOTBG|^0cB969e=AIYgRD#6Kk1(f zH_pzU{^X;yGgJNZK=Lu;xD}=i56W^kEM~YZeDi~T|90&$5rjcAai*HR&+O60#zxa% zFG2e~tA&O#Gx#SRU7ysUxb)}u8bk*CCLj5JbpB|SyFCXEURs$4Qh&C$%=vM7@%oHk z_X~a(G~)6zmC_u~O+EIO@et8_8H2+}keoOv`wj{D%*lOq{ll69L2?8pdk9ScblGyl zhA+-SP!V=AZR#wpX#OpI;8~O{=pZ-bFE?>1J(-49bD=H4YVjuydhg4i5Iuo^5F$!( zfJQogqM5qu;Z8&@#Hb)%gn~QzEOfDZKtl$62@P{TV~)RH;*9a;OFSQGa3XxU61eUD z6ix~7PGd<7AJtdW4t~DH zadYH>by~qd@5ra&MMY-hTpheJy8tD{ySLUWtq_#a1@IV@P%Q}hmq$Fd-9G1OqZ;>R z-VR8$M6a7u&}OOFbE3Ul8Kdj_x4I9C@5BYWeQ{lAVG*Z+6%SQ$2rR^5jFW$(1aP$GO^;i1 zDbra55vHW2xW4O7pS*KQRc<76_V_2aXQjnxyxzBG8-?;YNwoxNgJqtqV7LbWd60>UWv*7k5GYRKE(S9bYZll6r@(YtTw{>}G2RDi+xw!W$$cunW?myn#F(vz)+6%5jKn%fNsXV9faf zV7N9_f@wWp9dK!&SWIl_@6U|Mhph{KiofQfG^;&XPT;TO;cuY4afZ$$jvjE$qEgAKf1JCc*}_Lj)KNP6Ai*-l~Q+a<^PNL-+9pSAz74=_$CEOD|Rzk(p1Iq#D<>BXHE@j_V$I|APjM!n8(e1_{4YE+~j zJ$lq+Tt{JO*qMsu~frenxPMm}9x+Hk+O5CG;+6#VWOp2$dyx(efbRmKF_{A;IrZF(VHwfgwgu((UKk-7QHBak5$BY`sd_qW}q`*&k%_lGUaek_>%RpaXnIE6ispo9exw zJt@56vco$@yuN!<-q~N}aE$=kkMBT2U5T=s#sxuL;xrx>!jDfexiRK40rr~EXP1oNQ_73ca1a|0IqZ>cQER=b#y_G5ZMapBZ zd$SV)Is+|^ zyuhpn+-MerKNaJ<7Dc=lIGUXc4Sq@t$f(A1(p7VYr)#DGiC*&zkuE@+KC3Tk@kFlA zTScZW0!ia$O6v-LOJiYpX)JS(#xYk_a^U_o zUO)}0_gm!}Pua8@1uHEGv;=*8&+9#}{YB7j_SMIT-f+Br4T3M|r9TQzqQjT9!B#mz zgEMsJfmA~)c%bw9uoUA{8~o;?oG3HdS5g_V>iifk`(wTLg-XtRbV@sgoqCl&HFs{p z+LCqu@i{dLB-I02|1Hitz`5{iPj$E5>dx)*Vg|j2I)H*AXBGam;N?}Q7%b2Fy|3Q- zBLAWr3wo4ne>`_vE~zxqU>J;$mOFBMwI*gw?<)+dbzT-31i6s!!RPN{-wQv;Q!xV! zfP($u6jUy;`b`*3WgomgPon9dS~eB>tiua%&-dNNYXemA)o~y_R>LBfX;(mjX>M{G zm^>)2V1^k?y<^{sPmQdu@3FEy3Jba*Td#9nx#Mr(=SAO9916tMg>1VPNYtetlfKg0 ziyT5WdOQ`VlN|+E&@yr%ek+v9^7Z-BH9~s#=$s`KWsEgrh7|<{I$hb|Ib>1jnI%Ey zJB!?c{$a4&y2}K&1t#h6|Sl!im%_nJ&SGO7ORaW3-Nwzts}0+LPH=inNJw?^r+)uOWv3FZnkP zkpKHa|4N(d^P*NG=9@Le@4CI`Cs{j7DgeU!F3WhDl^&3mOjYn-<&++LI@Z$yA{=?0 zAo9$XsSeqN;X$)(WmcoX2)>t}?^eA&pEK#BMSK8SUul{0`2L!J1#4f7+MHZ?TD*P; ztHjVc;E!AEg;kzZdszV|di1P%pyaJi(9XAkx7kE&@O zh2J(x7GT(I_IX}~I@0nGWehpERQP*o30=jLih#)j%Vn>n6QGfW1HF^PpzHlSxIiJr z*K}qK)E=8@>#Ue;J!8-n8j1Y|S3{AvBAO`XDq+L!GPe*3ioPB>q4OmIEzF4kiUs;e zwwj+o#Fvx15G!=uTXED$X%FQCXRVhh57>A7m1qKu#xC$NDo}$n5B`6@knOjozmVda zm+Oaz1I2=1Jx-8}lco=8I{}MM>((jL>kdF8H(BJ9-3f6tHo;9uv&Ht?#WF;71U`!p z{Rl&>*Y>MzyjdT$9di2h&->wRc+^`V_D9X_VHE5({yf(6^+~9(9{&)3zgTvGv^Li> zpABY3HxWNsS>*&&h+=3Gv^a$b!GwXjw|5JZgnAgT z`gN+l%}Z?Sw3}T$y9Xo)AMk<_>xf{uzX&*T_5VntE$`6SqkJ@zZ`!|=^?=)Tb~!3SqylLT&ySyv8jS)f1%rG z*F?P;gC3Jgi_Bo8XW=?`@(!=nuEmDFa$$V+&()}`7iH#DZSsULUXL(&A^ovDkvqX# zMI7lB%u|b9z&_VG!=;2)^dL}Bnm(K7T z_y|Ap!?^p0G6sHwxVJ&3J2 zhE{b~W?56EA%+`uRg8g&<-`{OZvQA@aUXH`72KUY1e(>^Ow@K}X>Vxz?|pQC zYhWPcKPwV=P!`$TJCTfg8`F~-z0UJIG^IHsZ=Bt%&BLF6c=fS?6#8tMi6|T8h-L*|R-aH| z9U7y#vLendILmJPM`ZEdu%5!wZgm^mnua!!@uk(rzBUqQ*G*=acNKs-^#+IGy#_eU zp@2a~X#A@!woKIH(9gx#K=|i#vRO&!_6OBH3V?Q*Lk4T4$c4TFn^{HGXHN{zsWMBn zf7l9ci5s@!6Sv|6Z~F-qkl>hMSNM510K_kx#wDBdQiJS;s(OJfDb4f~KE4&DTA+&n zD0x=Mg`i*W0yE9Wzlzj5R%{Fpg3PKJpn-k~hQi&AD$Y^)pyYZsJ}gcjKUMS0JGE(? zp0aq|LM6gM+=mr(D<7%*-4LZWSGmUxd+KR3A?}yA9-^Nhd3MoeWnR&P0kdE3NICHS zwcfjSGHj4NR$Sj^ugFiLdS;FWTPt{J!y^!4&TUE>PfCw=Yrt8VB`pwiBmPu%ae^ZG zn!K3qV${`M_pXpFW9sVX5Q6wad+F`TM;(I@Im=5b~#8b_~2<;N|;&PBD*u0? zc&IK5nZw-d!ssvkqXjMF9z~#Z-9*HSN`W=J1q`fu90Aha3kajpU-|-e7~)CZ>^L1v(~+) z1b3HYTSyeW8sdHyYtxn3dGdHVauVm53C2@uv5#OP7SN2{>-9DZ1%vFruYE|%)-K`5 z*OBrHQLzuDPgVm>8FQLXx5W`c0EkTgC}$u3pRJmn4!_;<2%znWZ*kT}({ShNJkiff zaB*HQ^Agx6F0M4&)colAcw4dE&|q^h1Vp>qhF(zppsh<0cS7}_z6Lg+onJqme0OAx zWKq3;_wHR=qTPVc6Pz*x0TAkkM@UQUXe+LqnNssO+5$cho?pv-EfN`K`!Xepq7n(` zhmh~kh@WeO!TX7AFzGI0D_sUyQZAGKoNp!fGx4Cspt8J zfKD#f*I;YRnEl`QkT5qVbKkCqAhY=HsmO8jN2TtN<8!YGul}0kyG}#YI+=c!MocvN82~!=}WHf3%a^eBzh&Dc1i zHol~VM=g5}Ok!R^&c3zOAnCK)HXwPRr^%R?^iZHra(5ANK9byjsCoq`dVyqXna3%n zVD24I+I{fL-Q?O#eSpd^qY6xi;+7|Bg*4bM>x^3kcT#=}zrGE0yT=P1gxs;yB;gNG zn#cA~97DaLhb1w-&aq*nwVLQhqqsiTyCAP2GOEwq^N9LNE5o#8C_)OIBHp))q^0G$ zK+Sra;``laxQphLg_;vwmAnqMOdW+V&Dr##8yU{TDA$Ny7a7Oh-X=dH+=L zs5ZfnNo65IEdJnx_sxD@Pfm99gAac#@l>_|RA-C-#Ylu=xbXfM$m=-@EfLQfTpRUy5!=}jZCAVl2a3Q z`ZCgJT^Cv&2gWo7u7@HLlsb>11VQbp;$9ZmgX#IBG+!YX>#a=9y3SzkF$2Rc;JL|c7F z+-F1)?0}6m`ue|8uSq2YC?p8WQmeDIW_?@Je&yozB@&PYcl(v1Kj=t$QS@d5Ng*)0 zsnvp)JFtJ`iRENh=N}#yzWoRFU8mlJm*~5Q3*WKmy37A3IfL|HZraDl)ZG4QJZ(==wqqQ zK~rGy|5UjiGe3P=Qcg5JN`}QlshFOgXq(q?JK}oJ)tEDl+04GdoF3bE=}Xi8IUE*+ z4Dn2oW!4I21V8CCxyy1xTup9d?I8{@H%Vsc{5D6dBPc5Ag0;52SUpCzz#>n!& z7^CXBrYysWUf1Dw@rpoP{B=RcViKBWsv^|{upUT6{)!ea8X;}9Q?@1cxjat>0<@q1 z7fHmxh%Mjyb;>s=^}Jup$LcG(LfXfMDOo{2OBqdEpLqGeBxFcVloHm7%uU~<%V6jN z+|On#B^cpY@V?2j0PL5jij>2k^XduJnov1yPqHD8->9kMO5bF7g||oJ zLc~Ow#M71EJ*9jhrZ3aR2b%YzP;zAVE%tmw09V7riX39Ty zaKylcOXF_RWq((|UkS7aaC{Q$sk#*uD`{?L%v3uptcQRRvD3tJ)>s{2G((mx^*HX= z#A%mZPD`aS!D zOBpO!$E3K8v~mcYIj%QJZz#P?$mhE73XW|c6LnMVv@^?q(`#nR#jewW^kVk)@s8a$~ZWP<~8aTYY`Iw(I&W!5`)V{#Fzt+sQ(c;zGOijv3h_L{9&pR>utVviRW|rv!e|xlj#)GsRo|f*Yfd# z0enGfrLwfHlaJ-WFy(nF-al$CWQ>dkPRJTkglNV4xk_>bbalA1W~(h_gl*X^l~}e* zQ|ShKe0%4YZ1fyGd_P<9Ek7G4`3p0ocL(gg;9%>=gug6_1UkK zKR)!st~Mdtyjot@1Lh5=1%$x?qS(t&Bgs#QW%z{QMz#TvsBD3qaxH}qG^Zf@;8+Mw zD2Gq6(|A4@$lU$SJr(t9k50v37qoxUdJVKkFDSmqZWhwdZUf2Io^nQ@U;uD;jMRjc z2^(Dgnw+Q*P+7U4U$J3r>6<7vcFFZu&NnrP51jehpKu_TmY*X-mo0sfL+tpa4>ZI) zF)bNiBvTrSJzpHDR=&YT2rg1C{_-l+TWfpNgaQVSb?d$SN}P=hEX)EvaMJzcoT=o6 zftgpn#-%YS&b?Drt}74w^aR81w+6P%%?dNqL^YI_z}stki`^s2s-W)8Va#&;D{6ho z3SV!e0e% z5T($$W$!qMK-)V9DC7wT+Ohv%n5J8pjW#r_nztq+ITZy$!hU&-Gp@ zFDuM)Z%!p~504{D@jA)32xZP-_^DJ980bNRM{)*_gY42Vy&=gM{&GhU%3`?2HDrSF zTGBGEiCCs!Yx@<-5<(hRB4RydnswhYVHRHRB@}ZoJ)uM?q}&gRWVA-aEffcyE~jD! zA;Ym(!ReZz4z^-nFOb>1He9W0!i^*lLI8G7FHx~ircYJ^>t*lrx5`LuQfCUEgGuO- zWyjNlBRi>k(+$nl2e;xz*E8)YIBV*o`{TuZwz~lj!xmQWlq;6mQt`UWNsJ8QZsh}I zoM=CJlI}AwVfh|!_4BqMZ(ZM8VDvSL3?6IS&da16AGks{%(=Zen0Dmd=Gdq#ft7r*4f8mNCdTuxnlfhNwpw%tF{@j6`v z1Li!g2m=<@#;4!R(k~3M6Rrw{=-p8o%Whjqoov{u%ZxrS0cI?1+)weU|KY^~{_nil zB%BxXOM=IOeNG_Jt#kc=8<rj~|G<2oJ~*T4lvLR}FX!DL2-}p1_ARiaaI;%CqkW z-4aaPGIqr2{Xo`kOUnK35M#0g)Ou9}C(oOTpk8hNWmq{>!@s`lmRb;TAtKF3NmE;r zr`N0CLd9IJzgcXBb$aC}KdsAOLQ*MaNoTFr#)nXB-*d3LUJOm0Og|d%ikkfEnX!#(T{kb*yai_VM6Aa4`7n^{J*L;Nj3mhf)qnz|G+B4z>wrQU*oSb=W56>)Pd>{ z@(=z67(Z8s8`(yuqf+ko+8j2oSJ`c{6yf`P{ohEn5H>SOVnV0!b|68Wm`pb(Pd|Sl z#Z<<_wkqreoEm@mvott=7WqHqpEX8&7XabC$L3mG{)`jVGZS6nv8y(tGhvRJ8!11lrt{ z?!yO;%OVB1a;Avzp^iMxL?jDGH>FuVd}krjxImRzQcDt6bj&oEwxhf|SKuSHveSM8KZ- zJLjMP9}O7-kqpsvVf!uMm!&|dELbKE7}?kuYsysh!N~5IRDqjUYCa(;?992pS$Bx0 zMNDXA;wi3OIo(#yo=PT5yf_Ws)H>o=d)FXFdfz}fl=Rw1k;n5YSQ8Aqa=on^TlyhX z8V%OLJu;om=@#pa$cSWU-7b-$GMf2WU>04yaQ2x8glaV$sOKEHi82ouf3tDY!R1!n zuRcQzFvd3@&C>gqdTTE?n0Y?C?aK`(;^Oscu)#)Ws0R$FH}$>zApfkg~D%K zxn!aEQ7Nn`4uHx5i!)Am)!GO>XkT}*`!F9-3p{YDmyG7_dfjrx3?bJ@(#NSy1n@f| z=qcVaGWaeC4IK*ly9=0ab^)`*M`<8Ced4bIUr`LcySM)J^gOv+?PAWe`DtSN4;Zqh zwnr(LEly~p9`C4GDJ6mwXtITfhNb%D#|9+0x7co2#%oT9mp@YPft|H}ULK%Y9Z7`B z;?%vSv!3^S^P!P16gU_q>zG|I0iCVGRxGG0#cFIT-!q+kLzzLR%8;Jsc}eZOgp3^ApSqI zaJfGQ0eFbJ8oJeDIjdrxZd;6ln(mY$=_FX6g+yt)M{KEA8NQ^LAM&;w*<2;Bxma4` z0;wBNP`%xtk=e8I5yLgy_8JoeaUgf3!WkQ%$i71|vwBo*Z|?a`Mv zoaxZXxD-~8Kb)WO4`NZ4$Az!ehy0B8n#iIGPgxX_v zAYO|q{tzz*!o*tXO<0|&aKMo0<12N*FGFGpog`TI6$MRl4aD~b>mtk3i$8qF|N7ZW zjI5D2elf6?Gz=)T&FkJFg-7=#G=G0j%xC}Vq{a@DP9{ytnigo(t_sCSgyeoXKHbNn zt@1iz%aRmyS-9^_Q0_tomrZyAVWwSNF;+)2zcbKpFTswN{kSrxAGXY*(^iTmAiyk+BI%u5wChyF|WX- zRm|ykHc@VOcVpd2Y$XtXq&XA7+NEEeZwVK^e?5%pkXTyUX_BY&g(A7Kkk5w!{)5kN z4xXOcOl!}Y!23EhMFmX9!Kt%+P_ZL;tG~0f+!>;XnekbS3P8(^a;>fJ{7yT*ZQL+; z?C)>N>1!W}uf!|bJGNvZ_<-{8n>J-~6IJAfmpWw1C!`F0L4*>d8_LuH|m@n&cIP=w;37D@I0Gx>0@EI;{XNf&}BEesz zBN$q<=?bV0W{G6W3)%;Ha1Y@~aN5!QXXs0Rq-T&Jv z1;SILKsDxg|N4}V+5rLPv_L1gF!5nHx$&615VAIzMtybryJ-(Y@ZNzDs!CQg7UG4V zLY*sn-Ru23)*;n)TM8GtpZ=zhPNBm}}4UBFI*;K*d@;Eqoz6R_|EBl$La@GSzLhCewG-tra#uYVwBB<0oUf*20ao%~T0NeY{V_X=m#w12?Vz(p;?WSpUQ zqcaCr0woDOTmby2%99EWxRO^QdDcf8@F9xA-ZGP7Fcwze|Ijta+T<7maU zP3FyyF-lx9&PzKKJoG*N)i5oV%)FSH2kESb-Psm$B(w7UM5C=_tx|qX$DJ0NMkb5S z_LSai09CUErC_gzVBH7NT=ix}43=L&97K`mb#?b3@ZQE>F5R~okv<1fZlHlW`#5wY z2ex}&(Lo{*R^4cz+y))}35aq&zFqa0F@CIbSj|LB-Fi}QL^UBE-q|<0>K^cErG5OU z0Z_8tdiOcL+Q0?0Jn!kU0uiOb2Y3|o_MbP25)ClGa4D^^+`mH)?9RgfWhe4)SFf{! z{ZSpx>&st_nf-dw>B;qN=H0w~rr}u2ws%X2mdok((1+nw!*>#T;MWuT1gROE#bv>V{cBS0QDaplkd~-h9;*Pc6*WEXmsd#MDV{9Dl}je&eyg0^{!iu1Ky1f z6SF)WxhkjOmQ@4Jn{1st{`R_;qj!P{X9z~~uHG?Rp_c&4SJ)=F#r9y+s>uc;K&o9o z{+P?F)NQGY?|rRD$b2@f=Q?!rA0lqy4-uCIhTK$>vFKFaG1^xIlf}3ZGef27`ME{Q z%XqA&Tb8*0xA=sNait-i!S!TildCro=P&(VA3*j&M`p0Nfkh_faVY01>mKcBm*22( zP+FcBNny;#8GIE`AjS)QL1*SaT=2pRxizty0xL0X<@bVtsdJ`N_*8zm^%c+D^X9TtEwt72tjTrku0ku#PBBy0d#O%?Y*l?zgk*=A%kt>;#Bj2E&_% zGaj!z?!Y1s70Z8xy(o31oon(STDDegQIEfZIB(`++}-w$wZ zK4}aY+#f}zuJa@Q0sO$Bt7bg^d*EO<2kvE+J3BFS`gqX|1pr#3$qgumF=~GPzj7A3 z{8IjHbBbh?HnRkjov-z9pSIDPp=7|>h0Q}~C&Y`JT8+?h)eGLuw>+(S=Fm|0+V)U| z&;}1DGLGfZuW$!OFBBYfY0G71(bKMI zm~$y?~^REW$T`n<~So{Q3Pxy0uD5RKprVWIXd`&f6_IM+Yssl517VE>0Vdi&bM zeu9B=k1^wWR>P9Gf|OVAm^9xRsDcELs^>C1V*9ehD6P+aDj?9~-&Tr~%v~AGf7?mG ze({3?tz29dHuaAdz%kb_IVz}aiGFBJ;+i}N5I!kZ#|YX#VH+YKnF-A#NbQwF zL#c<>Ks>|=agI{;LredA??hvcUewwNJa~-W48oTdCqD7RR1Vo4J_+myxqf~TM(whr zjUi(th0zSedevA+qv7G1)$lkbvpI(|a)x3C&%@|JKs18a69gOKl_x31jn;(geCD>1 z2*d>~hK_!sBO|&@Eg5~Mu1%G^;AEOB26AVR~eldrbWBkUu+U@65iyeD-jkpsB z%()gWg};l3btWkjID9rPI*gvoOaN8Hki6Eq#y=gGj$b!UE(Bmik7xet%c}U}%VJc2 z95yGJFxWlg&z+Xq_czgD5+piwzdrWNykpqicjg&ZJWBO*Eia2@MLty(Qq~iq1Gij^Se8KcGRC%^~K?J6*9%bZ_a*vr?U#+{)<2EuNvhW@#rEZ%o1RVBrP; z)%hS_w-FPk_N{_sR`pP%N1%iT$nv;)U)vo1ju;>D*sfA4NZykOQR3Q*L-F2FxY8sv zk?*>cH}dl7$J*{>ivYY$N)4=ymYqk82LUz;1`$InxyLTeul;hsE7~pmx&)rYuQhv=Z7s9OAn%mir7!|ChWBO z%|-B6f4QKDw~0>%l*~M@c3c7ra6F|)g$^silLLm>Nr`0eIwJoVd>CRheC6rjpetg4 zLoQk!?j8XVJjwq&b>Yr%H9-0ssIg4cH#pDNn`){eI0bmV{~7s!4Gdv<`O3q|g)INr z$)0Yt%jqXa*1d{YG_imD#}*c*47Y_{$(c<8%&1vwP+@(uu%UGJl?uuS_#V&E>LW3qvYFN8 zF?*RA9kfy{Tc&dPye()q6%0j$s6N)a!#|qG_C%?yeUJU5JdHt5EWI=%LBKnzjE(PW zl^3m0v0XQLk6z7DsbhF25UmO;0fh4c@Q}Ym!!;$~j20ZmOr{rtGpeNie4Y6m?z25FtnbnO=d_-@Lgt!$ ztkgtHymgYoyoDw`M_&N#-#J_38QIG-?1~WJY2ynK*U=$6AhImNgW!Cp2zOAn<6xP4V|mdQBzeJG8|*nkf$ zAxG0Y3+7(kVnp?#*|UcsiL}Kz!1=3v-r1Z_aO5ZPYl^Wci+^_I{8|~_CJN3?`0ENX z{dJLS=B*b|vAr-le>xX;fJ_K&S0F$t*}R*4T7}uPuJf>h(5E8Xf7b+1?$uU{4h|d0L2}ozMoow1snjY7 zZ2>S<@nA${W}#WiD8J6wcT|E06+y*Li6_Jl(UXMT3n9q)xrA%G!lNWxHs&4WBirCfd?k${9M+I<(j*@ zEO`1mxuQAQ$9#hRE!4a51O*;kvAO&wxZ;-K@8F6(6M1~7J}$z0;GWYyUk4$5sB?9= z6)h;KKz z=>qJoEwV0hOCXjWO8)h+=571SvLOq=;ma=QpWyITLz@AWR_r<3{EgSEP!HyFpKtIJ zPp+}JQ-psUELCPD(DmrTW^0DT|E`w<(TKvZBWdOJ?x(a!?@cl1J=aD)El?rN#M^(Q zB*`$6!-|Rgnz?KTl(rqC70#VsLKNsx_s~(`NL}$W zh?R&>9km<5b}shcn&@xO2@KP9ja?AHy1v|PoTzf*K^5oT93aV%iEjFBC|l(ZRxwfB z(~kU&APIm~Gd?;>w+=*yakR_mo2%NQzCvPAK6`yukQ*F1_h%c`h7XO{nL!zXuc@^LVP{cNzpDA9a4%?l3Vn#PT|1Ps#63U7%f|B2y`OFF=p z${gp_!-#X zT8neOsN5EjKlI>BXZ~q7pD`1kd#5OrEkGA*veb+rx@fkC6_;LLdGMix?Z1Ky3<#L2 zZ97kAY9y4m_^_}1+{(>WR$@%}4@oiVUxj?P6u_uQnfhthwOC3afJ5+ntDT;X)nCJr z)Q4_1GeI%`8P2<4M{Tdmse_B$A?6E!Ec#PgBD zSp-(;#!$E!9O(Ds#(jDio#3qxetsEN&zbyi6~7ag8JR+FlugC3SO0= zT`Gj{=8SZRTF#B5O1`2lvH!{iNXmw^q+ZnmY(%Keue@LbxS zZa4|EGFb9gSsp(VS<>G=59bt zGk7HmGcl%l-245h&dBo~8NGS{-*VAWpLjXp<~EKqG-;3jY&kW!w#?>k(grG=R4WPk zhg4e^R_)8+$x5&cpn@kFItXK>#n%tq#7wy4$_Y!;@sBc6n||;PoYf6&^zotAj>L-9 z#ij?J)5U^3buH!85zU!@60JOfY1a+l z%NYr(ject;^GL*r-^L?FVv3AB9d;W=I7LK%0w^LbOXH?uv)@Ss*Jkq6%-?@lhM4px z(vfRrD~NJgTl6GNhLCfnuq2M)yA zjXwGjoDIr@;3~%Z5r6A(=^HvkI+Mx(PKSWB9C%H__~CC&0`GOvMF1a|Jhhb5@!AS* zF2l28GeGiQht=2K+O0XezP?U=1ZKV|JbogH_K<3JRw(>Vjv}>W*bexE9j;O%i-cfy zR}ouO^ZT{H>i+E2?IYcil4JMU#==bp9f}I|cn5*i`fWEMkHoZkl&~pJie7^wemQK` z9TIe)M()UXg=vxdwD(nmPG964bSdC?ghwKm-*P_t1LyW9Z;G0git$+U42vumApbkX zte5ldj$zE-IMhPvi2GFG+t~AYwm^ff+*t zp*izs>1rpA?3-c+!w|Z9(OU>e*iXKPpdlT7Sqp*q2T;Aag@}NPbes`iYIq;Qx7jgJ z_#GAL=(xq@FgMTkN;_AnT@1`f9gUY3v*J}wc4X$ZQITDdd7!qQ8}c&OQ|?WvL;qKW zdoa@N$(PNAR<%ddGzS;tbVr4iDbE{bCNHe?VDg?$8{Z|ltw%?9?iuICxH(%JGbP9w zN6Z(m*FXAD?y|3h&!8vOm{6PjICdyUa)rZu-s(+e7)kc)AoXeY&lxAqSH;glG@aGD zX`L=EYc$Nms14C>ex&lZc$5Q1Mq)5_8}+Ss!oLFd8%?IXBXl&KoqQERlH$@h&x21Ht*syu~|cA$LRBQ7;-c zq+Y`&@qryOD(vCT#1JRgH{jbgYf~1-NFZ=ias)tM>G`?t%?(0D+}V*#isMF#QfBx{ zbJeK(ziU58cYsd3JSzWrw^{gEoH%-B*hp77jLWj8jB<8qB?2tiw>F8C$JjG5_9+)9 z3bkYg%GrwcX|{N-35^uZC6j{02wC@0cXqj(X|srhiI-j?zJtm`D7o5=!GA~FdCim; z5tR~b-33fr{jVFW((tSIr-lBh%zo zI+QWCq!|hmIO^(l4=<1lJnx$(o~n#!==-F2eR-^co7I1;bF{kkk@>8`PT*Wm`dmmC z3)XX7Cs3}`jI=kBYh)7(orb#i^2RO=d|Wc0u1+d=!?7AnIshda@}w#?Ia|cH81Lt8Wi$aex5<#pD$WZLq_QSs zB;RwTJ`DlMiRFB1v07hh?8rt6Uk8ys2}+JXr}t$%%>iFFSXt4iML{IQ2b7kE{_sTw zEBoXeuCI@iy0L^T#xVfJJ@UpK&$RS~a@P`0#jJ;Ob~4NF~X9xJ#oeuF)4W ziZ*P+;x?gjy^(Kj!SwNjLJO(Lu5R90Z+#?$!$;8ji^1|7IExZs5-&i==mf#r^{T>+IYM(y@F7=J7qJ? z(^Ol3pH4>qIDpNl#A+6CG<#lCB#AfUA+r5u(}GdaXRstR=ih~xVVv?pD8XYjAtE{U z)r;n{`GtY1*;ya~%e-sN%lWj$+A~0ldiXi6Ol#12sMm#8BL5L#wutr2fldWm@=;uJ zzvZvFp3(r}EBaWhtFj>$)ksQFk4?=CdD&ViKeM+vJB-?e^6yt!2qcAlzBfcVs8Kc3 znvfAq;gk9_U3sDQ)$Kax85Z+st&bay9lXb?fEdXj(|xK0b4_$U8r#n5ZWs zC8M>}WVfj!dX=ka45cR4+o-JPv-v?cP^M|?tZbsM8RAk@2) zIZOBg-xT?1}p{=o#-7U;o?7}cq zBn|kZl?oxwx+F>GG`I)mqf`snwn;h6qhm&r!QhWPO_@C2uW^Z3#6 z`#R+J1)D;JJ<%U8017fJifh)WFc)p`bLJid!cK`2P%0d7f_>*jN}z_9s%f#;Ts)D!gpnj}*5} zL(5e~1AQwLOmP^mpzP0o2X>}T*js+91s%O2@4AkCm!9D-(ju_LB^cPAo zd^TDJk)>qLeLfG(I6~p{52@JAy%Bz;WA84I(6AC1{rpV@^QW0W3<=q-N2}~v3>stf z`7q7dk7$jLFlLgZ!m+Gz{pQR?EuAja`%ZPml_=c|2?>&ER;>|bSSgQL;ya0eq1nja z?4go`VHv-Pka#B9Xgx}H^D={0ZS!oNWu8zt@F288GM7Y-L$KhJA=q0RHsEpcAdeG8 zfP6?Q@-_Esqoe)!qf;JzSLw{0;3BLNxR8;K1Bw_M6wgGSLQB$+{0O|EVna{V!*5al z+@rH_KhumO3|n+xq3ZLBT^oHqo9qvcABqK{n$2dIHOIAI9!;e@9hucf9UeDS`Y%R+ zl5YQ-x(=N*(_WTHlkI@A-+e5t{|L9UM$VGKB9mvuH&@f@Wn*{TTA%B8<>YoP%R8d0 znKDvj;~MXi_vJl9REBeu3t{hwZr+Wn{o8W z8AN_VZJ9E)_KE2an&Lgl*X~S|2t=GR3gcShbja}DS~O!$Z;6E)R1{~%WQWl>4g6{` zq^Nu|==^&J#$SYTrH|l}qUl8pK3B;)c%-kOcld}*(v@UIs#MO&EOpE~hq3!vsm?x0CtU)Fe+r?;b;zjeLD#gINglckA|!%0&7T#=V-el6BU1{O356gJDC5oeW0 zo)G2VzU0Nc)z_*ni4~LNwwTQvlU-F&1f6P(tAmMS-}yMYR$!Jg$eGpMwCpoAw?+kvv}xh+;7$uE^ysvhWlb$jDbCWWzL~Gx`>84>D31puqa@Y&kmGvo&gT3Hw@vrVJ~A zP`tG^19GU*Xl_~2S7A=ac-C=ne^aFYD(!**8I-f0^1#3K zOPb9OmK~)Z?!U2mPqCBPs0H&#rUouF_Mrf)^w}NkP3ae<#&^ix->dGsHIUPx2?j_f3S6kz z+<3ALZt(b?nWxzNYI?)VZ@&?l1CtE5_JqgtFqA0l5Ug!K-Wk}KdJmSyEn6)5ay$d> zC!X*Y+)Tj-elGa2sC2y-SQ~F3VJY4k6pw(FgGK~C_;Eyzb=OmR+>i5g63fAlMLa?D z?Au-|HG3?2eD%{>*Ss>>>?KZlw1Z(n;uf`#u}oPb`?czWg9IcX4e)z-TT~YJ6MSUE znd5=ek?KM}jtC&UEb@zp@Ob1F4ijr74=z7&7q+B(^L3HXEUJ5R%c6$n&*Sa_ph52K z6zup8PsG7L8y+rfQk;g2taYnZ;<0w%)3N4i2mH$gz=it1D1kZ1VwWknay<7G=m$+Y z@z3$;eg&S=A?w2XS0=bP5}zO3Iwybn=btAzfPdl(e}7Htfqxrli;nl_fIle&E{}La z2K*=Q_?PxO$M!};3?%4E;=Xpb-hg}C9D@b_KH&ei_x|b$rv~zTla3FTwOc7_AtwgB zBuH`M`v=Xc8?XNo(yg#lItt$@Wu4yPc6)75{!1LJC*+JRW}HGBDKtRXa4E0L>9Q z?`r@w=foWqVeA)<_rUS}zEXfuM_VZxk)62cf2+#T&%q5TB)nh{1oz)(pD+T)6S)i~ za-HH{)Q6K-;mZyD2kSZ(|G(^- z|A%QDf-I1o<$oZV6QJGkM6N^15af{%`Cpkpe}(?nI3CO8|12=HF#l(PPo4f-^@-07 z4^Ji>o2NHY1kusoU@`}|1n-=FC~Y>DAG?Dku$$DSY3PgNZ>T? zG7mY@r`jCxz;B-Ztp1lzQ2>sfcWbTvA+)VL!oh}*Aj2tZ)*X@lDak}J^~?Vn7jOj~ zlu_Rdo#ew^Z3(pd;&nS(UuZXziUMOuT4P0Va*LIOoYD!FBD(G`1{pqpi4o%-Uh)}y z&Fp^-f&2Q;{XITG>7io4B5tGA0O!W2(eHQZk?ecZ_YeEgCJV`1gi;KEto zH#r}8f0^J#a_aT=k_+#_u+=F?;Phl0N)Ef6Ynd9GY9r{?QIT3F5`_;YKepC7YOlw> zGIzno4GorBq*OTBcTY2izuU^_a&DVz8R%k~)?#|mXT^bsUvUp?>W?QxaLS_rfb&-= z#3O|u>v{Pp?M zRTAjOdf=pO0wy0X-snI2>5XhZm+l0E& z!RW^zx$ouM-mEmGX4`5eV~H_D38NTr;N&mD{h%|lUTOV+Z=-T zf%l}sAJZIdm7oHnvexf1&%N8c(QksHNHn|$XX5EGo5*^HBr&e}_`RN}LxDmJqCcCD#boh2nhfI{Y$&VjylQ7MRFGL# zycnNGls>qSQMl1JpD!z<5EZTcu);lHVgS((-t2Q*zX2(|_~1@DWbQO3B>FVCFUf@nj@%F!AP|c&$a8@Z>?s1&n?hA4$C8xV)YFo8TENZ!O^Hon%WHR~FSJ$d2 z1q?n_+O<}!hVna`kGNZo9S)sU2d|?plIlXdsQ7kXoc)5feDd*AcMn$@U?-WtZmKCf4ja$fOHZ4043cwqaIyZoz&3LHhaSK= zkX^!q|7CO^TnE0!Mwb>BUy?>awgBB&IqLbw-5Iv)YF=}e0P#f+16$xONs%OH$#mjg z*kw&O#F$xQYv7sX1#nX{PYNv3y zS9w}0tnXt7r#?n)&uTVs-DE!b6+-}8s+yG#)74hQ)R?G1NZz6#SD4<@QT6VK5J|1s zS88FnyziDW@!e59ldo72bAJGVr7A`w0S3T1UNh_0M>4K_mtmD3o;7jSD1yx??O4it zV#DG;`~c<~eCcc}Zoc?YV9T~gKWuh9i${o*mde*_NjMxifA5|8c}?tOROSPY9?_Yn zQFqYixBkg+8Jp^=l^`kH^XXX-`huhta3MA7*8?3MW_}#WZAliAQ{9m^hTTQz6ry}k zfXS%5u$`uFNJ8~`x-m%N)%lM>1l7_nr?t?i!>WT~Uq#mY3U{aH%0l9jJJ&{Qx0F!X zuYrT46x1)sw3ggbO{4RHpB{;8qMwayF1Q0#F>l&TGX1sNSilzRqhwR_13v1B6J(x* z&z*wir6CCtgk*2Ox|11)$X{-K9LjlxRs^{9@H!I3`m|Flyq9#d)>VFubbr_y>pE(G z1nO`gj5kO%!UYBYrVth0r*yhZe_1i&TmTa2iPOf6z-4GR&`m*uES{A7YmhY1ASsyD zaA6DGhnx?_IHmd}2`b6HU~)BHF+Mm6dCCDz z@wC+N{&$v8+{Ahpgkcy#w^7!6S zB##A?)x`IBJ7M#`(@{^b4hly1tVy6LdhpQynwg=;t_PesmgaTRr|O)vI>Ce=$>5M{ z`qztl^pSxD6BN!8hrR^h)cwS5?{ALOxWzOj$oV*G`rC^AF_Hc zWkZiA-%_E)mcXDHe z-LozP($1~rJ~rt~jQOeckm@C}wUAs&r8^vjC=RL8l%FBdStpFH#heHHDvVzNT_pV3$e=CBTE!b+q%-C^5*Jsh?Q7-UsNaU>@IOi*=t^{gjrHOMyts1e z>GWClLlHLqzANiyGw6T7?Y7ga({l}99oWp?SU%8+yYgN3%NYscRN#e_vK)AAHQLL=1Oj2b`enp&ui8EH~U(Jxk23R2s2H&5L=LUy%|Lq&SvyvEXc035~iu1uJOTo zugC@uP-)xkqmmdmYnp@Ksq!wnK|+#;L9qLyMseV>Lv3~$R7N7*>R!caI>xLKzUMetB|ifphJAw8Sop1`~o0kWx& zH6^i{x^Pxgz~z}^^NiBB;d6@jEN=FgsDVxz-Fe9(Ctr|8qR4PUuYrpAEgu|D+SLCg z+`umrk*lST6GSG6`DNjiuAAl4?Nu2AOV4*UU)C35BfES)ck<{#=auVk;?>K zfF9{CaP7KIxxF3>cRO0Prw~*aP)yZ*6jSc-Q)_i&^zj&qB$=+$;qheGy}-lt=~TSLV(lKN7unXu5trH?$6jER$Ifc zTuvn!uk~xnTjD)tZ@5gC%*wm9#wEQJ)1ERG9%lLbDl;aKe5UV;-6~f~vc3!!Jp<(* zjRL0w4+$c*7(j_t(JzHnx%Zap7C8OixBYmr4OBtat#A-kpJS5cmYagB%|jvS)wcC2*~bq_bjUP*yI$?$V8;@`Wc#bW;`1N z5fTVeb(zDP!ZTiOD{zp*g;$16!mBu)VU;rddSN|_Bj~^p=BE2&#V>#0ac7Tds9rQ6 zz9AQTjCG*EKGkVzZatZxe|-krPqZGL(RrMGYlq^uw|3!cg3XHRg3g#0SdF6Q*7`!` zTk?yZ7KsixBv~W^@)-ooJSTyW(+t2RTIZdP=fz3=G+~KTzaCS1z@bAo>(KUMq&BzR zuZIWDt66-Qg@$&VJ$xbptO@?Z)Yk+j-HjH&XLRL{5tk6~PE7dua`UY+!1YmpC<8&0 z65TcFrBLW6<$vZFq4_uZBs_T=4Rzq23hM)Vp+^PD(A@&Xd-L|W2arGg0G!mV-@m$S zPq?C6LBRFhp)@OlWcB1M7}@&=zMGJXelGyz7G#()kBim*Y{MW`uq!zNg!1m|oKo&RAie@(hhl2%|6)t8qZ84qeXCpgLw8~j?{_)Iv8s?%h zCp(3o8N5n4q8_A?71S`Vx`RZJJAu@}D^>7O>Ah4fw^ec$wbz2Kd)jj5ZID8|Q2+wq z?XhhC=Y+^f@oxh$KX^M`gi{%v+oXUsEAf~_U-Bp!0;BX+8TvqBy!(r-t9qs4Lkk_E zb=nL=*|X!;9MEynR58Lg6FL+IS_XdYUB zRhA)Vk&_->cAm@p$6~%_+RtRXN2AX|qc~K;t(NX~2%Q$5=0lg~H}v<~m33{+M^vY! zlye+>0%$%PZWondS2dFlZp8p!mSs;?nJy7X3;7$hV#gS~i%6}iqw4KLrE1m##XQSr zV*ZqHe$2`z9~Hub?M>mhri%MUHm;l)LKRR<+RFJXwGr1RWVCOO+L zliPx2wr>pgp+{0eD__7gOI#iS5UhJ+wyg(cY8uM?TxLu;6Tyu9O#dvck_rRadRPVf zH)TwAUb=FZ+Mzcbn6*t!OtwS(6_cKl&`Qj=+6z%!W_ei$)zjFD3(lr(dzF-2PG7<@ zv=X?`oko+N;Y}gJi9-9oYOjZNIP20*ANl6m_?fNwVHJXjA1Z{|*Cc=ITwETr6w$ucp!c|t#?&rVZ|n1*vr#sb{J+*t zQaD`Sy?R$tF=oVFS)05`cXhSlW~!FIDUY&5U;vY1?kDaWo!~fN;7EyRIiLQXsOy_M zoj5%{9nWunH2&@_5cR`M5ZQMT6A_&Z$UWpBdoLz!?giNkQVd=^ISfi)SH^mBh+sEc zzOKC6MC7Xhi=Hp<5?SLWXwVX|H~F0?xpmrr89C~RrHO2!woznNP~~RsD;WPcw)S07 zIPw6Q)}3wE#(A^%$L;WtZWi?VRKtO&e(M#TG9#AGo4h=&^C*&25Lz$#si?mbVqC$sdh%2_q?Ym0{P z>tRyoz}o=8StF=jK4`6y?0EG(=UXr@u^C_L3{BMh&uaV4gNnkv`->@CkE8wVGy}j0PW_hrBh&9xH zdXStYCbvbIqE(ZluUONjuI;&Ipi>mgIw~_~o%fooWo$t8I*H@2$AER=Fn@Ui6Pb4~6euOfNSi=`sFY-9(?C9ZcZXlIu8djfjH3-&+x^PI!37hO@gup)oVr|>+y;NFHtZSmGpG0LrcTs?(UeTsLqFT?-gcs^|!-sN!{ywkipS6^b9 z87X_6O*<#PIk7&l2VETQHgb?2RbZOnFN_F5m(6!nm2*tBegW_uT5hxk_Qm%GTa|%- z41(F|q6(8Ch&j7cr|{m8b_cG(E{D;1=%rs=3OmDG4*!69t9Ver`aeeJxrgD^z8 zu9ELU$D~A*kcqcUj9~KN?Y#j(q;yGvLyxX{XrakZlXAnZ`WtT4Q#p;E@)w9#`{o!E zL%*@SlkVwWFJzt)O!cYs0UaRw-w2tsQ!0p-r0KYlW=VT2RAsBRv4T$llklv~6scl% zcrCrc2)Fxy3qQ=@L+x_9{TzQ=o!v7*h(PvL^&IenqmHvQJ!l1qSM}#BB{#t9?cLhe5_Vke&k>q#Gp%GfFZg-35!h2_?gMy z>?t#|TaH;)tkyP`*L}S->Sk+KyPHr;s(Ge0?H}wY zs^3YFEMWajxeR{2;70U4>0$15xM^l0mmV*GbXxd1!e3O@xH+U~4JtO$iP%7b*A#+e zr+BRa3TphR0yF_gTk=$FTi%ua^t3Hjxa;jS;Zlh;6!reR|4X}HPZSl#qCR*O>D!~% z`1xEZAs|?yCZ3%1<__dYr7qZ0z;HAy;xsF$%d;rjlJeB)HV1-Bl zKF12TcO_?_Z=rrAP^(=}n=SGMw*{{s39Fpw%~Y2RWm3x7$49>X@uTt2J_6T5{3)=* zMoGB>alKFY0LetPTTQXzF0l{?)E5NdC58FUA1lC%*nQo{qNTx5s^^1`_VzMJW85?_ISL1M)PYOh>TU(6Gy0d zuL1rMWLh!L02qU;1VI~Q%tQq(f#2aH%U~lDeB9T{|Mtfg)R8A>JU`M+a4p2+}z|^ z4}PY+F|Ts#AlYN;QgJ$5DvcF#P9sZ^F#?4ywF(ofPeWI)F=z?8!Bq*}^@T|eX@oZJ za@FSp^BFQx8>mf@@`QkFe%NC}GWO;G;VaV_+rsr8rIn#yEV6dTiAt@`n6x|mh$$>9 zRgC%ixdv0fv~D4HTA%tLxC(64puI!f;I>hU&Gj}fBO?w}Yii^xLq;19w&ks4zc6L& zHJZ)w3ysUwBsBaPcB9L$f3JJd6?3L;V5ZNf?A;Ho;NMgnjdlb%1=oSgx*-uI_gbMF zeT1QBfuPXx2EPzgKQDOR#AP#Kb1ds+^l8&|vSyzdM@!?@RvKm3p#V%U!V7S=2UF-cG&YyYU&bQyDkrhAjPuO-o>?>P&1oAsEk`mac%A#$Ip_**+%`hNBqoj?seS)qtI5S8Q>rDf$URb zmEK7ukXBG}HNFz^5&D+RU##BMFZ!@7ZngH6hHO?QEda(mNLcPD5ak#i(7H2+0x*Lk z`A9z4Tc#5j@J)U17D-YzkHM|A0@wExoTxftYC~Cl@yeQN3oWIbzLeZ)e8npnp!(d;tE1)X zY-eFwTlU2pzFKh*P`%8t&8+q%qGD*fU7dZj)2sP<55POJ#!3#G_MKyL=9}77xE)&P z$eYw(+^E>DLbb(Z<#yGbH;R4mNEA-Vr-~MmO-_BDFu1|+Gx|&KSfQJa5Mm(rhtAl( zH(ZFODMqmP8eB7j%{r+!s??OrtmZ+cMscTG`IGo73*BY;QT9eNmWRA1;iZQ)<9-XA z1;wE3pWY^PC>^usfPUej3k5(>?YEX(fnugO53TXrdSPY&4r(j8Hcc(XAUogX*LKA@u~Bh9h%DP9}b zdg)fbIbk-@nTjU8UrMVOgSyaScYOT(+ZPz)<6Ze0Z7g)lm&nnCLq1HNvVy61fPxmH1!@Rjd= z+1IpK^uk1ktH<9|-T(Bg@2~_@<6_;-lYb`?q!IJ|k*?L~N9lVohlU_-9}D-^=7X`H zak0=H)kBDUbU&yzV1A+0)U2ThKo20Ya&c?1xu|&W3(zBz z70*(;pMb8!_cf=nW!%^%#RR}KFnn&dJj1H-kUw-JutperZD$hpP|^Q=x7(dEN%(0r_G336sV3%=Lvy{dXF1`kT_Eukeyx zeJ~~~ouz{|F9Q!Nx3gD=w})gl9PPSq#7QP#1o`KDycW65_Z-yWhHh06lIUBZe*G`a zW+EbCa$NCfipTj$ll%G`2M3`BZyh!`QyuGPFovcgGN%ugtT%Tb99g|d4By);u*}Hf zx?+FS#9W(#`}{_>a94ZmV??qS`U|@RKuMfpqcQF)TILo=$_(Q zWkfvF7=-oG-)!0EijyktHU|?epeK%*Tg$i7oqa~N zNqe}PvpPGVXb@>xzZwhw06^B6Eo8dGH(kjsM-z3|Zc|HH8h)!KFS{t@!-YWEe!W5a zy2i zlv^}(l-vfl5*M7hT^}`6L@#%t1LfUg2fd%57WCGa8V4&7!627kwxFBR?gv#@YB&|| zve(A-V|>W;Xxvqe&lTM{BWW6k(5l!wC{DaNRA?8T8N2H?xm}gwa@aV_LH-1_*Pxge zafB!QcyzOBtQym7JIxx}%=*J1Y%r?$b?iZ`L}HlafhrSdds?`qK%pyoEC0?5r{YbJ zkcKlOrQcg(^exau;`ywqk3pI2e@X580a!S=LtDX;!+y zwK6MSZ}h^)X6yW^R0jMEx^B21{>IBs%xPR=eTU*P+D&X&YS6C=)mMyk8K3=w85iPBs z3}437lpt+f!!$Q71cVQE6x4s~*8QB_(GGoX>bgJ9KwRIobOB0jdNSSnuGcjxE@?b` z-Em&re&uiyTglh6kShH}~ALwUMB*>P>;_?C7B8S^?#moJZMETiF*)to@Mwoz`_*DZ~3VI|Dl#ebr`L z<3F0Oy9l=#%$Kk$h*y)sc7Hq&9*XMTl_4_a&Xdx*#v<2UjMseMa6VPIF6C8ofbW*F zbmRgG$a-LiH7c)x6+KT@0?4;;_e0y-p9Bh*`Cfgy)T;Jy!|V6juFpI+kD_@R1E<6$ zzlo;56!~k-W@>IjCvAfI;G->0?=8X_lJXkIbf*0NB*wTj{jajvSMqZ;x6C*^d2kiTSeZ*YGEMi-EknX*csZ4@v0;UmFE6Ta6$L``*>NQz3(ghSLO7B z+jeItkl~1qPr2`w^VDw=Ag{@)Cm_n*Ispddiqt4GGN!r}asAhf*Y4oCMKdb6oI%YO zDu$zO234UVZ26L4f$U^TV16HFrMsSWve$j;6wRph3&*CZ-ue8LBYAzWjb&@G%yktFdZ7(#f}JZrI4?r^qe!TXm<|NP*2?w70~jhnF-O<1|D!cvf2o z!5$x88ctwRwYx_JXd8y%MqC~##z^P8+bT7vH-k%K98PXnQ)VQ!3k;n6g0A3m*!)tN zq*AZtOUV)i4w;(+_q;nHy=ICr+~Aeo`dK*H7g8=wn~c4cX#ueJeCn0Yz!UCqusQVyox;Tebfi$%&aKJRE<*@a^n#S{;>X(ik8FRfxnbo; z6)#3GA*W4MQUUQ+{gECMkF>2^a2Xu&K$q!uOP+qE&t{&K`0mmG0KTNCL?bO56^kS2 zjC!Jb>{NL-L`RmWB?M}e<`4la0}`_t<~ zch6GwnP*(Q%RG2@0IKFQ$F;aALDk&N=bWz>mKe9FMtK^5uvOO!Lw1=Xi14%Ox#nJ17^LqgEbFB`bg3Z#J(CF=~P5Cs&}OEQ_pn(`x4On9)$27zpx5(|piiFU0+%#UL? zi}D&%Vt~DU-G2kb#w``xaXtH`7yIQ}&&tsV@(qeKwy@;~_DwPbE*pMZ`liRk4kt&c z%6BitDQ9`^?)GStFDmC?^LGy@c1Furd0$(D)UTkvV|McQqy({h-5yOGTbDc9I1x3} zmJT$2^qrI3z}0>>nJQejFV5bAk02RPckd+PrGa>a8tMQp`4?ZtR9EpRof)&xNMt`# zpJrT6&*6M3@_NUOyGKtA+v1dhG4Q2kw8;q-B0$50$1jixP73?nP*& zOq}zRYKt4XmUI=)GMRkLCIzXm zQ=n>AS|uGfpqvsR=y=|lq$pH~-fT~2kp$ya;aH?9-e$-~bu@@bBWQ7ji$yqAIkKBG zRY*@io9&H3%;}}E+AR;E11k9jEtyjRsavhC+Agw*Hb3wqLAx}0^N9Ou+N(C=BB#0O zTA=bjn|Ezxwifz__M$2STjbx5?AdQq!AbZPDR-TYZ6%o2J;wqEgl&MOg&#)&Cuh0DZez)SIm&Igw8xDV(8{g3wB_BRE7BFT!g%TV#M1 zBa@DJ)7R3f>Sutia&{$8S5w?x83X)1!sU`kx2Ok$Eq#AjKt;anCf)b!c%Moji0_+S zoXgk2Lj}1?Fg+gp2$0ujYFtgd}Jj>Sa4VI+87FsomtIr$n8K=dYC}!w{j|tcu@&K4FM>xFYx3RD6^hkV4 zCM9Pa7Ql*)D~+~B+0{}$eAXA|48s%K+?v|t!I2mHm~w;QD5yp$jD=ekn;bB)Xynqh zYp2ai(RYLM9?l2`lKl;Tr~oF4^>jz#G7fvaiXRB*q>-Sa_Nql%pD|(}wEQwFg5;jr z#f(SvX22e&Xv()ykdO^WG+iTmBi4Nzc+wmpWKJWC5@n>x6XLU4DsOV;ZO@g`;tI%r zJ~SQyK$2Yi0}Mw}-2pKEISY=6oJI?!$7@*u!-myv{UNo=B@c&!=#?m0khvNl*Uk^s zyu9TwlGB)C&5*Fyp3TDmDk3u(j#p0B5p_Ww2Pq&#og?wjVRX=PYYTV} zsDm{v_gnh_Eu!3B=7|vSZ0mDn%42}&Yg%Ch)f@gb0QjELzyj!*YaH_gWI*CEezxtH zDlH0n*{^X``7?Z#jP1h=t42!Y(HwDrkmPAMBRR7H2n=ytnSnPc+uepkz}qpzk6z-< zrh-1Bjm$#5CYMx001*r+f7(yox3A@qM7O z7nk_d_c~jw`GG4lS5%82r1s%psjPQzCjHytk5d3rh-OAdXLS);f;SsbMV|bp`isZT zL`tarNV7!#!j+6--HPPAAI%HtqN+=MWkt(r+oP^+=jBxbwev&a@0>0vqi-d@UMN;b zQ_M~v(%-wZnkZgKIe)M{3YB}gAu@;S5DL-r#o#g2zQWv>sR;6O#9djx^DH44zt>Hl zVDDgN2ajC6$wuBEojOIB_3X(b#jWT6cTST(mB8rXkt(6#pk4H+vpD&JVmrXpL)bON z;r|Fca%`Rggx7!?R7f1EyP@iKDAzOjk#cug8YjE<(Z|jRtnamZ^s5*_vuZYts?=** zt+oesw*LaM*hQNNCN`TuscP*!9f(?nP`A-*jTb)Le_R;V3pF`HJ%L24f*QXk8QLLA zSe8#p(dvNtkm=j<;1pRV(8|}H>8>)?grc`ag8skPz7(8cP&c3MlfW#sR+9m2^3DS< z)TOwDJF8VGptQg&v(!JhHhF%miDNd>s^Baz7Y>48G5R(pP5x3RBB<@+9|kpC@AsNJ zLKFFwdFpD-kkzwcpV%o!kkice=JRB(uWbycA9=G*%hvt#9QBOLIYC!;7*q~ zz(%ykdW;i5I`#s1N5ThYd&WI5IFet9^ZL(%NA1G|8zJo4=kH2>dg{!x1htkTPC=mj zKy_1=8r*a~rg*Gl^ajQl^p-`Hzs|x?_b0lq9xU<~OZRst!&S&L<)5Uq#rB3=R#;wl z0^vt*kw;f28XP`XedZFf zsfRWFRW)_K&~*}R`O!Q_rF*hB$$zT6fRHe4o>0Yi&cvVrl0e0m{60i|99RVOnF zcH_`#ts=s10r1iZ<32W2HX&hq;I1Ub_&G)HM<=;bvYWnh>yXvxznm`3UN)-)`<@Cn z8*;W6(x9A^2`UgtTJM|}`airXIykp+Ro=g@XStAmXOF{`9&~&v(tmdbh1NLo1h@R zWt;^1Mo6y$aeujIMf{gPC zO<{M-DGQB_stw=92mwpIHH${*2dna#13V3COoZse-YU!nnTnB7$%V%A2GdNT&2EB* zAE=$ckxxWOfKZu+f879-d%HNdeRL*$nG-nqu@9cwjZ()UJ?kdZ$;e{!JvTP<;gX^& z&5GA|1*Nh7VlB;EJ!$e%+J-+-pjtlACA~AXvFe-5Jm6mcp0<|NCmeLxUP+NLt3~N^ zhBYrExiC?H3?s3P-RRbC3SmoJbyI9MWbFgo4Fcq?f!WBFTci|_Q>wk!C2`V<{I`WX z1W1rRKd^oH_Xd~6fWSz(y=)?VU;&mOGpbTD-R%W}IiO`7F#{OudQ7$#XBbnV%E=a} zHmMw$pK+-p{~OP6cJqVXw5+zY_#iop1+-qj5yZ>aH@>%U{m&xj_diQ+NJ z0yz?sQ^6c@cn7EJK)zcbU>Z(@=5oeI4a7C2xVp(cc+}oyDC?SD*s}fc$De#3Q1r$? zNyGV5F|h@2hJe2H(DYWzhWjWc-=hByEg$wmr>peLtWush0XSSv#d+k={{ok16MgvJ z{Z7z8_CI1{-vfJ0&TVKLnKe>kzI}zyY5%<~A819^?97rH`#D(Tj68^v?cW54rt-P3 zMGG};2CWE}tg1I|S_ABYPK|TbS)VNo?moIN)g=yBs4Jj2AVL}h#3Y~b**4t_>1g^D z_6X4QI{xsS07+QIb$gF*ueswWyAn&VT=sGD)S(Vd%g?Q5@{eIUH1v8m-!-JxE?j%! zACmVh|6XR%pg{>aUz6U`vebBrA+i2PQjBWhLB?;-8y_Vly=#B=StP+W$K!HaF|lM~ zWbx`ogvZkc8?>F6=3W1870W`wO2P~m#BZ0OOlV#$zS=rTCCYS|Pzzw(kL+#n> z9m>j>A-lSfW#)PtV0|V;co>QqGPxMIu0NTXY z?!$iU_^8@)V(k?=k(WZJ^}Ad|4`tr`M`9wxcugp3)V(u6gcq-r4CkTgJ`ai`Oia>z z^EQ!D(Y_rciR`XMWkrtE(cnim1ox0j=l&z^(|C9B?;#~4@;(CjH#`*?2&sRdJ+$L= z-{ih;inbHewc^n$7q;CgoB6})2eg0AT$Z~CR%-wD7c+2<-tme-_X?r=V#cJ?!~up# zcN?rJZLOKc(EE|0F~7Th;oo1F_U%7Y_!w9J{ zY#-SHLU<=j&sqTf+V?3a9G_WzzdW`$&dAVit)b-`wra*ypXTHw)zHuo9%H}x@@yd~;bUtB zoTeI!a6w8vwUUnKa|geUVH`JQly>vUJ1@nHE}GjqgkODo_=8`!%Tgh|u=#;>HUH@7 zXxo;b!%M~)*S?%8D1>7!h5IVl+QCPsxN|kRw2$Q5<5Hu0;S8yTIhyI#3O#KF>FrO( zMiLTOerD(~({O7aN~k~5u4e>au!kc*O+~og7hdl!)i*T!CH@fo?0eU4vW=^!(Eb{Z zbe@-_U@!j7-9Ks{yknE!V?D-7F{-CESSvWX(ivI(sqa_^JICVHn{sSC{zr7OYKFPp3r)@U*kk`sRYuMxT2j@ij0}~DDl7)m- z>=_*Yd@1)?G@?fS>>1LRVZ1^T;grUX@Rf~!&U7Sy>9@U*MHiKkk?EU-qvUbjc z>#62&&C5vzuAHHY$pXCu9i`_VuTdT>(Y10E(=v<@5LPi_a6E^$o1 zW(|Kc5j*{@=qf+rC*W)ET?@_K5q+Pn!%>t-39lQ0p)oNQ3yj%5IKE^fCaKzC^v|^SHi1=l^Zo1gNejZ$R3x;=ID6SOVaLIKtU+r+ zRcAR;(q>Dv3#O(BjTIV7{74+dk4%P3xQ*M;P(zXF@AZ%EaF8~r%o9H}I zNl{c!ZW>&NYIw;#CGGznnb_njg>1AkblbfT(r`Mo{@0MSyV)P;jWnQ@*lJ`!ucYf4 zI`N;Irnp#Qcw~gQWyEhXBO3-mHP1gz{WwhZ-!Gpz{5;|375)$nAfiT7X`1zv>==un zpbCx@e`JVXTpV+xkl86mLTB309s)E7Y;j`tzt1N&*Zw`VH{PqvE-i(MKb9bs&N`1D zr`;i?u<{VsHa%yT}tz(D(XY;(hdB0F5{?mhd zY>zASmmXG6Oq1bi)t9TOvcBR^`9K3!P6}K^PZrE7J_4ekf{zaQbzl2GY0GcDXHBxxOMYyN*_)+ zqIlcWIZ~IjxM=6!GUptzVUN~ywqV%Rf(gzaW{-FJyR}n7x`E}Oa2#yck_y~YD zeotFWKYXw`@YuOb`$@H;7Rq3W^_3aD>A1DX*MCQMi`mL{w_}}Nh*4A2&tB~V&fQmrxC!4)hRaO5PYtz!wuH*LY zZm(e7jC`kodn{T``nwnbHppEXM#jJh0b{jKTN^WF89(GQqlCOOiTr7Jp326bzkZ$cDJk8fv$sDS=jLv_ zzi`}^otc^WXXT=rujFSy@@DzaCS}{!Yypj4+O^=qquZTOA5Yyx)@aiq~L|?1c++!!MN* z3_d^oWIOV#yFHv8MsRjzCBKm3Jy%mbOxn@yQ!hULD?EvcielSV$?5Hr>E!yQhV78$ zrSsk@pN64~Z#A9v$hj7;T;8E?;lUyVbEnUHpndp*5ljfg?zx{!VI@>BZljB9Ui%A~dq;`)ir=KmXJaR`T%g=&@Q&fE6|>7!O&+7DF+e*R=LbbV)g zu|+93HkSNxh1dIA$&qcUuy49@&4{p$GEZreg9qoj%rYXFjNMA!rlpZicjx=C$#>*g z9GhQQ$TDtXf?|X$I5;?IBHz68(bSYVRvyfH`Fn}0qj_)PQARO46jKyhgaCS{-p&w4 zp=hUiduwB0a?=0Nqdla|QVeiq*dZ#ayOFq`?{8hXas|Vp#U07_5|Mv_gDE^ccSwj5 z1_uYNhpNeFNeS85*p8n&M*}$C_t~>Y5N9+s=^^e0i9Q%T&c{dDoo6v5`(IG?mlVQhRf{*0}&?X{PcRnlBAIGt<)+F7ZF9hZaYlJ$rUtZ>B5v;7rL16O;Sm zjdv;>3}SY*c6z$HOlTFsrNSa)flI}Boo4kVX3O`Yl|x0cpPENk+fpjus-Mt$EJx9> z=6Myaw`lI$x&B|Fw{>OmEqm*7{|XI_(A~#*_UvA)rRd2?`AP^>!4VOD&l$xNEV}cY zrm|{g2Yi?Z7bjYT%dA+gS@sqCMV+&%i;-cvbixt)1IJVYAuX&~UecOT7KGx2Jgzc7 zC+BDUsf6EXORX)8DeUx?x*vmF`rS15omM`#%i=fzhJHAFX}+1oZ8s_!8bi3H@%}PtT+vLaZOh2Whyj3^@zzutUDs(LPQ6kFIXSsi z$ODtJ^H;83l}%MkpKZOZH!u_=T|GBc!-!*Ju_cTp@q^_3j@sYX_q>J%-3Q$g4o4D7 zO4ZMsYYSNhp9vYH+&Z`x;9tuxGrK=Aj&pD0T1bq{uND5%Tfz zVK@dVT48fqOdrzI0WvZ<7y+A+x}(uj?p=$k_2E22Q1m5v_J4EYNN`#DEtAo1xPt2) z?sq_U>(dcY`%r^uZ+@)%@|@30CnxLq+00Mtcgt$3~K3%(FLd*v$Ki zHE@5?4?rjh6DPowp+t0B9q@rtpaOCVlzra!S#9?t=3(}Wu!`t^tQ0g4XhDT@>&T*H zx(or21=4O`U*GE5SX`FP(4~e*p@Xm^W|x;QeZ2QA)1;Y&LBtxf=*p>p6+;FjPj)sx z$`DX{sF!(2qU<7g|HnQL4-Z;_d!+P2rcd@Cq&|N3?7?szJ>hRwQyp1OaBcBwsW$72 z_ltM7H*7h{HFEB^5bmrsdCva0#$(W#ZPbx%!-lUZ4L-<+(C<=Tn@f9&z2msr*Wkb0CT>fw`%5@js-ZX%zhvKxvrJ}q07^FnV zwH?LI0+3h@3mYq=tV&_29^lj|q(ayc*1SIeC>FSNCCMeKOF>M5kl^Eu>ceOyT?9Yq zl|APv+dRxD?(pTMl9Zp2S(`p&ASYbG*!TDgL|8eXh9LMRSWZLIJ8Kkf?(R2KR8-C` zt3DWOtfG+K^m_O1bnynR2qA_rF0H5OTKQe(r&w&%yM2Bpjg1Tr-no1Cu8Onh&o^6z zMX01X*Hn~z<4ow)7P9J~;*P?O5Y`qEu`nA=!waf4Hpam5!3~cgI^d{Ip40sLgExQI z_lRG?vjGV5pd$LVjSV06mus|a{JZAKCS8P{5P_41YBt2>p|MM8$ey2{uRNPkd}po{ zVcs)mh{a;a;Xh(xVhk6ZS^_~#{o_3{?EKrCCnO{oFzdlD#MpTk7coR0hFEY zc(fnGay0{Uas;vS07_xh$g$dQ-@MDpq*+*56~?S~ASd!cKEcW%{$$?!MvstF+1B#0 zLWgP7xy@Ba9-_-(5831$lKGfw-{C}5Eebuh#9%ZjX=#1S%g-0D^tn1Md^?wA*((MZ zsGGsxci5aPL;gtiIdMgLhKX!qPw zErM$0HH=f7_M!N%egCG~RPSlr&((yuP22CWVd1@jawgx}p4YAVi8T67} z=}yBdJ_v>I(szE?qOXa-=>S(xvr4<$ei(rXn7jB22DRe1H^C zbwcg>{8I^VS>tVFkN?ev? zuUzqML-V3`aG-t=VZr(kF&Dwg`$80AQ3r}gfC<;fHWRnH{XAO%DKMeRjJ#WElRu0 z9;+uXeZXX|BwdB;>gpiC&s86@QjZyH*YgYns6mCWB1H1n%BK-XM3og(f~Ns?RQb~c z|Ml1K{EQxzz`X{qt8Zm(ZTZn~0Eqe;1NiTLX=$lR&nG?rJR^!HC@S|J#24HbFEW{I zZ?3(P_Vn=X4kRMOE!Qx6{(@=ZaqNbYdUon#liI80;LA*W?vhaXw6sIH$>+Y+X&gs@ zZLgH=gu14!-48J>gk-e|==x~bS?ryP>AP0l1Egu}7w9NOWfRZ56n|K2xJ#ei;2N#H zYz)D)mfwuX1}ksR=l<)e5Q~;vL6)yCgX&G~N1Kmi3k06%^U|8@>OHMJ%!DW5QmTHm zw2UYoXGt*S)qT?0CPd)%ERKVhUH&keyzRK$Nhr7f`s*(huDr13$=oXn3Ih+gf?unc z3gJr5$>K;)060s?d_kn~&h{VHpmwi($Ub0Hms*UgHwZRp3{^Nn$#vNHj~_1|eYk%i zsS5`L@29cYQ&+BtZ~-jQXwJQ63~2op@O(iku8MBE^ycmuwk9Eh7Uw2$6Sz6vtsTqJ z83#;%p_e>_4c30AdpMwX#4Ncd2>l1o-fEQ5d89oKanyK{3(tiiVigH5z!If6qFMrK zhJu2EqlN!FL;Ku;t|slbSQ_zU)5{grwo$o@gD>8Q$8}`q;5j4$0s_D`xlX@@aqT+5 z@!m2jT=m-}u^Vb?hyVfD8t?Mh*MFJ{LHxus&OavXFswwE;_XdhPzsi=_^#a`1IBD& zP#NwiwY5u9IuWScKlhYSAH1Mm_$P4Ow(m4s{_@|eIQbAZP=-L~p!1~QlWOcxec2vY z0(U(8uMCY(Sauq8q)$!LKSyS6OE~MP#*|U|)k+4G5ovY#{LC9OS|}qP#vQgV!=VJv z(f!XZ^!D}!i2u(WUA=nsdh(@{wp0|H=pI||059S z?a7wppl>xIL#`2G_8fQa+~Mf?pu&-5+M04T=<-Fj!yb3gSG}XYmD&p7TY~X0=mbQ7 zXk{*4BIMR9<#c?e!|b`4r95QOnY|xM9YPE-NeiRjE?m9(>_YvI&i;eJCJ;$rvaVjc z_8)sWSN-KFh1bm{)&OA(Zozk$9`%-e*wLZh!hQ&ld!~6OKTr)2pY9CT24h|*PG;3G zeMamM6#a>rnTJ4m!o2b;*_4cOolc!G;0OyFft?~k4L;!oVc=5-z10*CM zQC^gl-2-RQ!({>Vtc1w+1o$LUMlmX=qrEiKtD&++r`X)+->IJJ{78U7J@$&vknog3 zh$bNwply3+j6JzE5ZARpZWU}V331EM;l|bECb*MQN;k8 z@5;4nA3HA(Tf$EIuMza3<>=U$Pg)vhntIkA!p8(H$x4XZrG!$$W*zQ}?bNA3IBx}1 zKF!HW%p+S)G%`4Fdr+_!Qp{Di}px>Q=O7Bnh zlhk(%4Vw`s)L+_b3fu1T{rhLAIn}*DRnTuvkn{ETzfk6}Wer*>r)JIpkZJ))=B_`w z8zpScAwqzN#Cwlb$r3d=qu4%APtPYlK10BJjJKs9TgLU8ExmqJfa-1FcwPya zQU7)IWS{4bd&@&_NGjrs&nF4V=s^kD1Cs4|J3B!!M;s7;_s*xb-hpLL%d3xtgoH4x z>!SLALE3|%x5%*u%KYXO)w9}V9*pf7dORx~G`da%W^HLQZf?a@Ev%H3&h(*d@)#x` zqQ9Mcax`Bns=8~j4HT@Xg(K;^V!^I@*y&o#{-LZ6DYhT}M8;j(4zWU(ldUs_8xE9_ zoZo!P9@}a;{-Z%7!3WBOwc@kgsz=)5SX+EMhHC`@@I4I*qUduPA~O-B7c}oUw7tFU zP$Oh4aUeJ<>Y$#U9_FaK`Qdg36P^@8^gv~0CE88^xPL)Dz`Qm$-B#DuI%9n1_Adhv zA08e)4hR=mp^hv=BBZvTIC*max2SXZtBRWdEKUfK8IJG!+Y2Cc6!?7jkJ)XO0Mmz3 z64gstfNX(J6mctzcf}PD0o#*wOEi)h1C>5!{gcPmdc0ZthZk(bs0u4}6NQcZJ=g3u za6_*Y4@Ug;*Av)b8WNfM)2^uWtPY@i4C9{&2)qM$;({9akS74JScHU*V%AWV`IO$a zr7+v*>{=~0w-B{1!)@ZD=UYf$Nyn(3iMQM4*+1zJDJiL7q^s|Hg{W1eU~s2GwLP@G zF_SME$hr{1_H}?MM)CG^R&=jX5Ch_1ZG~b)9}q&7oi7$BzH%_OG{ZIrKIn*whbj09 zMBJSf5I92kIKF4dbR&;@7a8M~Mn@$1po2Jy(x^z}a@*oTWQ@$r$bM_w6zdxh@CBgK zffz-fbNy~DgP*F`H115$%fl`!+nhi6oJmp>w_IC$WqfJ)D zR*w!bbhbgJk#1>gleciz<>uh1MAG8(Z(D^MfQdmss$1O?YeSUWGLhE!W%B@7E%L=; zYzXtJ`GI;;)4Pb5y9gi4d;$?%HR&3Zd2j*|=lM6^vV5b{Ra4bouzme4{JU{WR-xlI zo`}YqEdEDIn#4^6>IgY+b%LzAYcxQ0E1s<`s_$C}V^9dyP^->LDI}M4-)ep09?JFb z;X{ZYPZX0cI5~-E=9oMjstJk$;WmQ@*t9U|g849{ zXBQTxF56yD{VYjGM@K7SeH;uZfIWemv>E??0&@(z53vgJECUk{tU=bx&jm}qrt1_r zh`27NRo%C6=Yeae9B)oUltGISZvZLbUVeW5?+`n_)YK$Gv?gB(HlrgYOocVOSe({u zlGfL>RcHpq7Tz=R|I)#dS<6WGI!Z;#vk~1`#xKdcv9O?b>EwSTIlNf)N8$Pir``2s zK)g{2HBybSAOAYp)Uu+w420)_TS?a|Ao9J4i3yDJSSN;Mb?NF=5-4V$IQBUc!Akl9 zl(7QODD2H&z@%rbHU0qfZ~{hXrgVdwObG|BVVLn1U@K8nqErTTy`%n7G<->=eKMo$If!)rL|VQQ4hxe{S0DzdU z>3awvnk7xDJfma4l|q;fHKpu)wEy5R)HJr@P~-%)LR2SZlAs0A4(X6kdu1Zx;_h9M z#Z`zI29Pd5EDQa-5b*qYHKcUVq)c;b>*^{;zeU;1{*s9bvS>@AgM4+J=6lN3+p3Wk zOW|Q*EL>b<{q8G_P(Gy!o`SrKhW0;=1;B#^ zK}Gr)WXYmR?}U@`Da+ou0k(F*B$zgFjlPIGhTt*=7fl1W$VmdwHQCeAC%Hs zRx&#NeE`B%fv5vmM2G?6EQf_N2iR#4scsOyvOIS@dK~-RQ4$6)!fP{l5y0mlT=Lm- zx{nFTc<(jP0#SSziUYLUAZt8>{dH&jdwjxw0m zD=dIfAWEMFx&;YH*TT665`&~FAzU?svO!8OcmSa7CzmA-B;)?|7ge~G_#birhy%%# z@86YMqyZIzQ2UJtKpJxKNR)wSa zlZ_!>DN-iDAf=$v1T>^QpB_Y_8!(s~tO7}qMAvi6esy(KAGBSQ{!&TAo@W7nnmw_j zQ)pKKD+)paX}a1$`4HuNOC6+dfRTy-Ls}JNIU)@4La+lbL83vK4`4fj;V{*RM1k+| z2JFu&CPojL2vI~Z6?`CrZq9zD5OJ8IMMOJVj|lf;zX0OYKsZ4>Eh#N81_M;{^(A{f z7ZI@GL`+T?Vra{@mv|&rdLE#Q#eSg*3LHSzumg*?mbf90_28( zUNGbh3aM4>$f@h)5W@MK=Z8t^`oIxGTMCr>?gw~Bsuajp|8R!u7`o~D~x0{gw zx#Gl;U-KVlN9e@O)K-AGmUz%5eYxgv7BN;_Ts);X#EFD0J26IK%N`T^NT`I-Zn^-G zEq7G4)8<}NY#>|_;^Rgv^)mGd5KsN{=TD$7cRWhB*UeC+cQnZv%mP_1OQzA1u5G`I znVo(Su$?@q`upWh;-x@YP!ENz`pgRf8tRUN3Ksg|ZKi1}2h?13@fJ^elt3cx@9+OD z^`xnO9=U`NMD(iTI;#qH1Fs#|_!}ART8!l)WY%LnT5XCx3IE8;vHWuXm%Q9y1QDAn zd0W;Y*t@*wGL-y`gbz;h#zj`(`W?=OObAMWbCJwGWy?A7c8unLv6N&5#z zOn+y43y}R6vy2io+y;O`Hi(JAadANedkNKhWuhgV54V5N`7FJ&`52|j`1p9RFJstL zcRmHgKoQ&F1F6FBW`tqjb}=oysIgf(YVOWMdD`w-|noC%BQcFP0@}S&zL04xt49T90(gV zYIF+p1<~y8y?e5W&E=3h|C{73+1McjvPM*Ya#npuMysiU-m#2kUNG})PU`K*!X(TA zkBTZdh+lc%X2N}aqhT+IEWJcJ{_rbA&j8JI$-zO`&CTr>m( zRyQ^bE1wWUc9#W~eGcN#9ng!_YVP+I3ROR6)EZcK2l!Zl#H<%D4z(;Da$WlEUE;c; z8Ixa-Yt}wkFcy0Oh@n};|3g^}1sF$bOn43uSBTBXxqk~guck(g;)ay_`fCV-PD`z~ z=RhQuiC0$Fc0dc##N;%HW=yCm!|?|^dxjD*f&joIrRfw=1F}Qqp)VyXtR3ZKMaE5l z2xv<|)<$U#1#HM`P&F4!{QPn;;RTx?QQNy80L>(Rz}|rXe7AU^QM?1{=HG4U{>iZ} zB#?GHz|i46vE(Ajty}C1pp_Md5QdhbXRGB_mU5n@VY9utmtWU&IdhbTYI7|$zL z4gh!oD=zZx;I%GbaTMZ`#=G-*Ac}%!a(#jL;K9eBZUF(0W_T#xhp7@^1fO9wDa@2U z*ne7eg@I$iuti+&F;KLD6MWAbI7d%8ik33Zx{r@fA_QIK_bN#((h&=Db6M-|Vu-Y% z<-4;l&$9O!lo{kG*^I~gaI6FZuLv(^-V)s)*O?L;;1v0w%-}We;6+^$j?u{9m*c!dOs)0RQwjJe;O< zb?_kIG9t)v$B_mKL?cuyufaT*M8m`t_!6v8P@Jf}N(PYxvaKJJq>DbRC?r28E5>9( zng9u;e6W~{4$4S?3$tJrU=b1Nup_%DEiDa_jX~A3qrjLVJk^zN6$I`m#8Z|-DWj~c zj68lC+76IJ5#0x|0YovbZ88gR6}YIExCjAX*j#9DhFmxT#*G(2L(76i4hBIgsCknF zjsmQKZF{FNS`>0K(faaqJqRQ!tYFS|egivb@MDwIXQbvry(5#@d>jHQMEqQrqZ?Lb zThz#4M8xdo1wk(H-Md=581IbIbrQqsfC}VX01o#Ks5C(2g|)6pBhq*@!WaaO7vbSP zNF3tkCWqqL7hpXyJ~%JjL(zU~V+BDE{Jw*rj`&F=x8ThjFy=@Y1)7ym&vPsHR@gT< z5@BFc29ZMuGyxNf`~^jE9<}xLpJ5R<7dcwxn6{FDr=bRXV6#Ar&?GCxai5z8Vkg}r z?l~$X0M8>k$m;q!QnvK~M~0Re10pX3SRA_map=maiHV6MrKftItOElPJ6-73WNHjtjyE9rd!hiKsuM>DX)shM2XqQtOJ z*W0EK$VmirA#AA`&=n5u0TgQ{jbzbNAyJnS2kZ@YBf26unCf-ZBkDGQ zA)o|LGHg`jXq9E1YO#ShCxFBI2f((HYQ2$dRDbs!7@UKF4~4`W|LK!D zjtX_Ou!B?ruCU^X{To15B)oaEPtR>`|0$)|fFD0@V&!$AX9+M^1LuJ-0+nSi_-Q${ z@H9bV+hy-r1-$z_dzZgKtM2pNa{x9PDI3g`)D96w2GZRHbV){ zd*{mm*xp|kCkV_I6t7&#>{tW5V9=JP0ag$>Q&SG8Izh8|a^_Z&K9DBJ%!jlh*v+iK zvx7O?X)MMu({AEsGN(8oV2D}!XNnidL16a=-3njM2{cJO29pUY&cH|S4Hp6y<+DP< z!O@UaQP2P=T^l3IbdiLZm=AM&UI-9(+^&#>nL39{%UA}Bs`{D#OkJI&wxaKlXPoOYLD|1gi>{>#E>32v3{xsBM9{BDFf>13rj-khF z^87JzjcS?5DAd+FpvqVigKrV}dbIx86><{qgsu(Rp`6w&y2VBJ(8LyKEkU~UZjT01 zZ>6(R9H zD4Stk=s8kZXr(aog(wD0(ls1aijl4D144uAYn^F=JuC8sM&NQ~-|Gkxog7ZcF$mr;Cwogol2bJn# zWOJ`C+*_%Q`KRkcWeDI@L9{Hg)H4>&iv$atp(+j_r3{w*zg2rDQ=uvgZG2bpw54ATqij&5499P5QhbPHOZZ2cZ!@odiNuKT&wGH$xm0k)%3@xg&T(5Z*)p5M=K^t!GH} z?#zCRx*MJ5?y<1g(qHDrCTqp>8QdLd`uAT#%MM<{9?<^RN`g?av*+ErY<=!4y{1jc z*+Yn!-L)6FE{;EhdPBp#2THo{fW~v6IN#Zt@jTm;fp3$cyK>I*o z0jAhCe+3|e>+)3A#wsZBn`JvIJ1K%Q)Lfb>zsn!3wGQ}A(SZXPagh0q3sCgKlv&2G z-%vm-&SZPWKi!xGHbaDfmD!P51dPj1gp3;*5LXNg4H6N+a1a3gwsJ7k@RTebe)Q-O ztZ~Gm1E}7M0cUf@Zu~m|knK=muC7mJ+|bsZnw8LV9yuxq9ls%L$QgY}Muq^j;rKAQ z8~_xHWr7b4fNFx{OdrB83N!^8g?8`1*(52&J$K(&M&uiwGhUwQM}E=)05^C(8nte$ zf_XB%vHLXeo?zIj08)_>sADiopkfc0(4_l-Gx!WD_kjc5$<>t=Y7lTNeD>!lJpk1; zA|H`TQaBaHqxT%-o7Zsu)#Yw03vTH@mXc(eKb8`3|0A0Ol$uBgfOeHRfPP)tx*ysA zF`*LyEoHw}3>IHCHMLWYs6&*J^6M2K?~1Jjg1G>WRr2G0{{Pt-ix{($on6z<|dn5vCSoe=)=#BwPIMD-qwbXOB6zIPJGqEa64U?r?AjM0&W`r?{G9!0tL(-f=%AQkAfOHg zUV03OS-a2B~{0e-V4eVi-)2C~H z&)c4o5BZ*Fp>_QgF98%6-XPCI0Sn5cM9bE)%8GI3sj1W{1)!v6j)Q0nZJ8BN^bufC zEI2{ch;OSy?h*GzO4Pmrybct>h|9q;LFPf^7qXw{L30ww&hb$Hr~@$%+5{mS2}9@x z{2JnTpuDu6_;C`-lsj;t5ZX^(dd@(MArh(2bw(1Im4KRprh(Hy7eR`A&xa>BK2>-(0fYtN8eS8do2y~iE&quykG$_!RNPr=!1RMskKIDwN9-B^6(8UB4 z26auA@l0RIczXsjw00r(9kxzqbpFXv>DAGC3+U_vGsPDex#RMOVPg&`zg)`}h*{HVZWdY6V4;p5URX-Cn zQX?lcs0)W^Xn=C^1GYpK9)kj9FYLdhNoti)H1_?aAi7&3mm}gXvp;@BCU2m4A&!!P zjfw*D03sYAtfU(5CnQV&?F7o+qd0Nknvq~Du|A%dL?e{`t@|*HA#627wLvrmefdJc zS}eF|FhmQVh7JuGdO&a(&~&W?>VH_eL95gu%s;Hjh^yvfmj^CL+3wwIk4dviCGxP`nm;h7_LOTG6*1)$nc(MyhdA9%j z?+=7=ZPKz8#FvFBzr_|8@ns=&|2+x{3TnO2;H*&IckE$9T+#Gn=8Mki`{KC6NnJ=dmXbpqlxC@dFl+@J&<bO0%B3#|j}A6pVNvzoFeO;+wNHG%`@v=>5xL6Y0PK_ge+}#dn}*k=Y9JQ#C|a z)YdBj?P4fegZ4Z0mysiwsjf%x?+0uDc@Ta))+gAJSL7fK_eBV8=;IKB5TNngUQ3=} zY5HI{-6e$jRh6XH*pMj@BpP7rWz*Gwk6{$C8Qceur*~Rp_enr%GvRE+U>kKQ=^Nw` z1v`AV_=6$wlReGDQy<_8;{i{8a$DnvzME&r&C1S>!WBK^20%g*hn?s zI?n8J^cn`2#4a+47rxnL6j7rF>;JYo7nf7>r_OhpTQ}7E=Y*URN z0gH5MPIHM*I!_Wn=P+OQikgN};LkG89rG1{3S^l1SWi=3r)_%|@KH#w?3m7yrbnlsV-gl$IUqsQms6V^@Z`z9fMe&#VGJ&T^BRH&dS4|?oe~)LDrj!M zk*3ZEoHi}&^GfiwfdyQhQ#}&{9+XzxA?@?p78o#0zP~1b1@i>t?js;aJmswa1dk#B ze$WTj*{g5&fbOlIIMeA%QV4x!<9~<*F|ZTL-n<#oM>lK;S{_LNJZ%N}%pGQ;_>G>m zEM(l;Hjpfzg}xa;I)pA`!)HN&sfLrz6u5(u2?n5E$$Y(1H#z{rbq-NWcN!ecx^mu6 zPohRW=&`~#lJ*L;6+ZvS0Uk8h9i;5xU$%Zk)K}C$`%tvoxq#QT2AaEtVot4nKp%uN zTk1sr4>Pm<8Syf2=)i3aJ-DKbto8f|nSlz|JVATD$ls4L*bqE$051u-bqe30##eYv zAi?(JwJ=EO?2C#gm@8i@9)SmfL4JtomnR|Aw>?wU^mjrzPIj2A9`C|K8EMVFSa z`EA`*>{R6?~VE&)*3QEk?|txiOvC%dsL`+um`Wwgc?We(gyT>*!EdV5X zqS^j}l%sMsA_SAPSf)CsvTCb=FYwHr<_;pKCe_UzC$9PZ9QNZ@RrNOeVXFb@x}vG6 zX~ND|;v@k10pZ`@wq!jzZWo}(*%ax(s=jpT($o4eHe;RA((RrJe)>T4RH2pYa2uE& zSj*d!;94XBrTi$YzspbD{?|*RP+$nahBNHK2-)}S_y&g~T;IG(c&9mf{D4@#y%f&_ zttJIH!}-RrqZ#<;{HS<&KY0RjyYkHL(}I4Wrv-s$4`zlLzhEw2+^-(YA_tb;_l|_S zOM(qjFnICW#2>qn?sl=@--oV|Zdm>hUf*H2sH#Ss#qku>>7ARZts`=-ezWGQepWFH3gokm$+O$?vL%md--KEVe9(pKl3 z(c{n3!;S{`MQ>dfDcZqhIj_+*@N970Mze$rwMzK@Tb&JFHe`JP1c z{V~l}TuD#QbHBS@=u5r?A^d5LTZZyJSim4@g6H-PGLUE@=aOlxV-O!bDPcERcJvwn zq48L!y>UQMOZM|z;b8}{KJ)pDaAd5y+C`TaMxwAFCp(I_0R@%T_1Yu|jpWpKirijU zSXvrWgu{B;7TQ!H8bLsTf`?V>wui3g2Q-z4GERpd<`I33z7}THDCVASTRcyOG%W9< z+#9EHsXAXLXocEkPON6R(8NTS(pVwg!=%Dx=; z>d|~L12y$i0Q(@wDB_=rgYItFw4t|!Uz3x%8+<@n>e1U3U+Ox&w|gSg)Y_i*T(9X? zh(&{zYE^(e@)gyLa{>smh{vE(iGA zY{^EkQ)L;_#&FyO;Imu0uo!=!2YI2X88+3_7#UeI_fYr5!G-L@-kf>Cc?GnP9M%XldMynwl`g`=tx>hik2s*qY#&IR>JNr zr}BwTu>6QJ+1RfKSB3V`IrNo<@Rewv)R~2s%q&^j3Woi?6&#@rHYu9(>?AE04Dbi( z{{GuWeR0-9A@$COgQcE@JM&)NFm#=7S;$Vz>d7#JM-JUmEDGRG#uJQdYS1v$z%6x3 z5l=R*-3Dz42!Ridgln|BErJ~7P(!`{!!J#o2Ddr1QlJPoplbi0Nv9^GYu2K&*sz zvD1wi5ZhQ1To>sDsq?oBEH<`#ynA#=i^eW9>n}e#Dk_$FTt1}UKL*!RLh*n)L-y;S z+?-76y;nj;oSODi-qMQO)3ba{+cU&Dmd#Hf9npd&g{%YM62&KsTPOZR2g=|V9hgJ6XGh^1%)e4)XJG^aa{g24wNHMH)K@un}jN(Y+m9i#rX4gwFkc7)|qYudmk#AbhR^SVZdfhMtsmO5_&80 zSa}7b8Q<&MG@LP##AOybe$OqmUSBIx>-cDYaWOwsT8mX4J*eAEJ%t;Zh%R%`q2!4=2 zd>4G`{-^`vC~Vm74UUb4gy>+Sy#Y^m6h9f{y=u-GIQz+IjYG_x|3D()(ibmXomrQU z4kk+uti`S4M{_2HF#->d)jLz?zr=|8D8`X~SvTs}pL&v!<+gOHxFzjGSDwp}xW!}M zFFk7vt~MwK9BU@B%Aa_;NGfnw!?;D>%9jBYvs(_oQC9ke?7I&C?zRbdiuJsjO z+NqffBwY)(ZT-ZHxWkTR_((50G5G#P?OC`)6_uZo`TZp_;@#FdfmtL64p_UKbahM` z@#8jLG@WnD{_*k5$&*zRo4$YmuZ7z>iV-0AV%3pjtClx2S^R^+Cur;8il$)2CfyO` z(-NfHJKHwfUu#l_de-VYJZBGJzvjm1_hQeEe%o|?B6mYS@73JmOCg)lO*!-K(qmYr zb2m9``jadymF5c(MNUV#_55n$vIDN&9-OQ5w?9#TnB}0iVe3j1<1#(jr8iM62EtJ` zo5TH1BUOd(Rw{Q69cFlv;GOvTGzsUk{n(4xSloR19&D=9@lbfimm&QrzMmg7j!vH2 zf!@Z3{-}eO|Q0#YPD@)eW&JEP-fjn_u5GWD+gDi*7>LYKA@ z7riM?&c2=Lx%K2`bJdN!>w=~IpU9ddbdJpkn)&uUmi|1NE}rSJb}n<}p24KU9p1ab ztKFjCU&MwH9A9WT*ftaDS=PADZCFQkl-hsG{fdl>uA-9CWfzx1UY$Y6UC=lMxvOUb zFK|LY41TdKVNYMPy;{E<_f`K1XT37jQKPG&UvA}^mFvHtq@wlhU#?2HK5_V+>PL>) z6xF@rp6ZXntc0Fag{)o9-l+RaR$2eJ!*(IXO6c?IkM^z%?P*VIWhqV6cjTJ5m04H6m5#3%g0IcBTj@8?+nfA&%>-Ngz~>r;it!3bKIfj}b`zphz?)ub@Ga$y`lg;~ zPBzN3O@7aRf7x_URTP=tr5`bO8(x*{^G;;p%Utm}KssAf(J@3TV36|JxvwzPE5>zs zV4_QCZi_D<~2EXFVxIcKLbC#U08xR$PO#cBu>51_fi)tBR7$t@aXHArB71 z#ov#fTSN_oGnNg&z29lfp%rw`KX~eTgf~v7OaJSX{HqfE{q&{t5}VgIUotu?oj;Gk zrbafdl3TSt);w~Mj{zrxG9W1#^XE}{E1`bX)y$q1@V|`yc?@^cUlTWT>q4DT`+HJ z{_Oup*LT2U-M4-JQDmfL3nd{V8QG(kJj^A;7kMBVLf!F&&j*9SOd;(RD5@Cyb-bV&}wkTDf zR-aO5heJm$IFx(`&tTJ3-=uV})wQ&@!ltW&2sy_rP6i)3dyhUx30J|_Vb;GbJG=KYkN`p(6E?tS%)&GU=I~%nP zp%0NS515I?Lo|zB&fL%3!-gMEbUJ1J-7x!{h=>-JY=u{DPCfpj!j0~%h3_7vNxY%; zVut1K^O72ZyJ0$lVGDihlS_0YhN*k>mCykOwfupkE`yM;K1@xUZb1!_Om@+W^CFZ+Oo3gw$&HUHl3Jj z?-G!;8Y@`bLl0&69188|ci@x#r)^hLii+TBc7G61QMSKQQ$ZqLaE(QnIEPDQcWY{u z4>yN?JfLdG1=kst5;X2k2PeIIBvB1rLydhmt#EW?L~80+!QN=JcbLAbuAcjuXim18 zhFvT+GLnUuJ)LT!e|PY_VR(uRYEp>T@A8F;QeHzh-!s1P->Q6Dm11DcVPIko=3n^g zbQFUJJlfzc;BV6XIvg(0TFeMV84CNX`|Ys9{yEQ~l-%2UZ)?AT#FxH-G4Q4`2SwdJ zs*~6T80@1nTw<6wBY5Yo&Gls7PhUR>tuN+>q1bhb?G_By4}^3>%Ac$~s+-Yd{uyBP zTII9HSLMaDLDVXA7`;yDu!c_QmkM?N3!!jocUqa-b~Fw7d)Ggz|8x648pC&rweGuX z{c{zA0&Ams;x4BPK399R7nt@}pOF6r2_^M>u92Sm%6#N7@uw5bWA%qw9gLX*yClwn)CBz0jcHgvD+!$@FHXGhw zINOS=DtJ-lHaJ6gC%QyTzUc&c9@# zJoT;4H(F?2>HLZUx+v#ROC_t=8q*%!onkfoTzl>+H)SimPy=-mYl8Mc*w?v2-M;$U zum7xYOlLldt#2>&sTU$Oxe;kBkkW%>jQE_`F~W&Sq%60nwf`P6!Ip@B{e35?+xEB8 zO0165@a(|T5ySQhi7W5!n5{fGvo`yalvfz-c{zfdFj*AxQ^( zg@Nq)3bzZZc!ZCcsQ*O2V%3W@yZGywCm#c<0b6TyL5kM&rLk6)^hn!^Csn@Jyau!A zyRCFyFcnze=&4|0o>4m8Upc^te6?-%A)6JUv82wF4i?g8<`N*&4~>1SFSJ-+`$`|Q z6zziL)2BaOxoX1Ul0NV}pR{}QX$cR4h~_Q&dTVbas71H+mN=wY?@AFD+U@?aKYOrx zq%B5@6uEil))A!aKGxZ*a>;XkxQJ*(>HX8wb+;4uZ)ZK!j2{i;pm<6!K#ocsyVCA8 zB+djc&(#lUiW?E9s%M%+S0u7e59JH_3>DD_SLpd0$_C*f_uI9fkY|YDBPMs=KBqln zYN*owt+(7>xxoIoo{ev7Gp4ox>vN+4CpwBgC73fvjHD|aT>FRZ6+>@DFoej5pHJvt zRmuO$1vr6+z={9Dc!aB_ZN2mgHf@XD6(fSYi$AF)X?fJedXtjjfoo%dt3 zny3Sw>)vb|HjX!GFUPInJ<{R4`|%j4;nx2}1yP4XrRDY`> zf;A`zLo7UH*VUo*B^iWE$3?U73($uvRU4f7q&xX znnSsNV8{255tCnE-LM`1(h&dn`y+fLIm|v^=e)x7)sNJlL!*OyhIW!1vy^Bg?8qd& z4y4od4j6_l_ZjuPCS?W8JCA(3eq9qDh|sfAA=<=+2-3x=AwQ)oHahs!(S7Kn|M}*- zaX3$398P`l4pds#QmCs2eD7jH9g~}(B%=@#+S{wyl*0D;p#WX3gi_>$S2@6)|4giT z=nRXFuIOL(*o{xjEk#MX`iut|@^O0w33S&`_16#owXuaL_$d4T>nsUXL zCxx1}@W?|5T}-_3h%lF5l7Hc}?i7=8}GxTxgIuZ(HC3FTMM zd^sF&EV?N^$%w>;X1)64sqarq#>dxkpsQkn!JXZoZ@#Hv_m18(m`lxgc}_ag_#V4{hhXeh^W^ACS91ZjaAEM-yHyiV@ZDqAz$5S= ztIfdJ7}oE;6JDMoF54aCberk(0B4))uc~DeI7qmt_O-Db z`C_gijHyc}D-K3IV=CPkIkVDbu$krHQ5xy_W6=no0AKfV&kJp#u}LYRgj9|V#@^tx zo=oNqO|DdpFXVj&*IHA<&I_|28)?-&il|UhMsTVZ#5&BDzDR>vMYXiKUgJ{G?9!Ch zpMNmL0reughwwEOc_}$`qkTy1<)jXF)TF7*85}K52R1T{R#vwi(LPZRZAAX7BLVo{ z-?Hg@P7?^SfimMze%O^%SIqhmF7v3vcUhx=9u`1M3KJmthZO8ez&4^Of_ey1aWPfw+M4m-IiE__2lhVHTY3>oL z=aMx$zZ>F(j25b$acx5UtlHrnW-D0LK84q@stsD7$F|S10 zL^np5oIF?KC2^L!+dEliYZgWVZlCachPTuTb^^kfLg5J8=Fy1ERhEBkhr=)1;a#Z| zV=!&L3Tyk+#B1u51C@1#ZQ{s<1F^kTYMu|vo-cAFDw=B4kw-qa;P4cm0>YjL8;q!1 z=^)stu@W?bRtdC9`NJYIGR3cfF$O!f!+wU}oh4m%gu5QD@)i3()M$e-D}m$t9I{6O zHQ}wKZOKr>St)n2Pq!j(WYFcSl;3i`_vOu2gL$3d_4y9XU+#(IiMQX}$dzloVl;Ng z|CzsN3`SE^m?JVPFo4nPSXP%OgK_gjTnF`wV%_MoDwa5cC@(!Du3`JVBRevn#Pf#Q-c;%Qg$o4h`d-KDf~n-8 zJP-0u?tUT_cGx{8886D%lc`@5SaAU=&vMU~%9n571a9+m%inwSaBXh*1iT-F>Z*1t z*l@ShZZ&oWT{`G&3cbmiI*c50b+854A6Rziei+j>Xy9CaR;)Ie;1MzFuJ;f9G)@q9 zuR!`r#2oDRg3|!%@l%d=i)D||on6#r{aT`-5&6MB;kE6r)X&x!@nu!v6f!+4?p3vD zG|3ekycd8oTAAkQD3I0O^_g}ZI2sdBM^@9fYMMPiVC;rn5Y#L+S1eE#8(i2rkO-^e zk2L65tDElnMD4S?C4c9=B(W5Bo0iBBXLRqN!)fI~gSpB!7zz*D&&lDBrR zB~F|^hbw97cO1K3o^VBUA>C6F*|8c)-Is9_XO0y|*ooos>eu}q4LV^o{A(+)(&sqx zav95pmvc)=p+1H9g6iVF!}PDu{I3^T65E#~*|pMHx_KUiaYQiI!Eu8i@rsPWuwv(m z%RVyta15J)_6s9GhL$#ofy&MY`I3V;bTX*{dDj7T1KguDPy#|mXV1Yotk3% zg<%a>D0I)#uVe)B3j4j3lc4zs@FO59@%A0T<=0{lS8ie{p?U;TD6L0J4r#4V$1>0Hv1($zPm@)#Dvs=;sTafSSN7( zc28`Mwd5)qxHsCxuCvE~bmn`7H)F%ptaw;T;LUP=|9rzCl02(z@}GCrvL7}RmJQ77 zI++dO9UnILO}3QCaE+7KDf2p2id*OwyU_k9+@G)OiT$Gq${ieOS(ZaGC(s&zuHn+p zqVT$NFHUb~J&2MMb$bBYbob0sFYmqL&QA?jsSf9|iGnn@+Xv4BcL*Iw_zqzI-PVVPKFY@{TK?~&MkdNTWaUIY&*p?|EQarV3<&Cq|JJ2OWH*EL#tmwqQ+0T_>c^X>z^nKH zfamd1`EX_v|GrAa9)IlE@6vNI3Q9_HrS})mrUy_OTIu@ZbrWe(#e-ghsC*C%G0OQJ zxaabv=k2Giah!730NWFga2+;-Oos4^0;8e7JnP&(-Yjrz<(!-*#rA*?@B%2fqiIk8zyNW&qGfacoR6JKL#@7sd!I|mi z&692VW&S^28l-EBp2-rjv@N9?eMUKAxbTcS zDQmsKmznev2KT1z_(AD?Bcw-p}-h<7RwLE4bt1DCe}8lX&Jx z(es&bIm7MrI^mO^WC;o9HAQSmHg?m^E|YNMDXgoX17Xbw$S~E5 zX=T~*%M*Jge_^CUuw|kE^?QbQtk0%>&gEs#=fRMU9B5I?0cHM)>N5Ur)?q(5$dxwO z)~Tl0R!^1Ztqxozd!VYKaSOoO5}76R?KEv4x7a<7RMj(164;xz^-bDu1&u2^lF^8K zbK&^t!Sn0e8jsxALIIP}mMcB)Qs-s#O6qyf(57qV&cscqlsDCErbt_+H17V9yY+xB zh?*yasc_*2Hf$iFJ}JzgCvH!(@VV_-mTZy!0E&-O6HtZGRdY}Cd8vh-a- zv%Qpf7KN7+EtVo;JAnyeM$lC|TXnCVoHY5n(=JdHuRHc?n&l>H&4*feLv8+`l5hj@ z1xDliVDTAnv2flzwUDl(+m192o+y4F>8wA|CahtE($K*OU_91!_#3EX!QhFM;?mtC zK>d-0coHBCo&+=oxYZB4Qq@!LeL0Ov_;UL~fUF4QEGBS|k>0GVJZIi<e*L=)S5u0N zaDESXP@E-4Q?U3Iq0!fI)qEXu261t}@TfEbpXtFN9wDra| z=S6z}GIBS~8FEgWY<}5#iyi z;C-DW6nD!+H)MaOwC~#JRQJCw{4WK)o^zi5!U`0afy}iB7~o|&_eVtI_UmFL15z4q zupd-;Z;CCFF{WxVhN*iVA&ttAO$fA$5pg|*EIlYU9W`wduUQ|lH&rdSFrFXGW$L&X zG`64f$-0wMwTyi%Ysju71pII4!kBqy$WNa>jfXVfx32my%w&kO4S4x#8H;yP{prkz zJEOS6Ssp2UqT3o7@^&gGB^L(?jacv05Me8xM$Gwuhsr|js1e&&gL?lMo+HdzstN2H zICC$(Zgj`W4OnQCdDJ14xmfYiZYpd7K0Md`U#uCWc{a?<%V>lVyc4pZyHu_4LM=yc zygm#xfYR;g?k9TfAoy3GkwAZ?Q#*LrsK9~g1yp)4p(h2aBhc0Q!e;&@XmKq!;)Asrx>-BqSY)8UIch_KK1(Qx zgdwR;^q0e4@p~pP;`&BS2m+ z4t`_XlkeNtjV@TM^3~J5;xx}Pu&Iw@tjZ&<;WgNtqM==-B=qj5T#q{dL~b|RuJ1ug zYETjX)UtYu3P3Q`kNB7;n{5~0@w~d}kRw&VCMC`T>N>a>P{Pia)DC5>UN!6H1v2ER zS4yaxHEMAHQvK=vd`^ygDZb#}VF>oo!kGQCVfW(5b>c>k59fh<0clIJz@_W>`cPWH zvYQOG5CoPW$Zle-!rDDP#srFI-TQJE)m%f-0(_I1nL~w~X^+5K)Z1dmr#|LlK^A7n z6RBL3uxmFmY10jQ=NQ#rF;Z+Azc82H*_7%L`^?4G_GfBvXGO9_PnGSCk#+n_#5ci+ z)s((-dE5^tZUbjxZ-IAVr}>#znn1BS2^PLUew~TEA;~huHUzXe#f9E%0#NY_Li)}# z;G`x%l!OP{go2@A;zG$Opima+KE7CC~-zT!L=MTScL z60bU^l6I05gIQ@r7CFnoe)p!zZtV?8wNgz2mLsg!@|W^%$}pF>%`o4!>tFOn4K~0! z1-q6gR$%}a5KXiI@+KNiqZMhtI4FYhWP#l2-(gk@5ef(bWW{O_F#!=A4<;9IBa59o z{A*K84?55x^3`uQgY)slcIyJ63=+h3TUXx&-ehBads6i-mZbdw#5aK3E~b59p+CQL zssLEZsLrO(X8g;`z_K~0%{H-?=(H3VxRMNV01#Kp{>8*!w(HcYe%$(WPNHxB>4WDt z^>Y+%9C?g(i8&D4_2ZwMPN$Es6Co8kBT{X7XtVquf?7zoqkD6XmDrwtQm4wz*GIJW zv6}u#VXcP(&O-)9+lUBHb570b^Wfe;UoLY;2i~+g%@QEho`_A;K>-NJ73&z?Tby4N z&(<$g>g-#6;T+f2{UYr$5Xn$3)1L(h4gyGvgp%V(aNT40;zv3o^n2p}9}XHIOn_c& z(aD8b>%Kl)88=bEG3TXw5UN)>oZI_#%QV^Ob1hk2Nb&6@rvb8AO?_a#a{ z46h!5-a$b{of1F-FA;Ca0&M@>67TtM-%?Z;P9+-!uJ8~OKKZ+aCMPGC0}D(E_GGeMq%?PfSLZC(+Tn)4omQHFqXD=^(Jt6MZtzwy5R7C3BAkIu29WPGqya zuIGum(IiZf#E|>#3h5duh9$Y?(6{2&m$#j;znyk3L@>$>B{R8tZp*wm0Q-B$)4F@O z>Kgm~>WfHKOjg6_oGrCcJC+C!xj?vH^(u+& z$8IYj;Hfu&hh)%}s7~`Emo$j#1*{&3E3r}`Uq-l~ccPIyG5g#X!T3KT91q|gSZ*zw zP?}QwLw`?`YXhLD1^2#=ir5|Jc3AYi=>)@{ckl+JAh#71{Q9hba0x%CdMD{goGQM1 z(u16a00E%zMxnC&@A_8l=^vj(9+dT+)V~vLjmzG97Ao&>D`;rvK}FZetTIg^z-53g z)6n28kB>xV^!wIlRr*U*GWo-omv1Q^q{^%R&FcP=-KUjJk8VSBS^}_-_KBRLKZ^or zkUCPd%1N3cIi8b7Wg4zcsi7G}D;b0@jr%4pi3Tw5khj%Xay5!$5xj>Sy|6xcY znYxwFzj>EHIuQXJ*`w`h$qb?8_N$RKJ5=2I!CI^QQi^t%zPpj~_dr77C^Ue&3 z6<#+pI|f^bAbpp`d~ea}RJpDI)gn8VIJYu7Ns%~>cOMUVCqRg4*qhjJLiZ`I z(fM*cl1!6D|5&?|MDl&QmDmt~O`7r4wV%6>|3Jt#glLf`c4{V0(i1OPDPA_Bi4vWK zpdL_{Z5!(TO4XtqY0-6QcT;cOWvPpdcNucj55FI)y4NAUG=E@`q&7h1mewkdJNp)* z2_8S8w!LhCqL+Z+R`GV|^b=O> zRk`u*7k0a0MrH$v8J!L9@35AQtUS?a#r=Nuq*yfN<@)lA5ljDi?A06SqOSCK+Lc6X zppLRKPZ@Igu*$wFqEPqy&a=7~_msIB5+Fjf3s0Xs`8#YX&K;jMX&m=h4tOXA2ENVi zGVqeUni$@`ngPhePPp8a6g&+e=X_*lH#u0OLXX{V{js+PwsJGOQ5(KC9G`BZP)Ek;gUj z49^qd=t5p!yk$7}gT_lVPYB%!CR^^Efc=Hkep%nf^XJS@gU5nZ!%ylm(*a7EfDNoj zSvFJ5!xT!0uFnRV^Xgv!0G*jsHu3J$TbmCDPH2Ahl1yYKHEQ|5`||wx#X<8yjcv(0 z<#XXD?hjywLa$2@4pi9gZFss(em8yju&oM~j#mt;kAcjZsFm)jbZ1ZW*!)w+BA?X~ zYcHqgcc*doQjLVfet6g47CK$_>EAkozf15V%M(MvtwRCayUo4d*iDZ%fqQ8>$72Uv zzUkXz60Bx&U|`-{$LXuid<#(dQe8uH#RC~@i*fMWO8)%GqG0djDb;pPIA@!*k>BwDpBtDo`0KAepaun zSUp#0X}h@{uW>i_pgC)5?AHv4$b+LY!7?0%lmkP0%-W_tI{T7M_Z^MLtaB5t%|8~= z4|{Sw(*DZE5f}q%^^=v1%tpczQb3Cfo9}kNPF2|gIzu!ou1fSN>GpVeW(JfzUTm7X@D@(t z$Wg)s<-!WL!rPoItQQkax*C2IdP+HMew6sh|1&|8%d8`z*m@gXvspagNMug3Tklu* z5^>~1K4^9rY8IMv3tA5xfjym-R`Joa?u^miY)G|U z^O~=*cpZ%65MKveg!F)o^@kLW`)zv99dJ?Y8`vCnDge1U&d5W$%gOugx-X74PbE3$ zb_;vWU-|5{dJ#6OzDM>0_^gWWU zA}E{$B~{U&D`5aB?L51;buVP!3us|focC$!f+*^@TcrkUc3^hYGuzBu*twp>I=l)q z#pOiBDCO8)%fQAc2v-paGrgSfxWQ~s7E)0j?e)i{7nZJ)ridBE?D26P5`AnO>dgeI z+3Dx+=s&JAENGp(Ht&O6d%8ktzo|K2$wSWnmB)n%`7pRQaZ;U~0JJO@8T!nL{7d7$UEAhuSzAUoH!nTCsLBSs9vOc*IPr{cAtr)b-CjY#u#zdZ%p zB=L2&%Q__n^!n?sQZ@M;FCiafvQPKAnlWvM%@dtly>}NEQNhH|)&kG*4$<#FU&4zj zTlR!8GvcSi`FNaG2lgevppff* z<6JT9QL)^$K85DfgWh4-8MnYJ&=-B;P`mOk!gkoBiO_~e^;~hcMr9&K4tx?BC5x=H z+u_DNMrB`g=SO^U_`=V~%9?w4&n0|J_lynRj`4d$=ANo;+MCaus2p$|Vkl>q` zuY2NLmiD}qpIf67Jnzrw_6v%{w>_^^`cR*A^`xud<$;ATNgYZ+=?lE$~L@lF7 zM=*tn>_rX>B>mn$+ZMgx1zs2?N1#m8*6fhU%eWmWah(rcrEY&%zc~tGl*;tIx<#W$ zVnou&;HnZ0G3eY)n#-|~uUIY(yw1_w-^sf%pRG9{8zq)M69VLnvF#TvYV?;y@jzeCz_+4DwTzgwqO39YVFrODcc9>M~45iiSM}5oK z>7x_wA}~Bdo?d~Nbp_!%np?l|**LF4EFB3B1M8t(e=|N|02&>Nh)wm{!!#(bh!6!AS*N7{nCjUA2P`}ukcQ+??IQP zQBCB!u=j>QB8e>E))RKKYnQ~=eoLpQ=CcAbY1(NYQOTV(x>*(;=s!Rl$VKs-!P5mn zfQ)eQZHUhm+Px3#9CujHAisZPYkKvss{spwJ@xS=qsrP|1tZp|Cm=vxEt z`YTuy!pg@wx;`O^X!&RE`d6=3K47XOY46xt7z+I#L= za0e+vF>$iPf0Zc_Adrl=eSzi{|L z{tT!{XO<%Br2>e-Gk`ZnVar_w+TA6vYxn?KUpMgf2IYs{=F&qH*c%-k zrMYTB0W7HBUH}>W5 znJ~Ovk0ow1%s6lrXahA?Lx~tDn)4QamVAFVa$-O9A+K~tuA{PytlafTK$1~A`Ar4IZ-bXsm#*VZe6?;6 zYi+$Oy%JnQ`uE(2FOS0^i4Ho?;GHj?Z=YFVTizV2Xo_`5i(yD| zye+!qob)L1>23PamKpNmQSB2-Za#M?^WNIG;h##6{GY6Uf=9jX3!EgKYva zSO7JE>iZOcMOy;nW}phXOwMv!8;q&vkWmRNW5SpUw*r07;z##Jr=U zV=zDsrBGAeT<#g`NRam|=SKmnz(D^9P?_I&N`i-QXk?Nh$4E(0>uxlO`%bJVCG0z- z-|-pSfr1`&ZAYyzn|Af=wP0o+$0Q>waM3hj0P&(!ACz4E^ zVtjz)phf__0CkK;^9LZE!EU~n7xi02EuJCB0e#D}jogn5Gc)T0FNZ?5z;{@WB;zK3@>1-b(NT0Mk)H=!H3k|5&F1 zmQnE}9?illq~Li&QfFxI(e!5Nr3_80IXSA{&-wP-Nwk|68Kj#^B}N|a{XE5Jb^ZIz z9qZRD31)7hyCFfHyqP5qKR@>5l(^Njn^U91qd8})+h1jqmDk?&S*8&SU z@{k`6kL5KCMkdPr$38;*^4#^OB*GrbO_fH7FymC4)BZ*JN9ZoDe2H^|9QXXII@&Esv zP<-$1R9~HVq-6|aAQ-z8>jlJ_rNV{}Tz#H{hfRr9iT(JqPF^T`CHs%una0M2+{!rF z6hRsSo2RmdXz?y%!RV)!E0btKY&4vU6M46PO--OCN-{FN*5j5cC_HxLkCoQ)!UFu% zzu*1{{te9oyzJ&pyUj%@l*i57bO27vx;`bb(>8ydR`2-^mAR{7j~xEjpQ@nSgkJyv zGE>ceNfqH){4X&xXf&?SZJoc5{)WWIw<3+f2kw6$U3Wj-O3=(U^!O*WPzfMZ71;ft zOevZStV%e%4O|2JSdfF;iKxyAgveb0m4RrtXj`9?jKzu!HPZSXnd&^xyr=L|XAvhe zsG)G0XK{9p<@<7h>4Zfoc;{{HyZ6PyhRtCh!g+hq1y%h0hyR9trw|H0s&qx^_@E@b zLbH-bE|I+-Q~vpPMbi#kLif~WT76xN2ps2!m(;xPlWF)mPTbRau)7?Tt>NXDlj;n! zhwu=p;JSxjoyic8fH}nEnj0JcCD#HLp79>}K1u`Gqa;_AcgoYtihd>hIlUftPt?1n!)4!w!_|GYwnO@HR+2=#7nC#B?xFRZ3nmx{7h z(AF{zC?khTb?%ZipG^Ba+o^)Zcj(9NH*OKVGRN~aGbMGlo2gk>u~{oU1r*ZeXteBV zoj2vg2{`&d690M7MYqWA+hX48e}8*X4X`a>^M~315v}{(ybsc)xdD^kve%zLbq?Zi z5!Jd6Jpc0xoul*=QDwT4l8bQUK*`48Qy8ocaOB#|tze4gSq+>=N?7V!Eno17g zYe$kgj>)RV5H{wJSw1P>k+B4SfJj9d7D3|IPz^e8>JLbWkIO|Z)-2a{@>Co0UbuRZ zmNTlQc9wEgN3z=hDVVSDpR$N(=_-r&oN*>QD|vibg9nN$4VhfJelD_F5&LJ&eu7i{ zh^*>K94?-`VK)zVTF)zog)4Htu)(XC#?d6SCcB2nu`B(kf`l2+{@ZrlpO3y?7K&Z>` z(Z0sF#URz-5wO)H0H-brPQ9~9Y+N!o&4j61_W1@hwFq^@qeP9d%K;}Azp?2K<0CQ@ zK~+u1<(F!Xr&Y zm6}qG-51WIMgK%;BKz0Dy@EC_99ZT4Q~0G`{aFi3=}uCH-@{<~(pWPlBpVGKUl?#b zJ8T=93=S3l*XP%Ywux7^-(2N_hzw5k)NUE4nVpW@+iIHoilrVCB=zKTLErhi4VTM! zmi0>Y*zb$eO>jyEWwDa^_r>@z?nyP|b5h%n_2LcW?GoIX?!w>)QE=j6Dj_|jlwm}P zKEUFtWs+j)FycGnVp})n-g$Pz-{1fIrAv6QG{Z*(Ec)rPge;!E`PCBkIF#lG@x@z_ z^>Z(@$GcnSAOW-PT_;;d+QE^xcUZv~PE}fT{O40r70RQnBMXlYB-EH*sn#v^E!hZv zwH5m8RZ7U89O9pv>Q?EfA0x5OMnZWx2nZ8NST=6^@$KVfTQ1sV9eLa~FrP>hxg>0l zA4uau6|ZV9rlyMiJp)-3{w>0JD7oa2=75&o|5c$n{bhY>{_0Vjx@)UYm2V!4X;$T+ z`-_Y&nseV{#=5rLQ7Qp$YN}26R5W7iYCb?gWAWH9`#?-IK58A!*gLeR=&w`e`ok|Y zemBO3r8}&?sQ)Gz;S+88tOT=THnn1sMA5K#)SC|K{-4jRs}QBri8mOUhOqfuhI?PP z=l&4Cy@SVoH=Tu#@29447$gxH!Z5K?N*o)#d#-GEbz8!JJ;2%Ci7Y> z$-iVVSZV1>(OV@3@j-$^SHp7mT$kP4WQHeQ>b&a?j`k+B^eKS zEM2`c)4*-FT7Nvxe1yPO&^F9GT<&+(FvF(v4y)CH`I(BCt)YXyQtT${Y(v;Mwv=Uv zpr7v+?PZzW$H#3ioC zbt%EEOHPFfi;FnJ%bl}STqYBNfy{V2&18v-YRP~y05 z<(#~3I5hr{2#W^c$tA1MjH0o|BqF(W_1qqP zbR#9h*}I<@M9*LPbpCQ_DkpMIvV!sF``F-`0H22JBqH57kPzSm8??{YvDH4@*gauC zxprxHt)@pfBKEoc8GSh|E!v+yANn-tgDu*C|8XPL9| z1g@8D<)|{O(N!Dw>@j{czJqeQxKMcFPTdm~S+vXs};=Bx_xfD?>WNy?q^)bVA?Ty)d?wH#-#rohR>fTCxYVZ z&jxnr`Py2Io8c~(j9g^pTHeE?dbjQ3sO+@`5p_v3txn$>q7%Pg-_F8Ebet7WOk*>O zU3>29^duD;^*s#Rqd!i6btA38@Rj{m#E{)4mLMhS&Ex9F;xQ7ARIgO2oXYoIG`UVq zFr?z=Uc`S-xLaaMpII>}hg^%Av#Ads*H3R#5k4!nE%YG9^Sq%^5*{*Cf=ln%4)j7N zD{$JR1Cwg>8{wtPm+OI1@uKa+l^Tu1%V|z`#pahcjiklt{hdDYUP}6=Tep|KV@7JH zIENkGW4ChSznvL3J6!H544D+30nI zh0a@vJq7XgdGWP!jPO168q#pNZnHaWf8xHaTwGnQ|7rW`oeu?OKbtz^0oyOLSeXhi zuN4qQ7nrjzLl-XBXs-^ZuIxooRrpWDbFF%M6E71_ds{Mb?JW&m`vcu%tF}M+f~e@e z?!9}kZeI8nqM;|_VN%jQNBhh6BqO~jiLR%!?DdB}Roj91trq#!7Wp3fFB^%`=k3+` zpy1oQuJuP+VtKz!Okm6TE2}GA7keN3xw^XS?!*e|;X~G1{}t~sBlXNm4E8b^W?C?6 zPVZnLN_|-LdtXrl(fv&vgG9e@h2CmiKxh^d{ZIM`U02yN4LzPN)(uG~M(~i(1A>$v z`F}EsL$e%}O^r6Cg%ZAgIJU<~<7Xtl?=Wy^S4Gh_thXUpu-H4hiCbUyBuqom9G z6??5xnd?m@<(J8g6*ZCMrIs~Q1o`sfF7INt{oBo7EaEG*KP;T-S_j&1%lzTV-5+j$ z&GK!_QX{4k+Z?dFl@pSDf{Y^j5)E`EPhr0NY~bu(>Lc71U-|D(%sQ#s)z#MvsrSeuO$NW^)pna6bQo;@q!L%~1Qel7f$z#T@RqsZ6Q9o?eYNlts| z9!45b19rNrR{lma4NJ4ytJ&rQta+6m35I>PtjltD83sKY$~WiJ+U*X8a7jJBaW~uV zG;j~uep|y-`UWt19z#@2xYK_0EcDwH9(4R%G)r8IiGJqJW|&O zx}$!_Oimdruhd<6r%2=0er?x#+E!e2UzLJla=a;2!>}cg*X;HCXVUWI4_9utkN+Nh z;^w%h{qiEQu^{KITeq*cjJ^HPYAWpLDy1E@(F|I^z@VTTK0aL<-Ag_a!f?N~28;#w zumo2w&crJpY&a2i{#o;T7k7WLxuh&Z4Q?%Z51O(8V$eiyu3@^26(70;!IZFkUvw5p zeHRv4`7|t2!&}Sk!_C)!I=ws}uv* zfpAxEpstr6P`;mQ`XjB(jO_8oleZE5XE9OsA$BF3KUz9Oh?tFhmXH&dIGgOCG#aOe`~7*& zwtfK1Q|%lJOc|qqY}bRhm2<>UuMg7m>tEdMm`ucsVlQ9_5XLg>^}!$Ogo9f@Vgp}1 z|JH!@dhA`f@N~#VzEW(*XmsqU=H7xu+4fjkXngySGf8mp(w|1&&B|nX!}fg%H(dTF z8a}&YljV}sL5aU-n?)b?zLmc+^JR*6%`f3CF5aC+%J{6F`$I{al6}_nJsWNl#rH45 zBoB^d@whXzOKfp{4vl}dU$gzqB6nFLK zN0fK>bmsKBPi%YAUhd`GMD|cp1ZYi=Q0DavsFQ`wGeW=3bww3BKL{0-NOZh^-0{i$ zy`AE4H)RUksK;Fs3Po-4S?B|R&Y76f&78iaDeLHEV_JpR)r&YDv=XQn-tH8DDYqzY zSUq~GT^oIY0UtiR)gh<`{)g`HhPIr*)(%bemSq1(ra^1G*+4|fYO*;Ui`zkSdx=HU z<|Q!L2^t?UVwHSezJr4mx|*9|@0qU$wo3G$1+Jy7^2n6edT8$KJ&0+P^ka)-SSX51 zd~<;JrprP$nNt+lFI@WBWFpCqUsswViazad7yTK#{W3QEII_8x7O@Fj8^qVvXOm7y z-<5xOXH!DQb0Xi(d-+C#NAzdGy6$`_vHiWCgvu-HpH_z9jF7gvLni6%dJ(y%b~Vp@ zh)_`5y_s6y+iyN5ToX4gD!x*6ficUdFiPKa^5Z)M$?bbAn6dB9*_}~oCENX-Yremb zRKuwVUq3_p$=GW{j$OUZBfQCQS0j)GUg;s zaIyCXO%&l}B9V&{8WqJ<48mp&EuepFsh>(MMiGFmn3{9x8iD-OoV%DLF>Y(snD$ik z;f+E6a9Z?*JqN!(wN10@5&4sjKQkMtxp%B9vc}Ah;`H=)MPc(l4W~$m6Pf4lQ%(!N zD1}Bm&)mr&*7q(d*!>f7Z`oQL{8SQ?3?XxFdRg$%7N*DX{c})eH1sfGmU)N0tuJkF z%#s2hwreEaMJF;g{6%scQ}Ekq8d!l)H}Hj`Vq{8>9dXTN{+_k)V-dC^QFCkVOG+_q ztzTC7rEu+!9=Fl zS6(*9E*E4ixLimyV&3CoJ>Bz9+Kv;7f^_lHvhghqFjb1|bF#O{-*XbUr}$JsaCBG_ z_syj6{CP<{4C5}r*3m8W;WPX7;nbwkyI`Iu3~_KBere*l^Oy0=zbIxK@0ggqf3~x| zCJj%-;!GDcc(nHB+eS4%gZfd!ggNkgc!I3v88`h)Pr)AhcU=~B6(bv?Q~EyjX|_O- zY8$e@jnhUDF&A6;)z7W=eV?L6e+ov84fRAOdJk;$9yItMRSboLetEw>Pj@WHHEa*+ zn(i#FwA)WRYBLGg^wN-;aMzZDshs=S1JO-t5)x9ox#NY*BA1SykyEZ(RaV~cluWT{ zhQKqBtc9R$ADU=E;Zm`=rVE|6FUg2y&nSszhViCzyOL1Pb_2Jr_Whj#EXIz)&~VI4 zPj50V5`}{r*_eE`@p6O`VeiSjfdQSp)+p4| zH<@wx@^li9Wc{MPtI=S}@=c{%-+rEm8Vk;kA5UqntNoV?@aenbQWNQFw&#J({FXJ3 zpzT0NM4HCfw;jgX=1#r(jo1MMIYkvbFgM>{dd5*dKDgATl9Y2~kHV#tK|kxDe~Oor zi=(RO()f>$s%O&mD(I}W^&dkqZk(Dsb4op`Z-*HgWy7t}==SB!Ug{q}40&W4RjDzX zQNBGM9D!xNBtm;8xg5{Y|7b^t{ieq{(WaSJ-3gg}b5lW4SF^xBZyw!=+ajNLp;t0t z47kWla&7CoFK>HG{ZZq$78h;go3<+)rP9M1Hl&*~er)Hh!H zHa60ffx=lZT|f9+O?{&3xPZ=&+0$Haceq>@drz9B8218i#+8A9Vmm0zU%#5IOfj!c?umr-Bw9wrUNG`}W$`>4gun9!t*ug17C zZLZOTmdR@yPjYkZ2}f(spv#N#xr+z7kKv!YJ_#)9n_4dO!+t(B+v>&p)0nW#CC6zd z14S8%W8$dQ=fmW@mLO+Kjj_qNy{~Hv8YgLuuTR+&8jhAdzo}^H$0LPdn(Ov?)_9Zj zzBi6dQa`(P!ed+F3dxSkUWkyMC*E;7fhzelR|4ep>ACZq<1~8j_bCL9yG^`^D4L(O z(Oe!iB=g!-5SMy*Olc~nJ}p?Xrs)Lr!@WX%G!RmAr9*ChbL(`k)%_SpA4_q*4`Tbc zjbxc>i@_q^c^5GUht!H>9;gheAGm#-d4Vz&(pII`9#)rgz$Fi7KuEkO`TaCXrpndl z9a`5NH>V$pOKe?A;=ic^v6QH3FT|Z#K`hp(IM_%fe$BI(D1FOk$s1X*N0K?$K|fHK zDX*s|*%EnYt=RNRW@!TTd=P$a-Q(KYM^SS{AG#`+Mm-_d0E98sFdrib$x1u3C@UdP zn|2VSrwUm5NP-V>NvL3yPH3`xMCE}wSYE@Ylv#Cb8Zj}4iQfILU-b=$))<$@LrL(D ztqneDFwo32MQ5fg!Q(b!twQ`N8|pgbbN*K$h}_>D7owo1PEaf*FUruslGd~hT7opct8pC5B_ZNTozDt^x|%2MJ8<1*0Ktsj9Lzcj?3bil;@;3t+RX?b8fC= zyWZ8*&Z?Pl@#^*#S~JjZGIe2ZSm0``*9BcHN*=Kju=+(&X*F^Lxp~XN7p5DShewjA zTc}7|sCuS4P8{rs_2*a8AwP-~&crzCaU$3DJ`&!P@;MfSFJL*0Pra8W!4-K7@db|| zP38~gK)5X!4@%1<0-SD;=K1<-hC)S(%Mc#{QG^DERsPf|+K+j8Z){)O^5IYZ_z^)M zXBF~F@u5F5rwe70TGUK|M6$O!zn|5-43UCRG?15&FxcCx ziChDW10v~WG&5o24Ky4CEV5zC#&G=m_X*pp2||Y;;N66T4<8WIwirAF>WDC%fMVJY zG)D^3Q3#Oq`ro?d#)gEHlw%;GAVdns&o%SGoeqF;Dr;P& zIAKLtMqVDY2X%A8(-?_4^Rr;Z&tSBe3HhUppx4U!@!R6;t=qR5&<+E*o$xL6S=0EB zGIvLi7ASU#hf156d^Xx2eDMTy?~uCq15#$g#tm}&UPeSr*k1<2K`X2D9((vakbOr< zH@K%KEL22C6kBSK_`0BEiREPgdwK7n@AxtN{^PJWPiatwUTgz%hDLgjHg z$Z?0rad(CQlh*ellkJ@VN4TUn=?I5C;cA9SPOkwPIy93UY>yZl&Vy4r_k+A8QS$en z)%#f2(Z3v03E;=@0U)Ac+2i1x!riA^j#ts2fd7HNxQiG$`qAL;I%)d-8Oy|VmXY+W zV_`4eg?_Sa_uC)yJE%CIWAt>Ov#E4ESFj7vgYGJCT=X_mS-ycs#M}XHXbXKC^*nbR zADMnK!Y*c9iEe@N9pGj^?9hT)ReNN7_FLl9PF}mE@ZMZU{sP-AMn|g5s$ZBBHS;sd z1}*$N3GEUmE^vs_b+U$DGk;!Wd+9G|9;>8)j8Vs^X%ujpZi|-TGzVPx}X?m%8pUiYky+sg;ya)Ac-s0r-{whGwq+c z!&o^-&jA9Ysj0Hi6LiB`vxfggO~oVQm!Pc(^5Jfbq=q3zkmP~6eLdZn9yoD9Vh>w3 z^n?BQHmqNb{QWdE{4Qn+0PY6lklxhk?OCUpjjad;%v`%zNhc?k zVM&VhO|ekendD*CF!n}8MSbkDw5~bdPnw*R1YhX2zo%DW?7-nC#PDFCj@+-tu34~Q zP?}3bq;oZNu2?OGi+{2w{YMJU=!nprp?N%ffWEkQ zdX7FBWG4dO6qJOvqM|nliq%7mPWP)6NjyBo!*kKu+1a0DOH1rFk9^As+GM@ngF^9PI3(%#2YDW;G_@ zPlEn9j3021U=Utj9kx+5%IRVxV#Q_;KK4*oM>1J2f5ES6NRm@e!_EbN2xdk@W8_C| zgV|Y_l%V=VPFVcf+EIhJbV*og6((mYZe@KoIaA0)x|I#`NMr{Z2a)6usJaWy1~#gk!nX!0kPKHL4*SH6tHEGeo*i$wgcEMWCGSVyJE-z z@YVANU&+|E;$Y=N5gzDiO7OOvF4R8LWZSx&bd7=ov!4DbL#Bu>Hez7yjJ z6Jk@nkK_39;~)?TrpV4N%NP&O$y>oXON&v0#O1)!c>4utL+)?Y+Acae;n>F!S99Kn zUk7g0o)J2~x8L!HKgkx>HM=m;!dBx2)Qf@?Ae_ zKaGi*aPGG{69pnv<3FlWjct5T*s)u%7AS zyHx@~Wh{>I7Klr~7_rk*}ui-(|U6Fw=p1m&aTMtLm79L~#dG6@WCNhc(sP z?P9OHG2Yn_2$H5)Up8=y`Ea0ye|;t;*@AZ_(GldSL_L;2Bv$l_($Lb1Dbr{$2Y^3O z)AYJOB+U+*B!j-d$L^^RP97L`2v0!1;%QtQpcCu0gQDiqBry#drZCXXmNllPrm*@G zWVU2n1~C{Yr>+KL-jb%t7drSVHFc2PY}l@OrFY#4cA7UQfxzNi+&cyRWKk7wNr_|) zyno?cs8M5KF4fRFnex__3MJL!q&ferlb84|Hde4zg&Hjm9@rA?Z7VCzW2pk8#tM^i zs;pR;v1&AQ0Zoe7W9tGzgQcvK&c((lqn;zg=ln@2)`Ky_q!x{&m_|$Cn896Yrj0Ts zc)EM;e#~k82Ez~QVo7gopXgM_58GS2SlgQAcY|2^$UJWTHe+l;P@Bm8xQo4SCrVEmwwhMil0OJTX>euQ+3R_KLKzvPxd!A9@*n%DD;;|DT|O06g}isFu* zZb~R7*jM5AO)(3bV+X{y>V^DeY*tjKr!T-YSPE4?(Ov%Kd?TNQ0$do{ID)a z^x@;+;PhFCfCYgd{LKq9E`2T&Dx#ViU_$Kicd!CM3jhKu&C_#uh8n>oY0`xn=`|Qy z!QR0lsA>JK-YloEB)x9%mqo&`Xa9f&W9-VkM#)|k_oJkm4qAkhlvq*5FZZrnX;{w+ zQe=$6ZZnRyjfI(4DI4$VI4xq~AF4I{a_qcYp_+P3-2t%YtSy)HY7*U(dI+sM?|r@X zepz&uJ~Lk%GN(i_>d}71nO5TB?u1mJ2SE?^L9PXd)L;46K_1KC1x;V=g=P9ou_7Olg-mIP zD+mAn5B%;4F!&i2Y=O>gCu_d%N)^ytc$E!<{ki6(%mPDLj--D0j7 z=5eV^yyxk5KURIJrv~JIZ1Ncpo)?4;gaV!&&<7!~0Q#t}2>Z1US!nlZs_REQ`Z6*t z{b0j%5JB+>TcpQ$NPkBNaRGE-(RUK(sxwOL93}36Bp9Uf$u&J%BZF`!>abrKZ<4XW4G*N?Z zx`!_AJA8_m05!5)sLj?(6x(0D`8ZGivAEB0O_OKwdA8SzN7yM>a-2-d8IK-)^5u(M ztfbrZN4(EwI*ACZBGc2E*bgTI2X|wx(R>{Y_Y+rFFXhEq=r=At9RI-i-?8IInAuk? z04m2(reP}eo3QdNy;E96>&JClepVB_@@a`GJsfz|Y z+XSU6&=`E{E{c7hsxu|FUn4xlm<$H9@F6Ak;4>q^ebF%+T}8Qud0O14+!+$F1VomA z>;VSvY;bM+XD87*({WC zP7`JM~PfJ1&CTJd?@Q+mbaDuWDdS4#FS4EXT6c{bIPon}=T ztJ|s77Z(m2RY;J3yxX5~#|6Y(R$XuXsYiVD?#RzPt0zb&3PKE>&IEitxv0}R%{2WF za)`bgTB8Tr=?pK}DGGFK6*OkWvSXX^D{F`GuD|+7=O$)0q~f(OzWN)^11)yjq^~wF z=;4$+7`&{@sabsR&-(KrqwGY45_iEU zKAN|%mG>oXzKNh4fWJmia}m-cAs%nXNGT&t@3!WK@ntFh;j4bP{M_~HXOipVgZ3pR zoUeM0lyW{V>vzv3oXEToW_s1tb2qPK`3b=TC{OiPJKVN&%H?&#MXTB0IefR~C%<8Q z_l2tXT0-PN>zBk*_GIa3r{-98m*tPLyAq8uI8V$uT$;FXt?%oTJY4?liZ7voyQt&h z!Dx}Y_k2R}B2a&0BF7%#`SHi_`lCypz&JH;eY+2urrbm@M%O56LCtn1gd6*m{o5#L zv!wbViF=4RP}Tove>oyIqS#h)vH61QYz66D^94#)$WuT^HevDhbZC*p437+?fohVK zVrG9Bhq8h`Xv&0vt@V}3ZLjjdxA&(PquN69j|F~|yE)OAFjt?uuV6cVmuS2jwk3FX8uxLeXF&tY4H6wV*$(hFX{doZ7KRHUB(3V1M7QjA7LYMUnh=vgWOfh-|LRkkztp*@YMw9-|)K+IJR3@wXV zk%z6e+i`~#*2}s*OVX!s@Qz3A3shUw4a^3tESP87DB=tIWIIlB{Ij z1ZST=MymW7IMF`}aden-8+lVL#|n34jN6_7s)+QihG@a6KEst`9O5Jn$@Tv2IuFe( z8lJw?%B-W;`#Ex5a(&jgId?uGGxq~c@KIqBOzwuJgy(EWKuCg5Z)pFmh9V(z4?A6x z+X;@I_{xx834T-0HLgp%7GC@0Wfnv+$0Ts<%DDJyu?8L2O}9r6j$1rc;)q+)E$X+Dvt`fI6kyKE{B*JcDT`w-ogiF!iK;Ip?4 z)UOV;#w7AT3lG1M7(NIdIEKe{&Oi|2PC$vwav0#PFm@wQo&PbnqEdTWdSuxhr4T|X+-Ovv zslpO;^4x|LFl6f(n?xxvA9d1)>C8XJTo0)0l5WzHX0yxz_k&pyLx`smVC(18OY zKEJqMWstUNU4kiW%wTy_Q;T}3L=)O!|D5U~-@5v!*V?5xNLgKd^gsqLbvh*f*A2xV zeWyv?$qn~KLw^BJ)HNLK-D}-WlAMPERKBnLXeVIdw~I^lw#oO}D6Mxn+bD5_e@n@l zPr5t%tHO2kbwG2vu1Mrys>^{8X}Y77Uj}E&C)Bk$nw2UTxSDR$l~`%6`+c)r-y)ZX zjjw&GuBpkT>wnKMqBP{1xJGnxyE%oQkWX~-TCW;xNI*Ovgob10@ECyq+MKL(G}fU} zY;_*XH;3gbzX?DCN|4$?H=E}B?@kb?4mRiBij!H-H?!CerxPjsAdWTr8=Bb{1 zY7yt+7Q0&mEv%sfiA^$c*GtzgHC+nO&q{P_8!0Gg{~FRH-Yj^m^42cQB;JY6-LaSo zwjU}$UIp%qo~)0Rsq#AJ>!(2RTGdbflA`kY#xX{{uDR2bTULC6N>zRR%fIWe8I|h^ zWeSNT!Poe*m_wLl#_hc1DqGm!1^!+Zc$JYi6M5zG!oNeChJ#N+L>0)cxvc9AbK^rImmT>q{vQVegG85r|hntq!U*j21^*kR^xlKyu$h z!^1`$AGEbfTm`^GqF@pqnzMQuBy8S%4BCzTf@b#2A!EIv26n0-}m(NE?CPcTpV1B3TMOuS!}8XWxLdH zOQS7BsQC^I4zt@36{>3TWDsd*0N@@i3d55yD~Kz1bpFOq_p_Wax%6TNWU$G=B9dLy z2!`?d6`^Zg0q~iC58kt8AF&TjB#klDDOnqe*$yjdik9*6aD9CnMV-d&z_zhxopQ!- zz#}0YPlMqfPC7+fCiDCKfO^Ju@57nYlG3o8U|pZe>U0_PHGIpUf_{cgEwwuC`J*p~ zsi^KDTs6~-WBviliW2xLeYMYyQ-Mq?2KB-LM&AKmHnKR7vp#m}6k$t#^U?T|jsQF# z5EakW;iLt`or;>; x^A+1OazcFK^b^FGAHfzZj%R}3LAmpVh{7lAuz8b_Y%T0Z z>grU-18_336FUf|Yx}#DVF-l^1eFH6cZK&8JiGA^;7biulJk85>`}mN-UQ7b zkeR+1U*W!={w~3kAKU}qM|0XSsJDTv&9S4`GZ-+1A^AY-mJ(JDtQ9__M zK%nvtc1|*l$oz=_5b%T2)SWkwjfpRc;MTrBIcbS>p3U1+X)(W`O;I%{`UZi(;JG%z z$kIj`g;z0py$|;qtGhA10ew44PdM;3#4g`ZgtZ&(xl|~KLAqf+5p#|`M&I+MExN{o z)Rl18zOQkyaDAPy|D=vx(2;FdgC>Rizb2*~-8f5x9dn1`{SI@bLHZ*obgGbyv_My6fpu8HaH1IwcwM5LjNWOdYwr8X0O z`N& zUjZ@*xI_7zIuJ+-Dp6-ZK(!m)&Yut$N->hJq02=P&F?LI)ngmxm=S3xZjDQ1vKlr3? zR(QN1vrngSm!ZQ(Z$^^{GpUtNB(hY>kmBHQT95O+!J&-Od7b_A0vN1;;lrWzZ;56$Nt1)Z!jRfjI^jJFmHyB|&~)=h z5iXhlgb25N3Utixx8F&(mGY7TXVX&~%0dZq41EiMu7{>i>RAn;sH&TSZbec)5&OR5 z<%ia&S8{hZzcV`iL1%-w!@C@87L`^$sAFa5+_Ua92nhPHzutBDVl4;t`pOuoVuYPx zg10MlkC+A9_cSc_eww&JFc3w8jtVgoDNvj{Z?sE1uXz8Ug39OPD*M0Y>37ezbtFhi zi_K)b247KXX6Er(x7(?DDY%Bxk8T@gjN_uVUM&lH{WB;+Mas0Fp#sZ&D^V|*f4;yp3 zK}=$Yr@Ea%<0j_gdN*H7veQxaPL=AC_X`+I82fQ)-i+!4Nhz0~Ii0}{JGuA&Jj%!O z5*SR54Jq_zZ|#rpUgZT!1xkgWO%Lq~D>CT{&W+z*IRf6b6BEDV1@?yDpIH9U{a5{Q zTP-t<-WcDM6v^QJZOLB+mWv--MC0xD+ms1{13FN{=e-9SswWL*oOeMalF^^MI$G7VfVcrT~_SYM$lA9^nQZC6_JkTTYmJi+iG*c^`4WI4*2^X-KWH(PG3-1cD@!32)7Bwd7xp>gPYfk<7^9XPQD`Nc} z5NXCo#fK!kS~|2f`})gW*rU$@+@6iX@Cmu*a*H~HiG@J3phfxo(8 zW~y_QsfeD&KtHiR@o3M&&(qkr#)k8q2KpGxU~&+-qKK*$WFtVl0zBs+<=6a`$hm^^ zYr#ft^hpPjZ$^$##Z1*MOG!z8f7z;AbIlt(TS=L_VY@EMscAzIFJzrQ`fPhA-Z&Zb z^2YV+jN6cCL9iYzq)Ck#)YO*>V)-U^`$CzisEFEaDZt4bBl%=|cWA5h`h5>3HrIZl z4IV*#2+b^WZco#sgnGe2`)qFL7M}=Fn{_1le_+d0YfXYan1lbsw`{#MTvH_2wf{+$ zn@_=lK9sOER`T3%3!;rwh)cKd6Yk5@xxI}UfzxuVJmQ*%D^k^pp)4x}S3L4?D^gM**-j6Bg zd}O<)Z`2Sr{A7ztA^$tT$puG-6S4k~9Y;9kpP(O*a!9`#tSCaPiJF!c>J>C4@adc7 zXd~4+p^3oI&;X!L4jWhgl=MMR!Wl&8J_ocxg1x^tovp=PDYSN0LpbID@DAGJ!Kw>c zwC)Lfv&W?P^y$;Gii(fBo%}bv)b-lrpQdf|KYJv5t_>l8vENRm+iL@fQ8!%!?zq@; zP{7<4zF_y}Q7%HfO+|ps4R!))AeZ&cFD$5Duhi6f=JUsdQRF}t88!6>1o57l`Y@?T zc)v*^(GGMEP`k5*o57V>pXoK`NQUKKw)+`Gzt1?i6qQgrdzX{PWsd9hO6Gfxaj>x= zY7O8}ZIEz%`t<1z#iRWULr$xCgfsAru>b7C&3sj8})_Y`Ec zFwmH-Y7nUOPFlBau|aqPmr1Cgd2{e`Mncdj>SVUoL-*c|nt#yFC&9{SKXiY*#P3uo zD5oF~T#H?XKIMmJxP3^ibn+`+J~MuO`t+N`#JQi{nYR}58Vc64(*#UDUwhtl*(j_5 z$=MvDKGd=iAzdpKL!S0&|Aa_}OLxl~3y1oc8DuOk$-SjsUE%`EIUY_P)lWphsVx4JzV064Ai*!5tXd@xjRVO)Yl!8H< z0l|R)qb$y}QHF63mPv2T;%jCGiVyU&o)9C}bSgO_&>}!Daz~ORgwgkYF5@hC`bcuQ(XjY8 z_Do}>n@)ARc$$L;7y~53_L`pH7ZZ5QGT28Q|11)4EPEPqo+-t5&?46b*i7YV0OvRt zm)0%o|6gd#kioe9A=M+M;?8{T2N~mGY!mKEWbFcHc6ds*ol8@(omb>El=Hy`1?>ku zdf}Y+7ug(4R(=`C)180wYb4jJ_oq9yR(YyJ7@sU#N!(n>Qv#xRq0k|E|D{#YL z6vL=k=x~}f9dR<=1!PW;Rc{jCDJJ_~Bo|jc zU$fEf6HC7rx|D``yDSr7B&CKeHu1P!HKvIH!PRp?#;yxVr{FQmc+VZj90M4@i)w1^FrLYIN-vtr!2>6Q#GqV(ZIUTSZBnqZ@Boq zIwI|d!brYV0X@5mkB*Kmv7n$pKGeZ&|F|LCTVKTcl7Gqdp(+&Pus0QfD7#qO(bSyy zYa+xTlbw7m=mq48P=rOu-4Qk=G)2oC$0*H9rostq3f{=H0}C*#;G`WOOuY?LQx+w* zp26t1=l;p95hA<3j^TP3N4^O%jqqfPU0oTA$8>f8P)_!3`iF9v@LvDmP2 zPPF=V{lA(-oRbGh|CIDTh#jt zIZ)!c6OW*B$}jo-N3D`_B9|IxCf09fUReO;-WhS~G3V|is>RlSdpItb@6zYZ*{8Km z(&z2-Y|x{MneiclEsgA`c*{Ntm1%7d<5xE*1+UzF_(Ug9K7}h|-(?tR;K5@DC44tb z2@wX$df}a;;^@AYFE5>|jO4_YrekkFE&V-I)Y^T9kb!)vU)H1iE=E=eP;>^=${YFX zWJnc<@To^IjJr|Q$w}}8{)B+AVb-Cy;nU$V#z}nCkHq#5ZMqc$i)yRwgh#2+AUD8K z@{~Tiy{xDFlw@qaX!fU9JfFM4zn1jvrC{DB(Q_rUvt?Uzx^HhM56-q+a9#SUsd`=K z{@y3V4u>1hL(T~=wZ(At$cE%)>}4b2NT0oDFqYkg2STMcPu6pgOY1JY$C3bBX)b8+ zoIvsj|ykC2CIU8$T@S(DtoQ%A= z5cdhF!ErHu8Kp%SOtlgNU6}QopBw@LR6xh80P1)N-_=E#zuE4w89TtH z`_@9=nq1j$RCv1cA|t~!T>w(-PrpC@=|{+!xov*rBm6qG7c80G=BnMlxkgnc4J|Em z$DPDILoJ~u4}c+~hc@v@3H9$w`Ya(KBU8}SOS-C#KSl}86)&gaAwV->z0x21|B;YE zRZ&BCBfVp$Bif3ghY46vf@_5`Hedj~H7zZrck+70wZ~OK z9gMf6S{w(C*G9$=poiV7&VF*T;exfy%>C^z2oXJq4m?dr;FF82U75HCrsHqY0y$B@ zOHFGZ7eyeh+&yZB+p=v}jDs6(`4!L5q_6wX&~dXlXMJ;F1J95>8?tb3laq_!kqm`s zZ-10lSBE}Zz{BZ2%i4Hbh~}c5$Fi&p^{xEwUf#qT>g`jcB!LJQP-=T{mymmg9F_5RshFO@Q;FO2{6?&|fD2tDryg)iad`kr6Wv`}SAmLU|i-ZSOGTy8Az zW@B9Kr;g!hm~BMQYuUw;+uZcOvVW`efd+o5geX{HKiW0y|?MbnPkF zIa%dJJw3)osTDoKN}&A{UI7jSJfRi_!mKwr2m%%G@X;q;o>1I<4R0}uJf%%97i@uU zACq>3RA0RL4vRw#S&TGn_Yx#@Hc>){@CITb+;no&O`uZh+k<)vCFVOR!Or>pq~mlC z1N4`2DA|1sR(@NGiUMf#0;yEsZU;94Y|}I|tD!AC;ugc)yEXYE3wqTnG{sA`g9E;{!>xuErKY(p~N6nT!3QM5gbg$C% z@`;`fBGgl+Tz`k_;_druY|DFTxHP>d5^f%<7yl)?AX*54IPx#~qca0C{yk2e`qq(c zkz*~1q(491#o0@Rv9B%mtsx<(lP70?3}K5F1!flq%I-~unL-?PygJqXhP*t9b@`Ta zk3E(LvZkveF*XkX(1K?09X&vqB^4fZL9eT2Sa^)VupXy77vbRVk7Y|((gjEiMB5h;Zn zh&{jwAwd?9XVv{iJx#;frwrx^flV4lX8doOjkxHPloV5Uo|Qu}?{wsvD_65VUQqvg z?)Qlzpq`2K$Ma#`bV)E|*}~^|PA>i!vC_Y1eK}C{p^W$1M|q`?jLP1Vl6G&aCjx^T z&U;-srA#MxEWi2s@chrR^d~=Hp{Za|l>QG4ZxZ=T31UvfD=xIQo_IY254OFiem!8< zxQZ>;AJ7TG$4P;|C*C(Ku(0S_TKp0OJeneB-Wc)79~` z%#U~4PwTl3_%o|;tKF8Y^7>;zHIKyr!rS~o`)od^ZK2`FVERo*#jqiV8{H!pFEz~- zXw^>jt)CFYED^iA1ZJ0%&yA60lDr+OWjVTQ&o5kC;M1_(Cb%elYu!(%*XF60u-@n9 z4(CI@jG;>nirpbyV^mbRv-tPT+I*;QBp)~Qh|${Go{oT`L7b^qsg!Co@}t6K^0nJw zx!rFWR)PXizI;%fCS*Mjb;~eP%xRp4LpgSIneR7YkCcV!Ggp1o=GRR5c1Cs(UQ-R& zo)c3-K&aynRv{6x4&s6fo`8_!246NpX=pg#EIwdfFl_w(gt{X|6Tgwx%`z<%w zU*11#HMZTE-vX5vH-CIIqK%knO}g@e=;GEZmF@B}Ud&5TJGMrdZO%O!BC{1G4 zDd6~Ekc43nqu3!>_g|o&;9RGnkDDGT1`HwO-|pat2!@_!8u-vACT|JA#Yu!hzIzBP z;g8N!Iv=#Mc8`sXA;W5-T^(an_L$+U*)K?ZD*)1ER{wIKpwXYs;L(XI5hzU;DuWk= z&5R$6IGUiq$O)iel7+T|jbb>)$o#bqT^pn6p2C8yT)v`k05x^Jtp8*>a8c$`0GChjjp;@Y8&^G5VQvZJ53#WNXR5#b0 z%HIBTS=36ZdK#>PRI>i=k48komOp;2x~xq1?s{H+`Hf0~bjVCO&{r_Nkk3+|A>Cs)mzu}$zqHIhE`l%gn$nJ7RSfGi z_0(=OIpd}$pW-u{BLm%2fI{5gi5h8vQwp6Gp)`d7xtBY8`Tft``-r?4w3j_alM{Sr zFRH0MZ}K91i=14$sj{M?-6rJUfaf2o+061IHFexh%&>zP0~W~E`dyYBo~Vuw==o1%}0BB<1fK>*(#`1 zkbEr|#k~KEIR-ek*Se-F=eB+ZA7t+$d2_nBkz#7J(^r5=t@9J-1&sd5-O<)21F{II z-qp$%EU*}%eu?AX_QS@cx@z7nE>DG0M^5R%rjRWXF=G|qof6$&3L z9ZCEd{ve7~%CVwGf8&jJP{Bn^Oe}x<+RFi5R)kvqc|B|Tm#2s(rDyeD2pmj7^IJvg z#GUS&wZ{;buD9qDTDLm3OWrZaDZ z2#H!kuZ9o2E(?|>;VDkUkh%kqw|yoIq%Qu0W%-Ze+Y$idZGW-004?sI1H-1pn^~N7 zck0wXMy_qW(x_aoE%_S4lWTd8#{idKlK0?iE=F8aKTO4vUbA7-dZ6*l9nj|W+2seN z6q=A;FUz=MsA2PN+FiDbkf0@ahUD&IfbK1w;*#O_zr}{0!%k`^~j0;1B}@!+9}6l>}-pCKed2+58rdVc(>d3n1xplpMx%? zMr5XvkZ3ID`IADT^5i%xeQ=%8K!yP2W~X7wIhcxST3U|=YeLDLSdLilOvJzN#?-4T z3u6_2`A%+uw4VrBe>YtYdbHtWV`Hj1NoROIL!Y3uj&)R5SF-d|aI))DY2`{kv;fMo+xM~SL&%KPs<)6qjKsIhrJ8E_ z!Pbz@n{5xB+M$Wzn^{Q5`oZ>roPbdpvg13En4H{pQ(tM#H??g_MxO>#7iYRF9a3Q) z>>8~i>&c^U9;`Z3ht1x2ed+x{|L3*owZbf6so_ytX?(LY=^Y)o^ zN!FIg|8#rA(`;qSQ_|h!wzNm%-6pZK9%fDTVzQ6;qgK9hdJ1e^z#O`K0*ak=oGmxv z-V$vH#x=!kB^Y%s^Q=Y7PZb@oXwALYOnNv-{wY>{FYAMY{(g*F2W8=>lV9!^{)jv% z`>6TS6{W$?h7#}ek~kDem**@)H46s&SByWI*>g+@CO$0v^7Tn%Va}MBWLv3BR8%BC z{mn^_EwSg0$C?(-9vOIXFY&#>!r@qD(wcC}v$tl+e=ynJZrd20_t~-&ANVp?6~wYc z;$?VLQSaF;N3Uu2Hcp>kIW}uQ*(1C}BE$BXp46RoPxcZI3ocJ5x;ZPsk~0v z@lm91_^1f>=cln&!81Sre%MJ8nzH>wr8&`oy!HBxcU}%eWzlEBU)HWz{Km36N%SaB zE@v)ZsANf=@^JljkcO3nX+N{on+hwJtUF(28zQ3M!l#l_QgXl_DLpIqfWW(jmZi{Z z@blJo8pD2)plY9xi>ug%#^JwQ0C$&|ikqPE1RW`fn5WJh2`)HN(wm|KTp%?|vYPDc zDEhq@ecWz~xI5|Aje=r$_hMuq^zVeTUF8Vx9J{!_PM&w=D@Rwyg*NzvC>+7o<=80Lx73tNJB*)G!oJkB=8UB)G+|&766~F1lBdojJ zlx;dFt|Q(0_-I=1m-pc{qE2UseH(l}3^y2s?{2)kx{=^8TxYt{`J^nm`u^ID$H7kq zOYL$B?1#x-Sih5hd}yEAdxMxZ&QOPGJ#h?+H~$`A;q9?eJichjX5}X-^j7W49;3r} z>lD7ETQ5<{T73g`)z6n?_;8oaG^8VSY_D?6bZeaN?@+fSQ;#g~XMI+LpKnDs1-IRr z4L4beMg`r!+t``zDd%Gw#-be0khey$ayB{!*A=q9Dy6u~~WFK@-TE z()M2OMnS|27=>}N?~IQp_F+V9nzh5-&o(E}p--%A4!#epBpBwT8f4?vYHOjAgx6h$x zg+b|j?5QruJ1y1GVzRRtHwz|@PT!q7ncwG4XXq&`JnJZQE8n9(k8C|J0};YJgC7qq zMMk2_?Mk{89-)6)c&r_M=zt%fEv&LX`vaJCs*gb7E(Ch%j>Vy+-nX1y-ZHzKT+rv} z+Fd?vhFg{qb-YPwTBl(vqbX99$RLq#Rg&zcr*4N1U7pnv$ym6=?4edJOdB&fa;?9 zV&g$7dEP$mor{6STem*xEH#3Wk+ta_ky&+HIwT!k^xy+G*ZY*vvp$V-875|Pech#Q zIKLhdsJMeYVsP6(u?Ja%!I`G^_m?& zF?{kYM|soIi`3@Cm74|(v(mYX$+Y9fF*F5h`-ypTp$`3p+p)p)k>XNTeqMXu}xV`MY@$ETHk#xIc zja5Hyy);v6%khAW`USQ?&M;`Y>8`&(muIlMFqk(COud!imU{ zr9J4c1>uTtjMB`0_y_Tqv%MRwoA;c97}wdNG>53|WcO0-gDMgACK(} zU!0hO{LCJ7NNs&n_1T4-IrrOex>`RdVTI4bxc)QN@FBuC$v%1&b%2Bj1D2-A$79f~ zI8&gkdIO}Nw;EMGC0}!V|AQt2=8$YV?dS&B5|}w(lWm>g-N2o9&E4GviQlNh!pcrJ z^w0$S3`W6A{O!5k0rPngmM+rZO)Gu>E&s}F{BFWw88>6(h8C6>k9QY&gE4v!G+y^- zvmRpQO78GwZ!bp1E6FE5gKZjGuD_AfWX~usaen{fc_%N*_4WVy8D%dXCtcnmB;EYQ zFG}N;Me5F_R2F`K1&*#`KuZIrdduG>nvE6e=w2kNTqhS)qKz@pZ8FpZ6;`Nr2E9+} z^DeXxmT)%Fa6nhm@Ip%Y*tePCS-7aTPMQYM_g$HIXl~cxq;=j}Pn-t#2iyPhlD?1I z6xdchSVpLya~nWr3eXR}tJo#;jQ+DceD36R$m!(PgH7=w_3gD@5uBu;#N6LWJx{prY11I-?16C`&I98bxj-6O! z^V+fFuPnahO&3p$Tm5WTf7)sI3ZBB^c*!hyTD`sOX`YNkuB zJ?O2G*4eR*rZ7IwRz0-Sl5Js7p)+&5QijF*dB!7P*)riv&-X>V=yG_4BfsjCm9f2X zgsz^xDXXGUVAcTQn2Zg3dyj_@^EooAuJtq zTnHnD!ZjOj>dJ7{84R3;?T}iAUKD6$`a8v|NY3p6l>&P$+^N4yXfM^He_W)?5!{NN zo+W(@JF9DN9Pr4mW$1~aUH#b&)_rg`X|+_f$Djpb2fZpon5D+cN&$*10b~@)w*l~= z7qva6oDvS-5e97_fcAko2iPf0*joVAeSfD)^yF)$NWW**n~P6ex0X5|2L@K&%Cg1s zV+U?Hist4T>#Y>l{a`Glf zSckOVIdS~>g&CSZ7J&jt``{HHL*kz_ROg4N2^NV`%6;)Bl!+})c7+2zRBXc{?szh@ zbooecu?r5^#cy@@+I1@Z&GYv{>>+9dbi1m1_^a9QU{iQEMN9Zv?$^lG< zPXdBSFX_q;?lyvbF(m-5Np5d00OOt%s9fiOi~i`zlSKHH<7o3eum<`OV3*M&h5ziS zi-QNeGefLLjtN@UahqocY zX9RbGfg&c5Yo`1R=rIO58z(|Dd3fvh;GmfE%pAzsBa&{ zHN@1w7&$0)J9uZTx!NloKYKR3hS>x4G-!qDka*YM`%o(4n@LzdRvZkjW4eBZA6b0= zZNVeti|gdcuw12zaxG75e4q#TX3bz)$BFjg65Um_dYy-pzF{+OQJn_`w-c9XYRn%m zxtCi`4A_vl{8`*I)388uCtK6L4cOY^H{BAfveWPOC*7hRveJ%%P9OIsWz2!=1?H}4 zUqSV`WtI!E$|+3;p?yk&*@9TL!-uqr&P}yD;E1)2sb!qfBMgAk8ufn$fZ$lwsc1rv z0KgQ`Bj8Yq#&ngNP%??jL7#yipr}qMIg8QO*0%ha`#9Sad;R_O6R?ghm%1;l&iHIU zX}^=?u`*r%QUIjQ>!E~zLE5vRlOm>}+Mk@RrwzDK0`Ti3>)xUs*TG{MuzQ*4hw1BC`{wgL45?j0lbI60QB%k& z<=$xzwCc_)4E;sPEcr6O&;1Fson)jS%`BNG!zhF@CjkMj$F}M~teC??p}QS`R9QgX zB4kwnmCHhJ4+F9{ti^n&Y-9Skw6t`m7Xt%BF5KN{To!bF zc{Rf6GfVsD{Hzb|41K;2CV*;Br-Z2c;^=u0ckv8?x`6Xc`)8ePE4w%0_j^AP=ec3SdGrWD#z+PP)S@${r4l;I_a?L2vJyZ-#!a|`q|BVk%}Pb zxBk*a+g*7eW zsb4R4muyc7Y)e~J3E%@5rnSVf3e;S|Q&FtT-UpOsn2qeGVGHM(^y1Y?h@ z24=-e?|&p*`l;qz6WtZ5^sp0GAZF-Ik+TmzH9FB`2nV=3TdZx4*|^VpXy+|mb0Y3` z6ch@)bAL&ybrA|Yi6uCZ4ii@A=w@B!ve4^9ml{+64+_tfR< zmoHE4#Hc-_ms{ANvH~SeP77cBJ!8rfQ;8y}2z_^9_zY4VL8jxX=G*jtd{x}J&T_wf z6a^P(Z(ilkN)@(1A>%87*E4T*Yn47^)4>)N_Pp*%*sy3 z=JA$Cn(9*Kaq%e~T|T_vR$lRR%lceE)jb#t36jlnSCJ#Z$UOlm7Xiy3{D*nz)sMe}AL1=S3tyonU>*3qIVpsw=QGxpJKCPjB+re#LKo?1f zn2WB=a2Oh!>UNgFj4p9zAW~K$?7cKv6_bz1SRXWZoNbbX{#pZLDG41CCrpN1o*a~w zqkze{@VW3{S?xVyWN9ABPC^+Kql~v6iepX+!lrWxYz<_I)jnuFJItdq8V5n>o2OS) zRKUPVx!-=Y_m5d39L*2K=j6a<#XLW$dOu#uV_XkDExY%bi~UUku!C&DUOxyT=SCAl zizvA<#OpW6ym(`792eM zmCo?Hgpz}OFkJQ{Mi|H>IO~5ehb#;Fp#fr#_I%Y}>fpb1r0eDwRgt)_OgFr~5a7Dp zbvsJNM;fxwNwAx^bHW&%d<(1`D7ZuCF^0k?41KWtN)3&dmtG5iHiCEu?#fPygZrVX z%nvLy<80t>`9vyBzx)lgyZ^>9{;6Eo93Td|iCk>LT0k>sg4eIY_nXPQcCQT4D+=BcID`obvXU-jkfv%%q{}$Yim(_rS|)HL=yFgn1VGE_PMVAzi@RG$ z;Wq)hO16cFgAj^>MxS^bI9-`-PZp6oQ*rZJ2En)`B`3R2ovz(6VeU>Ay+iI44Jx1@ z;cvP{42Il_;$pMhF3*C7}a z6cpW!`~x)pvo{?)|8E=*4yRd8EYl6b@_AHQXD)avON#({P;l=osav#M8gDJTvI(L3 zN#CI(;BZqhfFJtaptPuufvxh-Y9f4^@SijWpoCv$eYnh4{@a&s1qmi>^Ol$FR-Sw>!WC;SChiD>fl3jqHBDMbwmY@dgD3 z8nQWX#4Et$4QR5ES z*A`~g>!Jx_$yr^N@Wh5j|1)v7Hph;{ByjK)kzv=#zr%HO=->0U8EYBR(a5mFj~s<^ z!@Kc))v23$N$LbE4&>4Q5$%IHMb;Etxqmihj@s_*GaeL85 zrwS4_ErXG$ezk9mEa*}Q2^X^|OWS#%HNO*s* zRH19mj@PLHe)DOycdyV&C0sct)UKxh6o57iYSjcn(uFMWO~lpu6Pc?e{b?cdo z@3yFYaSZ%E6s$Ho*F)Ec^S>so$s}VuC!zePQqH>^?%9N&em{NiJl^4%$UiacE)|iX zpS3VU`|T>Ol0&V~;U*HBw#OkM6rxP5WKf3j&NuWZ53^5&GS^ESF{}=l6MuY6NcW#o zee*=UkD>+C@o1_%s??c%&qmg zic+RNF;uz^5VC@8{03q(Hc2k*2eKR`bO!|PrAUpSZl0wgHiGBzlPAUy@q$F?3&6_G zf(q$jK7*@3ZgAb0%D*?s83Fhf(Jb^xa_IM3QBAr`3q+oCaH$qQb5DUAxw(c*@LV5D z0pt!CpI9I$erXWtucwsR{M=XSG1gZq0h>F!kkAX@D}6MspZ66Y-h~qVwRwAGQrb>+?$`(Z z!qWl2k>crRP5lKmEz;Z}+06I6%$ARgkg_b=#Di0)~jVWz*1` zHH88$8Q})6fxxHdv$d3ax3kg9pa~$v`RU>rdngKBS$TQ2tFy3RFhl|)>Nd}gTwG9S zMPm;{DSL1pTY=My0g4ge7F+;m336MW%_!|vgJ30q&Xh)cD^V5Tk31X6n0AQf` z(_PIzj~S^DMzP9p73qDSFHlO!f!96So<;}wA}8RKU|apoA0spFf2HNkMQG~>Q9Hp< z?tL8&h#<@=LPA42>mX}}cS^v-{Uh;o>pDe_r=YL!h|KmHCFX8t#t9yt;C`R&Uay#m z=zU%r%T6jOK+4+0Z_Hpe7u!@&DqgAqO!^s*Wy_V$7-1_UddtSk8v+x(CCgZ0MT{a7 zxNj>32%n*R$S7*-3wJNzxoQh2NW{dg9_UESdHgt0O4~Ph0E$p# zSUkFULsR+vX27lF*3Cl=Nc1P(paA7T0GJ18WijlMwqySN)qn~OLnj3hQtSW2)mO(w zy>(w>qGBTkq9`gh2nq-ym~d4>ML?xPknS!6OhQFL+5{9~=w?unE_KuaDUoLA9)@_= zLGSZC@9&TM`P|EenQxr4&)#dTz4oD#CzgxHKTCi0YAYLTamB5Ed$LCG6!A>BAlx~M zem=H90gc(#yqQUmDg=tz9kGa09 za4m1t(gX9S&$TkP5+7(gl;^o=3suz*?dO<%Jf(WUXa1kKVL2T}3h=>iQCYYLn?|w_H zwHmE+NP|9_ktPsVCXOAt6Qe@TM z%LnM`SS+LSLQ4Y$EBB_=-l#UMpzU09In7)ic@`~JsgqItn>AVE;hyWM0ANlY!j@#x~eT7ddX%gdf> zM*-Qvp%kXQTKDLcw3>B7x^rDSQ5PmdPE-Se`b8sP=oNVDz&_~RrKDTXWGC7&e(*E_ zPR~QuW%T3SI>3|7NtIGB5l^zmJ7bRWt|jtOjVya05ZHAM}!lOcga_h5P z*s>1t_+D!QrRNV++jbF4c88#P`g=@tcB{{I?AOIX(lzz7!&Vq0s3R4^I;mhNjCwo- zH8LL~A8mbFz#MFI>U(_GM|}0CZy=s zOqdJSe>6yP+R)~_=1JQmG{r55-RzqXa4R}8B)p4JgEO4{rXeUV7MNu#(;t9SjWW6dkquV)N?)5M3KIJ%e~j zalJK)VA3C}x1P|^6%9dtL;DZ+$-Q8xKRMggRP3{py#_M4f$v+7^%ifB*t&W1bsXHd z5)!q~U7eSt^{#WuIbIJ)l!NMyVElA!yP*}=u{+DhS^~9z*XV>aa4JeZWZdXH=3$?u zv2@ph77(d6U`b}6_Eks1>HcT)p9<;0U-48`t13zzXu{W|GFy}pnAxr(d+MdK;wnUz z^YT_Au&|NG2F8sU-imI5G8lP1V2oJi8gL%F0vmQ~;|mWB0s7sU{R*aZ&~!hI-jTug z4gkk5Fe3cFvgUe`>+T~@6l`8+SR?Kx44hu+s4d9AHmQrK%rM-*A535;k#vMEI(29E zuhbgzmtcZm^uOTcmmO{1-;Sd3h?8Fq8uD8>ct^96K#x{nkrFE^-2~DwWZzZw0q6E5 zSYnFRTFwDt-i8*JZ6I9`rv^W9DuS93ckJ7Q6s9fQrRO=~9>#Vnr5G!VTGW?SCFqe5 ziG*&;&YgF6tHxRW{>9z z>lwKSsW7^xiw|B3$mxqzS8=qZQ0TY7g8Rp+r6ua-FQQPYu}am~Co%N2WL|!meAUS) z{yqb<4sK@GYNPB&b-Q>zO3e4tmfSuv5xj?OL@wosv@&P>v|F3^=(j{Du^#(U~JMUp{VFbf{Z}^&IXNAv+;BeVDI+BSInvRY0-l|d* z@MvZ^PBGgqAq7Qg(S$A=!`gH!$^K8AxTTTahTf@6WTfPtZ9Betp=jX&>%!{It<-R+ z^U7;{<~-b)Y+lEG^TT_b10P{b4t`Rs{b$N0|CnFAdlqmHzg<@n$xfL1N!fP(H?8Gx2@VRf>5%qV~w{j zP&C8vY>C|rzhbx?5?NGYWS?ZX*CP!d=r80YxcWxt_RZl=t?NcjykY>TFF~xw^O8fl z_eLd_8!sJ@<-lO2^nQb~wG@hBxcj&f1;1xDAi+z|e}?Z=Y$ME)c!CVsbIP1LQWEtuqPKgcF)zKR8Jh1eVe-M<$n}}mBbiSB0%XF>tu@l0#^G+3b-AA+z5YXs!SIuO6 zus|Vp?!{a|>KNZI*4_87|9Qx#p6&RhZ8C0q=n>jN1NC^?B13-_jWq)5&+z|DYf_hx zMyv`B0rY#i%v>Z;A4 zO_nwzPOaLl;*F>RbJY3oakG$hkgS1(No?ID>z31~mXF+BxsA{lgE@;tx~{QQXgoULU+bFNjJM!GTwj!ccv^mKJe?7~Z9OB|)uBpc0nk4p3D ze#50?zhw1NORdfl5l5=&rJ3y_MHl&oezDr99Vo1bKm+^ek-xvqWcGH&@K;*7?vl)A ze?Wx7icu?nX4>sWt51=;4<}5o28X@V_&wB1hp-AC?^cB$OV?mq&QIk3AJKR??>$cH zYh5NnWnqT`7jp8$-FMkOz<<}IwS2fmvZ*+C^ra)A4go9WGNiC##iuTb7mWX9D*TMW zHALiAX~-Tk6;*p52L7~hFgh`&h6itLK9p7r!(u$N9<358dy;x{8AG~V4FPW&+4wLTjmGFVL- zRf7VQRatzlsF1QHtj;{Iqbz5maxG=xd&^HvjfS?)uSp%o&fPa}f+(| zCXMOnav1gBz_+>Lfj86OrZSa%oyvjm$-l)JmbhH*_=W?zX4fdFiro6O#jCL2{>2Lkt&f@v{WnA?(nj-uWYz z;a*sQL!TVzD3V^FGRK+t=#)SItk2Qsw*1wjRHa$)60r%oF5o2O|M1~atf)(g`giHf zYEw}G_4FgaJaA<1AVnC?Pf|nUWPS)RDBg(1|07Q03+&$NCz{ zPMifpp?~D$nh_2Tz!a&-UCa_G6KOrf9xoeax5}zhIDL8%@C5DYsmTe3*0e5)eW^B` z1Kc|iX5tii@D?8-&6(5p>*lhR8#a{Vb?;Dl_ms7)L#)o0^TA|cB+BlHLAG9sVfF^^ zg|9F;$#t+?>>Fx7*SB&!XrZGfp z1LMIUpFgGCy+g#Yy|{29dt(B;A;2Dj;BWN)X``S)UwM0&YV<^3-ZC7c!N5xsEgGaC zaPj49_I2lkQyf8 zY(ccD&UV@lMQe%)eI_E7hukjK*Tv=bh&^p~kak1=IKjja$P>(JM1jpf^+H$=O72uJ z_SqDw9rXy~jl%j1NbLih1}Dcu7*vc;WI#e)lGflJ!uVYdNaT0UX#JKyP~$!nls%aY z0h|;Ch7oQu*4DzL^%6%WkW8i6%Oc1KOR$@>D+(JJLD}P7NtHX)Qs237f0)Wfj%)yg zkSu1Pxao>PL&(VcuvOw6`+q-c?PZ9lJyX2Rac=GZGK#q1uM3T-_rHncikkhj9P87e zM6F!$BL2ilW<&Fp@62xg{QNi)yOV?sTIwy+KGb!;Y}$T{mSEi{u`^;cR!dsKrxWvrCnMac zk3$$D>5)!~p;S-SWywd35el{DpStlh=gDw23zIU>VvbpBC%*)0w$;5HT`yTTye)Td zYV`23ByX+&8nh?Ur!27K z{hLM-TS^jK%~lGn?v466=J->$Q|#)A$@xBO#oblnSn~WA2MhbJ$&X5Z6IdpFeZjoj zc`Lr%*V^p5AJ@r(~U^A%ovx#C9EC)dnzR<6bY|J%GBpGtVAm}{LU)hr5)b3Rs> zh0IZ)pw&jh=1ifXrfy}0ygJo(TXa8jvYO)skpd-E!x8-Rp_86fzvx-<|?VcL7)Q+NiSF|2F<#&#<(#)!hQul^YjOxF9 z;g@h=6#A8}o+nbTeZ)WF(ikD^>OH32ej=!+I{B{Ke`_Ac>M_Zv+~ps-)~xrDAx_J= ztl!RE6c?)R*_53iK+rgUE4x%A7CFW~osV-z-Qa3x+grck8iCHt>m(>^3M$U{FZVhH z+!A%u1Df%D$%iD&J)cD{?00ip)iBsJK4t$^gIAiPRr?55?qrWEyYb3-w~Ob7WevZi z={Y%JGfSZgw|A?Ez4|D4OT?Opc1H#bfyv4P)KlGk*YZ~u zcCBl=m}MZY5#jPAu_Z3bIo8=#ctl=wnrYImA~Savl1`Nv<)wR835QHiJW1y}Ih8g= z>HGO>;p1IOzR^24JSH-Ojr?V1_5I(DH0IQ*FKHaohMzy*6<@kX@>}c9de_%U^uoS3 z{?pl(Im4+1l7k+T9fP$V(SeTZC+GV%+Lj27bd9(DdPQmT7rW*9j~By2{}VfH-H@?r zkEt_nrERaGLF=}~^VhO8J(h0U@ayH9`&DTU>`N?i@3)0JUBmmhEU2>C^Tmy7K@~fX z!%qp$RLvFr2B{!2<(jtZUfLm^J5c`+vGs#F9DIsp^N)`>UDuE`)0iG97_`^YbM+a` zC&CP^eYE8-_AMH!D(Y>j6j`!2f^dVXgqtH;AU`xzB%go&+Xv@DIA@`6OZsHVlRZ;E zlYETPnL5_%_AR#IPNCX1>yffc&ZFx~eD~(=XEr$ymQHJL-J&BopK7k!%Gx+PSoqKu zYDDxZvZ7q}chkO{PLj&uGGmYw`{kHihx$p&DaRtAIS?Z>b^*4ga^p+hLCDJf}ZQt;H<(@elC+`&uUXF-5 z=pP^xIL#=0**)!diu2Z>ZJK-b;b(`8-Wa(KReM}IIKBVJM7pQ&m6ATDYA&X?4i}Xq zTI;3!9BQ`}wD)NU4akYhk#5~$rj|Qy&lQ|qzP*;P#ft*7dW=4F_-{YxAP{C=Il6sI z(;kauj!XR)MwV;jwMze(Z8@3~+g_g_E*j$RK1b&3R7brjb8roXR-0kA-#*I+t!7u+ zQp>lBPONF$|FwFQZq6-Y-ZL!JCEq}o?Juqp!{dzWe+8bv3%Bi8^V9Us{R{ehQuyi+WU}d@vX~ zxFS^d2jMY+v&F7K6QXruMh^}Rs^-N!2bY6Q3e<8h2BrhiKHD?sc!9tOA%7;EAY^yQ zk8}_WNYel?9zZkcEdgp{kilI{G3FA?8CvO3XSaqZfG@l`&vqgD>~&-|jkXd%1Dn7` zE$zJQ<}9hIakvh0oRKVkqP-vuGeF)y9B}eoChLzrnADBIShLCP=bsnTdsqIIuu?P( z=w9m<-wKrtb+htWcA#H7lIv=4T*urjCH@mS;2UR4nQ!v&%gvVC{h4qlq@`y@p7rtj z6FPtFiJ+IRsX^ZSJic9nXL!Y3A0!!8%s!j*qr7YygchOgdSB(TMSGZV?rOMr(@&~Y zD)yZBwtz{N{p^_*z+x8fs$8{${yHxW_L=;g8(h~AfF@96ZgXtDS^Yd*|HNQ41+%R6 zeDA$*?4L`aMWf9WU9NMYI88+jeVxLj>_X|cz1v6<<>7W^=>(-%sm|HQvHSJ*S>$CH zz1g18SisHJRW+W~%Fe|m$Dc%3dVAt)s(H#~2y(=!lz3?hqk2`zaSlYmk1b_q)-IW^ z5GDx~LXx7AQd)ht>wXJiHv2=S4Fl^_81?sx^;;_&=(kcUF;6`&@N2e*M4 zd;tgFNvAA(j|8Oy>^Cy~--I7UDyD}d;X>@?C+J@wBTZpVe;lP*aaq}?{|o(~^#0qk z0oZLnY5h3l(DMqV6d8ttG#JA0S?_NylPW^qPN+nb4!>@#H)oqIJvFg+``*AOZOIT& zviR;y6-h;R-CRA=P#R7f5Gxq$RRg8PsJanPbf$Y zK4JKcP6@cTICtSBQp6o$|9~7-#hca*{9hlA;Iap3X zFUlk64MD~5IQA){0ppEEmS~8WMe9S^jUUX@lJtvLMl?Z>K|q0gF!pY~JGH2i8kx3G zFaK~883bZ;1CB#&Pa_2FI=>N^3UmpdqO>fi7%~AFmv3{Pp0t<@k!#Lgd;P<;{qM!!cw7{Y5Wg=f%*=a^m_I4EcG&r>pN?X<#V%pz?Dq>t zn4bm>i>HqFNtdgbSkm<}RM7sD{iTLAXt>Yg=}2uHFsHKXUMLmcsr1s*Kfg6XfsFFw zCIk~~qyz?MhGv!*kVSc~7h8G_ARG!nwu4r`=K=z<_3%hB{(k4)y%(svvDn$!Q2nAA zZx(?`9=J8O0oFc;a>u^6zMFb&up+FQJq9&Sa1!$+1 zc`k9)nu;i!o-Xk{Lg#AhvbnbVZkRvTkah8;m4r@Ps!y%Etc|;7jyKAcbJ-_m%TCo- z=5jZbHDsaTAQDBcNxx)jYo6J3W=L4gbl;)ap`pd1ll`1-TDTL`{ON%HX09_2 z1G8liN3#)r*<+!^ck#8PXXQ`ijM?Ov&<&F2)tXCEJUB}t@tQNV9yn9|%Z*dMCg>IN z=ruJp*@TXl+Dv3S4MP0m9M|DO)wVC+UU)QmT3!!m3+V;|TKhH0P|^vLeJ~lIPKsGADwJa(Uo8M(O=r5i{`?C>rCH8$*Qt&+ zzzD9^XJ@efDTR8$2`oCv0l_o~gY$ZZ(*kXY3yY-8K4N!RckRGH=Y1HnLeLn*H+Z{< zpdNm2o<>MM(Agy|rPPLbm(cqFS<0)g83{Xh`egh6p z0nh=QvgW{!FY-*F0QiMIq&m9$)@R`RzN6ume+_@Zwa_#jxe_5Nx32}Zo=4zV@t7L9I zj8Jhetr{J7*)ZKwwrriK@qAuIwX!#y#ikA8>ka&a%+y2^+hdGe2dd8t7;64@EfBAF zi%~thWH)vC-WsiSAKn@1S$5xc6=&&bc8xBLof!u+Ay4{B=k^Tg*i@am zWym!5(puwMzZL7-_tttA>l;-1mh&98zIJMVfMuiW{0PMjfYEZBWJp&cd^s;GQ3W=U7kgv79)k(Qe(#p6sP8&v0aSI2@b1C zY~UFf?A+#hz;5BCODg9Tc@3vR@7Ai1issT-=8b!B(*bP}PHgXc^{PUa$u4Vd5tDi7 zyvu7tjeDVaX}#F!u-C*U?#~SA>`uMi_1S|TtK1$j)` zQx*+f_ad#7m}__w3Jawq19>cGG7u5WmmZirK)5#0c4BYdqIKwhes=U5A~yO!1htJs zL!6i`f!Ge>gw6t(NB$QE4>j3J5OCfR%omb13s+H8|6!oMeL-Ojpjk2GP;a(BL^@~j zWx&#pL#+j&8Qej=aH1ifUW*=CWFD9!cnb)#kbco}ka2`v2Cva0T?=~P(3X26{=b@_@j%NhbB_={@!wXH^ z{g#y5_ybHdU>JsgjzKHsZ~UPlbU~&K)G%1pp?RQ%XArJ{+(a%#L~l6Qkn}uOj+x5n zGsLKa9G6i8?2%9jyOOp65-@?G_S{?~5a(wMVe83n)@a__D<0POJ@k#Mh~Zm0%fYPS zzx^Uu~?DAWe=3> zW+N+=2qE*9h*_c;5kv!~n?#X}1>TlWjXMrpMVP%gNH58cAgV4}2GI@*JhqS)} z;awl|{a&>xjP8VV)aDbl$14JbaP7LFjcmy|>du1m&z9|hotz*+#W%F|+zR!C_ybBQq?A^JfM*GO`>>MsqQlqjnG( zr#F2LJNo-QSq%dd{LmB3U0v2t>zRJ}6YoXK?)aXXG{3u?Hq~52W?sx;{w3lWeA>LeTVUJO?}+k zZf2Yd3V!H5n9xqzcw2@2D9j(MeF+)S;`O3s3|BKzwX<#@6o{8%_Q+2YAn$!3Ih61w zpHbI511}2wQ8-3k-Y5TnJL-d|2c`oVJWXgG2Zgc-yB|(L`^$BWLBIwk-F&y-$6^Exf7dTED%1ieAUU5miO=7ySAg`!Rtij zTXW7HeZ045N6F*O>rd}I+kSe#yT>=rxIMxB@+_yretz4Stvz+6Est6sWvRrbH{Mzw znhMqp3JqS!RWLv&Ql4Z%gFZDN(=ip%VIm8lHIYhoRS6+Y_lh(EiC>uQ%PXxQC+FQ% zyBxJkEv97(1S*Xb@Ab(LxQ}xMj0=RZAM^4c2{($f;jcp8Bha8(inlFnUVAVuqm{ex z3bra{ufd-z!o(en-*1Qn*$!CL^W*bc!n2)6l$j(a}k zW0@O*KNJliQtd|%A2uFbVF4}(5*N~APNKJAxYI3FO(!qRzl#T51w{uDu5X}`B7@9& zMk(Bgw5=6rR3lM3K}3bs4CO{wq8_655QFaL(wl<=7&wBG^#)CLZ5Y4~_0)v`B;b^% zp;1N92RB+S4Z`8K-KF>v>qLev%zZotJ4E=|$fw-$+TW~na-N-|Irl~4CUt&dZa zEMmiIk=;KZxi?Al@Dmz@%<5?yq}^Sq{$g60ws($Qmf|u|G&F_qG|1VD&bJg-l&7gH z%;?m$g@YiK`%tlbv&?R=YfCJ75(|w}B;0fY2IHkL!KZ`cK$ya9O$vC=EVmV^NTref zXjD+Z^YKWz9;EAdd+vw>;CB>KEa>CxuhUtb{p{2l0SG+Xfz3^jKJQIg*+y^AZM(%N znJ$fRQD4fr$fRyLRa0wz$lmGxtot7`<8(Raj)+`+7Q+2)(UzZ<_uQgv}I zt=?q&W4N!+5+aK@#T^~CnGakin2EdB%IoN?Yj3&veX~4;zB5hpO?q6+ST@hwnq7*K zxOfVYquK&W!W1CV^Nq#XWb6Dqn;=Z&$JDMxDoStx!U>BUfA<%zx1$ka070)il$Jbr z{CMtM3q?PLsJ!}LrtWV&xD0WGd{9`PFQ=jsKr8g2Z1h+js>n6>EsP6yi84`kW5&4? zZ58Lbn|ljdmOnojvIG#tq`RQ27_96h;VU-S~bXLvC&3$&n+k^U*%7 zY@T!8N@H2G{Rf)G9?##YCI0_?t!R`}4cy*v5#7?EhaBSGcX*AHp2r8|JBd*|HgQ!| z)$GcoO^i$rNM&dD1}GOrWMBHzAwfa``M2v^4$b&HY`!NH^L^KLQDUHQ;^F4)W@|pW zh=!DRZ?^O-Izu(xOMd;F_XaGxs=qBacQ&B`XEqc`3+!(#5E>w@(SJVj&tc#wXaA>v z^*`VDQ7`eY;ojO9)KKVr#?t@u%X3dbYJbV$cgq+DlerA^7_n;>(<>Z)-SQk*iP#= zq&@NOzoNP?U@mMQT$d$h+)0Ze1zllBT=POvu~Cg*htJ$EO3g7u7)^fo*`roCdADAZ3H`Fmae^F-4aU+d1t$;y$i7|Lr0Ni6@%Ng1JnKSsl%xFocjht+hTo)Vda3wJV?kMq?bSl-YBTXI znN76h(pj}4)zg{+S540mi>-NY$-cFpm$VZn4zw4$-D`_7d)%h0HAFHN5AIu(yA zI>f1}CwX@``Q)A7JC^(9h7Rs5vj;A!jjr`(qQ0J8-D2jyz^!^TWsqS#)i7y$BPlN8 zu!~9tzk}W!Cij8Q@&ix2&PI_}dl^sWf+=3@|2{vwT)pEn*jy1l&9#o}T_iM_C~uy0 zEc(u>48aexyB|qw{C}%=L8DN0!XMK#?{z*hi{~GY|JNeq=nGoMf@RBQmg?p~)n@3= zOYjf(11FqAvB-eGcxwVfKK5p@~ggqZpXk*QcqqbK-y|I}bIS#JpE z&3=F1F6R;3$E7;QtekVM-%$B-_A= zTetdYsQgF-2lx6;Vik0RESl0dZBe6OKu!Yj@;~gR$r6|Z}oQ_*<-Ngw)+LUtY??~|2)Vk-FV)ZI^z^)TW^O$4uxT9y&cx0 z-<{D0I^@_-PJ>c^n>};?`{GQN=Cdkk}OFf?BW*%Qr|8j~oROCk&_cT+!l80fzHAM@>;~AEGctt+MkA*S*n*G`vZtn%BE6 zAJ06(9jl@HK51)fiye1X1;{r<>q}8IJwtu@p#lvO53wSNR12L&UtY>CV+$5FD?tzT zI#JWLXvSP-{d{@n{X2KijVxNVj_*^E@4p9=C9ze9XZZ4U>rMehy-9k|_?Dq@7HtUo zxP2rihiKp8G(v!`e?h|{kR9kw72-L)mcRJt(cit2e-Zc#MCat-It4hMX!wst(Vo*f zfPbdAn!t8s)dAcrpv#??61O7f1QuzD&O2CCt?D|k`PhwoUCg`K`#%?UN4E<;ENF(E zhvvm?!^n)0%@pRIdA#E&M6)+95(AV?NYK%F7mCcf@CxLDSGs?u9DTQv&z4BNkPYHb zJ=gw?SJ<*nz@cby8iz1BT{i)zLHy;|TBo+Kfml3=v!Br(g2q4S&VnSJtRLLR$6wt) z_iu0fg3TB9ql*EFE79CSivmqNB=3NC^Z|E55-nbJ7jecq-or!(HOGJ%K5+pXEV9|I z2Fp}La6B5cHq;CCaX`kK5emPEDdHD#_RmhO>n58YezG`h{%-!612U>fvST2**q`|( z^W8mKrY3qJAVu7+5L#sC6fHI7N|M;48rL1E{e_clMu9O_*Bv!`&^U|CiAUVp6Tr#J zjT1&t-Md z5~tgW9dY=XB`W4sCtuK1$v4xWGlnn5{!mZjXtAqXg9q0V8Zeo_6Wz96tIlIY`iSJE z9*MAu?%ox5+FH==)@+g(;s5GcO=)IaJq}Hz=baI_<6TcA6#Zi=GoSuwiO`TQk*cU( zs~9!s89gk|I^}z>{8Z>2t_Ij{KtT@nG*k zuFPZIQ-h>!Yo2^577~x@k&#R9!^*d|ZCr|oW*h1@KQ8jhn$=u+0m@ogOV%8lD|^v# zm9okAJZfxFsektkv6{JfUbdPe%#4r#=~QJeG}#yP;3ehk9sd-baenpJy zNA(5Uyu4&*dDRFwCdv2NqRr`lb3AwlTWD3GMse+T>`N{V5pbaG_GOHthkGEWC|NNo zy51w)`&>eC;NS%(4Gga)i4a$yUCuu8K%BuIHZ$<@tbOH6Eyd*)u<_+3P4m8GIB%L+ zx~lPHW`Q`mcVuZCCsgrS^<>eSJ3AE?6^9UXYxBJXkRS8VBQ}$XuQ&n!V*lb*HtSyip$D<|?ab50{KZ6#e2yCjbom+fTh>tB#Hi zLfPCuf#&SoCp(qyJrtBKeamYw*w%ZW>0ZCe*{(N~;prInEw@o(<&Vkt-Ld8)#?(3E zw%b8NY<$b z4^XHj6!S#|vD`&5yxFiIPr>PgORTY778mzP3RQ^>Yb z8~G&JGFDW#)PpVnL%{FaLtnbfjtD;fn1i1>esTovUDq6-7X|0?;kUcSRB<}6S>+$=x zER(MCl}WQ_)Bas0cGqX`aeBDo{$YQIFCDg9!^KNCq^11wljgiQ(IiOz25_{a{n(*I zn~#2PFTDAP=Dnk6Dq6_Fv1Rw}`#?U66y`NP0f%;*z%&HAxrR1uOJp84;Hrhe1OD-K zS&ViBz)iQ7@hU)gjWoIKuM+9#)Dq7fmz(4D{-mj^EJlv62E4sxz0|B?DWD4MJbONHS|p zPRIr}KUp(B(TK5BhAMr1v*O{NbPa!*VMljMt@)BH?waYJ<*G_jue2!U-c0>ntM5Ni z*&94CP?W%P(Do_&p?ZIcVP2$}ZMQ9Nib(>e5|Eh%|nyQ;&E;8Yel!>fs=28j>!vR}|e0927+rOr9wq#*!g zsCh=q>TSf?Z^Vi?`Rr1@2S{wq+cOlp%ePl_#$9jkt!)hN8<8!=Ci5I<{kE5>u1j9( z(w^AE1#5P5W|&(YhlY-HS>} z2229QN_V1v1+$<72OryMl#_JuI{M*(7wr__hS)kkKM-GWFm8}sbu77LS@0e6V zI#g+*)p0Bs$np1?Us^|08$1@Xs}!GJTFzQq+W2I!Tt#)Jbf=(3_VV(=IGIJ+=1@Gto%R-x`@uSg z2CKebN5MiUq5+n4yTWn%I#Q7pTwEsl+OyqM@#k-cHZWqrTAaMEKt zuSB~x(ZK!1h^aU*ab$GX)-d@B2WI}6xQ10(DNG-bMfTlwm9o7#H#8|P^NvqujK#ZJ!HY)x0|#&fw_H7I$ULC zVWI&e^egD_yJitS0hb3wUELQn#?9g8bHr440<(XW0RP%(7&LrIhv16{fHpYPejp-< z?i4zPjDv^sgQso;uK_T@(*l5Dx-?Lc5z7qNG;_U$8L#8_8Sg=IRNQ$XTYqb>?vHm3 zW#Mk@YlWY!apPr_Al_;>msVoLwVOfNc;x#$wJzx~L4KvxqxDYfTbgujHhjH0_#>CC zy_UKc#vyuN)6*Q&&m0O|BKGZ#d=mc>NAt7167?S2rT1v%W5u61c|yBFm~(^D4OTC8 z$+f4Cw#8peY*-MZIc)rbZ_6n;$@`H;$;Q>*&UPkBZJEK;%aSi1q*^popr5CsCJmyF z0S*M5nfACH=lH6O_&ibH6UvSaUNLfTQ($w1^#I^&ZP;w=xfp*9R61!DMlYn#4DA6u z>ahCl-z$%;(!@ilbGK9Zb55SKeS+qcv9U32!#m5jG+f-FTef=tLMTBJ40O>&ns?DGtf=o}X$u9U>GV*YxGK z#Mh|8>8fNq_EMEN`|5oobt}MBuB_ZT$XvtmR9H`djWeoJXUs-X*rTA(n|nWCPhr=w ziUpS&8p5Pgw|;(|SEqhjUax|F=BkaFjZChH_jiU^f_+}Zx3}l&qDoJ#QUE!PqdpRX z64aIFmm2YBqtkTt{G~iIDqKj(pu#;FMI#egsS^Wdz&ZkSC2rIx+n}=L02d3G-Vpz4 zeQf7u*FD0*UpqFJ{LLCpMgS3UsZ!rOfGYB&+{a0R??Ys4=7%w-_^HpPKD?e|b3AP3I6qGMCtqpxZ>A1x( znPWNdZC$v#)vKlf2kFqcN5V`@gsnP5OKB99Cw|-AFa7Ejz0x|nuu^pW5cj^a{@(rw zx5hE28sD&r)erlg!$b(=U;DwXyUW8tLkzWl$?Na^@-it+ko5ARubEkpi#F<6CY*nc zZ1Q@0ihaHKB9*eTZiFqjWna4CFNSm*jcR9qow_!Yg#t1`S4Dqh*SMBYj=5diD&xx|T%WdsFKWS28&7{(`}F(#dbsR|x~94ivm22{0&QIH z%$^ATDLA9#Rbsxk*mlw4FYfU&ABZfiOFrhLkv84d6S||Pz_YWdlEi8aqd<6v86>qx z@H|q8+WmDjf?&GV3Z+s4%PYmG+0$Jf*BldT?Ih@w!?P!|O{a5n0a{v%RcQRZxKjXN z$VpmwF>s4#QMtd}rSEn*>C-t}ot33<4V`fVJ^$k03ddTEzc+dDh?rTI;LzUH_e(T)+Og)gVuqav-Hz!}x<=!J=`Qp|t7_PBA*`Q|-2JU*rbHV^ zEq!3~Y|>EiMz_V;^x(TOLKr%9{^?A?=@6k`S-r9dZ-8L=WZ=W~Kegj_nl)YdF)kQy zW|yhz(dni3{z(bf2}EI`x+&b^Mn)`VPKlMCO1Yw}j>8YDXe-DrxR?9qoS`Oe%I5l? zVk{)o=Sg>FFZqhpGvUAgQz6XM3XMX?xod@|5ADn_v)^fAm8-PPoLGx?=$!k~w`DWgerke$&CYLi*D3*t)ttoUJBwXnpyiHQ9U~w(? zvQ{4x*PlbReWU4V8e%^i-1n{v;xB9w%n|in9orL`7e=SO9Hm{{W6;h9tGR>TK`Gb zRHR1K#*N(j2SJh5F z&$(`eH!7CjTCzbUZ{jgK z)~`P^P@U919IuD>S%lS8J2G{Dz!wl_>va z+Sj+0v5Z$Xu8;}m6$*ficE!fkA0k3j_M81?|7PL1C5JuxQ{x=g4o=nZ(@);^eNCzp z53v>1s`=RvXr;yK@!i0YR%_4evCZ^FdDw_k%<`4i}~!(R6c}ttJ|))8R14;bg(Ff`_1<1qCI(^BTEsYEsyb03S8t zzScAie&m*d15;kcutE6qfhCx*ymm1Ta^CG6n`g_@Y^&0^m=v2_67iqW#3KSH$F)sk z77?ebzo_^2Ga-g!68kmAK!W5j#nXW|w`k0JGI9RvzO?F(?&!yEN zI45#ynDYmms-@~9{^YcFT7S0n_jY>6E-Jrs}zmZn94``VH^SNSi!f7Tz)O z`Pjl5(Ih(>_YaC@MW=FU$51Z8j)j|x+25Q^;M>3E-IaP(|MrpgO}@N`KOLehk)i!+ zs$4^hK4l|!Dd<~Hql~6YztwpGb^Z3fQ6n4r9M}C0m#I$OQ!cy3QnLMF(t*4@JxW82 z8Z7lAL2q-^ouZW(73Xtlzf|K$*3ZFTd6Vmel2zk=#Q7~{d#{_as;aN_E2V?=tyJ94g9Rd-f+_g8Mdf?S#G1FJ8;WEoy!=Buhe=go&U`&!%tDHhi-+pzK!KAPi=I@a8Q!KPc$iH$I5gUZ8v|XWcYrf6`qm|n=I~%4N~?3=M58`GbDOd}n5N(b@IX zl>d|(e<|ifhod7=OV!J1{unHOuWPbR9#2;FryWKP&Ca?vFxeJ|k}6b#%^)e`eZpG` zBQEv0xU~G0gp0KmVh<`yv9Vt|m1M@X{=t0Tj--}2l%7`9k*=s7D+qbxsH`0BI&L>E zJt@I`_Kmejr&#vGutQU2B0ruvxF?(3&kxP5G|*{ndwFTNbXkS~MJ@LnwLi|C)*@Zj zGTCo~<{s_*0WSd$-X!KgNNEzt9Xx#CttovH373DG z#{VZ6m}l4i_5M14X-I!-+P@ErI@{;?P$I8H9RHv@&n5r{Brn;b)uv?%yG>O%=IcEz zHR?qtsi=d7)P&;n2SFw3v6GbbiV+g|`Hu&adu#o*0tEWTN5YeTZV=CoFz%(fO)-JAS7zq+%D3N2})P9c>QTrdnn;kY>sdz5#*fxq< zpu1RLR&VcVc-}NN%23Q1r()_dnr+I0m_q)!6JDH!OOq^mmm1UW_8Yq!8Ljhn)?04j zF*a{qM+ckhSdWcDA$7EMQ~icR>+e^Wy-|`45@NcsDQuKhkdfie-NPz~Vd8Wp_Y{nDeuC22a--1W<)73VWS3532DhsA8dH~x}n?< zr^2i;_b;L9^tzwvl59ciE@cn?{N_aU`>$zc(mijqB40oI2JM*f5lyTDWR(T4kEOd_Oaa9pU)cpOmk}F5ce|? zM2VveTisGdcU!fkU8o*wEvquFAVb1EVfn|DmD^r0ZGWB@(2(1_e@j@J*81grx5C|S zTe{RJWRJFL3k%E7ipX6~jYJhu>w3)bG;;$-*w3`rXKrUDDW1?t87KidDQy+3S$D`r ztu&-4@u|3nlvi4P#QWFZE~p5GlzLY;oPT+lD=wC+vfVFgpzX(o18=ng8;`RHQhdmv z*XIAx^%h`RZQa^1icJ_O9R`TBbb|uIrX{3H>FzEC6;T8c=@Jl-?v4kfq@}yNyXzkd z^*#H0&-t&*o#GQ~%{Av3_qaoX|L)z0U@z=%E_+Hpe)yOSXM46Lv?PdD5zY4G(4Y~q zna*UWJ3CIq>(8#P;_MNY*c66GE2KZ}VByL$Zgifwf94vVYS7hTCx6L3 zyewx|88w`D?iuwYS7LY`fUiAdQH=)FYi8R`;JS}I`O{ZkZy#JzLgU#V4W`tF*rY{y zNaVzA+KV`E&3DzP3QvxI{6iAi`8*hFcu2y*uFBi3^hALoj)uCLwo>JL zPFI~S!!-9L-_RT&@HmOhcc_^@t2=KqYj?8`+8)sH9BOeN4;Fhq7u;uD?g%yM%?;#M zEwGV5)d^m;*xVJ>aMdRcOJD?u+_3#SDG4{nuXGE40C$d{&ryOpje0*qA!3Nma`8 zwX)PLDl&{i8x%Y}WOacA3RZJ4hk>gR3r0GK`I^l_H=WkTBKUv-wNwvu2xr0*p>r4$ z12hki3mBsSsp>#+gjMq1OzZi2$0AD2(4Cr|d3Uw)_f!)j(>){Xs{>(@i+eL@WzL6w zyUEW&*q+}+8ykBLEC163+koBT+0n&5>o30E!W}F|>Nu_WB;03u3mr?eO(rh%;NU3+ zO-mA;y+)$$K^;hAwK@_<%;^*XV~R5mL$f(t?^9`xsGF)-ZT5<8FSSOUv`tVJm31}K zYG#G?=Z%N5nlqw#i|TXku3Sem>haO9({x76?L(VQhPQ*YonYb74IE$iD&x6;amXtj zAu;*m%?AnMgZn8xC-oU9^U=*va<@HO5(b`*;M%Q)Y_kd6a?NAo=Xj`V*yX+S4%w0x z_W$^5nf|Mk6o$h#%6H>iW3Xg0ead)l`T&1?_|AH)%Sq9KY*y0O^xtT~Ms8zQp%xFr zLCKt0$spC01*hjF>lzvB1?SiE8;qZ})_(8RS-J5;^~q9EEi%*Giv`vlEE^C3ak|p` z|LqPNzxFJU;Ppmts+Il9_OoZVlunrPUJKA;a$obyHR*ospMgEL@T3uj^oQkUI4iz; zsTBiCbipV$qmw75YRkWDg7H2zUkK1|(ymFiElQ9%dAsoQVG+NSMliO$9DO=1M)^-Z zW!X^K_}R{Kx<Cf3mGZ1<~psF?|AtchZko?n2#mPZ`k z5!7%Be`d^y08PaaK@hNg)l)kd zNZnslUjj8em?h|f92we;vkyV~0tXX5Fcd-Zc^61ef9wyD%o||yjg5^Vk{d+-g$U1( zC^Y9~PHa-1f57DsC@z!9De2=N^sLa!0m!`uIL%UTuH1Scm*68E{OrMqdz2I)6fbWO zPyb5Cp|88-A3&MWBe-Py8)ZO7eXE*+OJm}L{>lhj63zAMBt^=QaN zmT+y|1=ah@8!|G7xds;kX#(|6DyvwGEYOYF&0?(L*Q*s%&Q=_Iia4Ympd+NMuZhY5 z`-i(5=6lmcu64_2-CJ|&X9|yt!)W&`&pRJ;KI%%Lu~c6o%rzMfF-M(vYbvDa*0l^Z zg)wcv4=%gL*$1$ZSN*C^$!IfMr5h8szDHgfwFz97Qwqo@xGa4oi|&WT+>;+E)t_t~ zZ$Qvo0?iUNuw=lg5}{+O!#c9=K~N+5gF=tmJx;51b#qq zfJ6gNXJC#eE;bfCJgxgCmz#e^s7IB`EY=f+rz5zVh~n@9nEf>X*F`zk;5yKP5&_&r zD+P%aqJRO~7h;hZ&F2~dwoM4P2;7JfJ9030vH)Lq#D@zeav)d|&gelj;NXY}`6FPq zu|A)YAzNUkuHmxw1d03;XDAZ_TP{wJib3A_#Zg#OW3a?^L8^s#F~a-?DVP8oo6OOD zc5|6u8b00GhmozLBkJ^Cm;67J%oIFzQJ+Gdnp3J9jMjvN&H?d8%;wGb(F|g+KRT4n zG)Zi5(lWeea=#cx``o?99DqR; z?69QXL)lDlv?l+Se;~S=nM8Eg`Reou?r!RNaR3}A%)!YYb7W8u~OdcquVfDkDY{mdV_e58i?$<1V#%k3M^MnucoZq-E} z5s~QS^etIgAXJx(5+7mhazus82WH?xB9LnYUs5*FAQfH8bY&H{rSEdumQFeL@X6l_@#Ycf!bM_!bID%Ol|+rR zqpfM&v+Wa9b+!Qst>*#S2~ZrVcW+N6abJn)31FBGQ)r32f~L(Msi3t1H6N#23+KlO z;ZoLwibm^g&yA6dH;N;T_I(*C?5hj&Sm&h_{~(w`YzK+!R&M))I!tR|csEIihl3Na zFu=lD*Lpf7OPmR}Ymvt4p9u(XC4>>lRp6?{feQq%f;?Z{gD)>>bnD*a%2?BX!$3}xVlt+QoeO`HKnkYW- zn?s@*5JyzNk_bN{W+zh8oyKh8V1w{kn-EwE%xGX6Hxp)@J_dp}M8^LWd`^xJ;t~7; z4{FWEjmAqd*QQXvslIm(5!ECzs(ANuA53Qnxb0}+)8D&ur!q@$6x1zKTRobTG&C5X zW`R$32Jz(sManl2fq?H@4kWA6;$k3z$>CDR*)1o?FPmJ)3I&cLvu?vp@FuJU70ItT z8zdqCB&6sNy9Q!r$fCgfxdJVPz@#n248kPk+J6{3rDKRZY)=RR#bWkS(IjxmL=8PgZk5*kgC-0vgmh7q{a*efVp}WdfjcCtcKO|0eXQ zJ_h2R{#4$7!0P`nou5JKT47-!q8fVr8GJQCscrfjT1FuoH8AcFu}Xr{veLs@ti!#5 z7bpqmUpRhkC3PoizD4y)$ZGx0$bQ zj58?hH?!!u?DMg+rLSz;QHX!}`m9k84H@CDt&~|kX-@aS=lV3_7Extyow&LY8|uP3 zCAe%d)Skko$ug-f!ZmD9sXbhOvSlQ#R_}^TU3=kN1r8uklc7;h22E>8sYVA2%!tAg ziby8rI1~}e)4NBIQUG2!r(8+F7U}PETTb9N(n!=RZ8EhiF%~6(amgD`4%l^x`ogG` zW;%o-a&+-ztB>W`bzp|nPmJgt>N67@j)%i|nvnf_qnG(r{n^GiDEkvT2D;PaJ}A(I zXFCnu&%eK@W9+e!H4O8tAa+*0rCK^P7f$o*9jJZ6ms~wvI-9Bt*Kzf9=2}sXow(Fy zhHm#3*iEK|>iM1M zL~x~t@)U?5jQCdOGrW#VIIvYxBIj*le8(KfZ>mh#4$2yXcQnEE5m;Pi!6h0Qi4vhq zP(|(K-EzR;{L2Lpe^VEI1$nRR#*Ty=6k=Kr3y-xFz9Zvq7a*hHJW^7+;1oXaT!3TN zCae*eFsaupIen*3(PDifBs6&temmsvE`{SzkctU(^@=HJNm!wYIGKKDU;x%@a-Lss z-i8Zq4eY>k_}unA_C_N?^d!r*MtLu?R2+3Dm3*T)Br}#Hi_)efb(EVT_@jTQu1Jr{ z8d0YNH|y3enkUJmUFqq5ufJI*w`aY8P1u#uxEgcB8R-xdS+c{KKz99lOQYaL*>V?J zq}4L-tJIg%@Ax)`wYd=LdN&O#Jb$BR@Qsvv&wqEb#OFrcuMRe%FD>7_cMs>~b#vE$ zro?W|K}}sh(}Hw(N;^_Mkq;wb|GWbv=&r`;_CsI#&4s;diki=^%PHV)rK5s070t<+ z?s_yRKKlw>5@}4w^AN*nQ>09bOX~U^y;zOz<+Wx>;klXO(9!!sPy4SsHm$lSpu9u37~GR5jQN|?LY9f zO_rAsB`rkJ?F@Ilr@PEef|8ah*;$-9vJAlIDr69MKTfNd%5iRerDh83E5TMTGOY^h z4D^RO6%!FCi&w8vJ4~4?_mFBOSusr_sIO_CKVLR+o3%4ZJ>a^z?^s1l6@B-%NqMm! zVK*uYNCB%I8OF++RjnX$s$43KWK?Z}Nr5BiS55~7a}g~xGlyr({=3+mi8n;B*(o00 zIe6}$Z2v7dfoKX|M6kC(7$`g_$e4BA4mk3+3bh|k*&dD8d;mFCVn+@;+%q7$&sdeO zm#Vq^hYItTSb9dD9!J<=>?--~_t#Uprh8^k5!$ym5lzym_6iC(-~{3J-XA!n7M~lY zqnU~xzp&}}I=$?I^|8wptOa%HH&&KFBZ_m(5#A)-yaDyx8Q0>DI8~ARQsIK~I^-qW zi~6;x=7kH}st&uAc85i_7pvZGY7Ztd_hlLyrwfj3I?SH&CFQSAS@99oX{^vqX%xq2DDfR)71>Fb z+h6(JZ_(-qI;W5^P>meAFa3}rRw~(DIHxZ9`=t|duel4*9J{j`6c?V?wBF_q_wBhh5;%D;1}oe2vo?e zlx}1>vd?hjN;x>-OJh3*Ub!{CJN@A@vbx<@hDA_`B9r0f&4gXO*+(lb!R8}bA4sqA zqP=W30{ha)7zV#s9q${oCw5%o?t34VH-ar(Bf})Z_}F`50yJDLuUVsxULkK1qehHT zzWbX0SOVrJR+3xEJjb06p=rd>cNK;g|JlUS2E3BO1mS1E#qiKT_u{l$zDYi|!V4rz zLeJq*o4rXBYrEb%AG!np&%$(DlLWrPp5d5;LR#NXqBy<;#hsSik`k;5%4VDX=QAk> z20y+qgfdx^B2UIzoW|JfT7bmCyfOB%bEl~%oIvCEzytPweEJt!*A4(I#Rqj4CY5 zW-;%-_HuUi2K0meo+qSJKiekg?Wxf^(+OIAQQL_9B~y4`=@LVot^ViFj;6i0B@$?< z6_YE<(Y@3ps8Es4+vpa{YFEG^Y#hEo-w9u|fQ@KR9d8HAM_YH3^P{`d80JP>037cu{lW6Z^Kx1(p~i3@2TTX;>$cGn;edVnIKnGU~t7 z%rWonyd}W8z@mOEXFt2iMcdt|S(HUKJqtTLrBrl+QDB3Vd+@$(hW09kxh{Kz=-oLJ zrmhq{zmek}vpS93Zb}GZd0OU}%nSEO8K8}Fk(f6>-k64fp&||ZHk!#8DnzilIBuaAHdd9OOZ%(?% z`ObQVepRVJs`FjO_*mb|w{Bi-k$ldmSzhMK>EmpFj-iY(jBem$ zy11Wp&tg&>EmbAw75w*j0uj;r)8Key9yasBdvv?sJw(3*Y*xb|4yZDr?n?c+Y>tGpmx{Mk2cp= zhS8y??sl)N?;{r41JwkUsfh-w$yv)(Hkz^8Otp@jJ`?i8GOzG(-4WC+>S~!{c}y=q zV(WgrJQd}fG3g7a)%*AOLmtIB^)MSZgq*GGPL+v-$E*&h=IZp(5vF+b8dih)@HsP< z^XP*E*&0!d2y3?=I8E5 zstu(|kqy-#EoU0hyqfB0eRx1?$D0q!1N!B@8Q?lard%2dx@Da^x-}hwfwuOIB(`62dY4n{ZZ8@CF#Ue z4Emm7mr7kPa=XU_FRr34F5kJ!eQ0Fd)4y2Sq+ARCx)VbT2m)T}* zon$-O9n1%H6fzo*$x%5|Ig7y~B&Kn-lH=7$%o6xV7btOBEhc|n_A7rpepz!^1jZa2V3mVI0|SA>0V?|uGUba~xtDoxIooZFoW)Z5g_ z-N|)iBd%(rTTv!>rG57ytt$#P%EX?F#{X;fj5z#&M?DxKwg}jQS?68nQ)mHL;5Bu1 z+CbuRJ9GdN*Izi!5j+qe8>T3}qDm2%73>DTUV?>Ed!jU1uq1GmV6c$S|bT;e{^PMcaH z_eN3zmj24s11sGMp|$_Hmy;7(NEEQarKl}XZ(1-YRM4_>%VB7>pw{BpMeOB=ud<+f z*dCWVufeXpEx=|fddb57!TkSC9{epmN+|8w8|T~94M=WG=14;<4Pj@SDlW}jc>Fv( zUB?HZj!_##{Slp+5zQ~TWPB5UbFd;-w~Hv3PTdH8B0^e(o3d`>bIoyYW3ROXn2U0T zC0|b!RDCwUw+1H*i<(x78pD#`Y`13S6?{)u^VbQ6v&Y;q=_$N-0M4^fi5cI?b6-8^ z=l6*8Zv=KPro-} ze950L^_TGGY9f!%Vq?{7rRuw5#)21+?Ptwa+cAgMr{7Pzi=M(~3amHtPS57IHEI?S z>>C@;0;Hmk_WRU9I>w_M{7k*)!@-DZ%yDU|AtAzHK#2Z{@D}#k>r#zc{GlmFZ^~0L zxF-j-ftfbsYt2e`M`#w96H?NLi}iMu1EwA+0TLIjRiA}GeSU~g3BSU1&h~??5}I#6 zsqy9X6hr}aD))sSLFDKE2iuUwQGTV z?%{EXL`O+`5{#X-~-_k?{4#|_m*gZZOR ztbEtL)eq&KiZzf$a|HT?=#;^&FnrX#) z{y8hv->@(8(GlB$hQ6u#+(Fx0Q@=Io>A5KoefYaqS^r3r{JW{2TDnrbA^EW2*{k`_ zw(4adum2B85$BPW(K+uKEUAnhmIKQSTRyJk(rGu&*XI-9vuM}Peh;16mVT+BvZ#R># zYWAYWd;tv^+EjUM&)AGB+bs{z;IAyML(45ub7ktgdd>xHzQ~rO4sRa^Gc>L;-|z1( zArdZVyq;#5nQGt<;(e$Qlb1gS)8x;2Lk^q9^!2p|;9b%-eudUs3gaN=l zCSeN=15Zs;-v~01Uq+Q+fo!HKfsWf?IQ4qj#j@9sF8e5Yd2_bg-@9WP&0=kwg3bIO zd_aXocdvn!#n1*FWV+LXMK|w%BvBr9vD!w%be|AxZ|~T!9kFmVZK$cu);rRpenu;u zXlKu9M~g|+?q?a@qEnTSHrQ7jKf%^Q&#oJqBvW?9kB{*t1pZB~nKL`?s{w*W&Q(l4 z;>P(3=3pDEo=baH$1fC8RYZykvj+!rucQ5M62Sk+pHJ7w_X$2diCzhLM zcFW=}DVCX-3E<>2F)SB+i^&aU~`58|n+)(c5+_D9B-+kPWluW1O=)vBiJ69NGUg_n+rM ztp5yP_vjLQxwm40qjuq+Tmz;!3a)ss;2V*{+u6Cf5-iwMdur^ryfCHEaB*=(gJ?z?$!d$tu;HibS-)p% z2XaQVcZhpSQEf3zhRTQPCSAljq&OPhxOfWD4$gr6}mM9>?Vxwp~(HB?2A4;qa{cIbMvh6>Gj)WMIl^xzBUtY+pOm z&iX^MoJqN5fP<@dgX^xxyLbOgZ9(NF)0*b!Rje`CUB36*DHL zIC0=}6x$j!kKbD8%hqNv2O;m4A;p~1HQCo18CBP4hVOG)-l1T8oG4yOTXpR7?pe~7 zY^%`+_%LR_BosH^2z6hCe@^gkay~&k@Hb{xC$4@pR{8Yzc2ddPj)30 zWhUL)8))|>R9_yfy4e^E5ZgR-YByQtcd1S=bcvS1xfbLPH@I)@MJ1!lvari|HYMC~hQn6CT#%crPC8CnN3T3MKTM7epc1QHn> zn;ur@qdtz6vF(mCo0w#0Ztsx5TfO8dva+*v`b%|zmmJ%(u(lpix$y2% zrx9y_KE0IV6vpZLgC+Rq*V$05HNBoY+T(|=^Qr8KElzdf_A72^y!#)03S7I2(^6Fm zSckX8Y{Q6v6zxFKGLq2XIFQ)$Qf93^cZHK*l`wRR78M{NEoF{9H1v^uju-JhBIZ zuOy~J2iKd5aKrw7PcqzjAKX8W8j~;7P|uBx!`lc~Sl`x=1&o7X_Wd0q+)pN8#uwY6 zNYEalV$(eOC8B2Z_rv*mhs@a6*a{39+Xw~j3v%K9d1kdhKIrM`DJX30@|1&<6B4!F z+R#~p9~_MNY1A8U{{Athi*|N)H|f{OoDxw#Wl>C4V>Y9ETTpdlrvRBtC}eZk#+T( z$?9`?DyB^8!ZrWe<*y_Au37P9<*K{E%6V=X*H6(OS50a@GEDxy?Mp zt1n`G(ypSd?G@###|A7aVeTUs?+A{k`pbA}rln)l3(g3M7~g0H#zK%v#9g_pDzn7{4oV(SrW^N^+9|me4Ul~ zt?eTJ&{kV(htL7oZe$8Ao^R zDWDdgYz+4MJbv^{EbCX$MCh85*3Brk6}CY zaQyRs#2zq+R~@Fl#c-9|$f{i)d&sJo8uRkow4Ee&<_nrsxk>sy(kQVf0@ z!@BU<2eh5I5>a`V_)jjnsC~N~=eGDEKJff(g=;%4=>?t`;{%1x6!l1hw70*0J*++A ziVn`u7_)Y{XiHR}-1elbO9urhe>!R%%*WR$kWgo$@LN)4`UI=zY1&M{ar&#PtdM+wD^axP{mR z=oPnn%wCr}R3_W1a^~yv()5_c=&bos$)sLN={Ad(-DCPZurn=}&#dya!PXFWX(`%=%Og|iER5~gczSNBjNV9%i?@@F@R zd)7`x7KiTk{5A~@tIvQBa4=EPdmL@yPN7nXTFFxU?7b@rRZ3-zM zei_tEcy0ZVQ%0uE#$*R;gSTgN$vJR%s65f`V*@PTOW2oL^V4E{-*etdkgt!G2ru#3 z7!LNKe?}cNRnjeKnb}%DSd%i*B@M3Y*0>qt9m!LBrDl@bBs@`CN1X?$7pC|u_1@R{ zIY@*yp4++86oG=H+)T^Vv^k4+A!!ZOefTS$z)Veg~>QSKBhk5X%qgcSFk-kIiJ#3Z47 zd2sU*vKcxNtcyvNih(d9J$gz_+8y@G&<>h=kpcn&mo8tH@ln(>L4ASJ_p+>lVo(+i zp$27F=Gzk-@!$xSdI*gmj8qUQNk@l5R(J9fU+&3sh#hB0QYqqzdt2NVH}a1gL3i*o z;{uEE6$}=`T~0|tmzF+^;O}dO6vaD4ufS9^PsEwabqDK1PzL&Ko!MV`n9G4WbplD_PxcHqGtON&&kPS#`F<(e0{aTNu>v>LP0|)Wt(|O-d{Uxh!w2D5mgJ0c;QBKV57$jIH)sZ#CjwYWZ@5?aX^-a6=j*v0SAx~#> zZ@yiAzFLW;SD;4t-u#Ew-Q$6Th@Enwg=x)>WJmPn!6UD!6n4vrZS~uFgt4zz%UnD^ z*YN3$R8DwzOSiU|5{xlM>Q`RAsEL*)B@#7=U5G^@Sb27D*Sf~*M9F(Q!!K~ z-H?tMa>6DeT^1i-o(6K@RG+RiC~{@@2=Zr|!-Ii%7(&ZzK3sb4JOvL)+}NBD7|Kc| zGKXG}(ELV3U)}>&2QVHxQwUC;U~pX5*B9z>9wS??neevW9aAzgG7nErgiMvS2r($* zlaoR~iQPqlHG8w-7|YIRYHFgvParW706WaUBUt+;B15g{Yz4#zBg9L{{G5iI%JJT; z!mFO8lESsgxyP8)dmF(>-^he~_R|9XUtgt*hIJ_dS1Rj-U4)Rc2cC<1$JCpNKC6F@ zr7!Ys=80J>%Efv9Vw80?W zE=vd-9nqTZk%~bcS87`7&(M3SFO(^MZiU;UIUFCJfAzQ(?GhFig-HIQDCxpUD?04; zXD&Gq|C1iUSjXdv`(rkGAIQX#m454%3uY3$OT*6it(-U)OC?_zRJqz* zJOraCmC^&_DU3es3NAh~vW?JSB^ybp-BBtv@D~~pd6ON_X+0clAlbz7WTup1O>%1lw0>yr8tmV8 zo5g3bZxJmMx(2Ygvh-~X?rGcYS2I0#ZJp<4>ocN4hdnNwK`)ELP0rGjH0RTLyZu6y z+@mb7s|Wl0?XU(o=F0cyQ#hno>ZJI=89iO&<4GjRfm6d%-?5Wk$H8*fa0ov@2(p8N zgNV5$7*Dd)4dDE)j?ayu-<7kW#Wy>VwGpem@lX0QC~Og>8KP~^eA>YKPYCc`3-d*=U$l@x|n4+Kx#I) zE&h;9P7UQ4PJOFkeCFhK%l3O+aqIQeR`->$kz!fZ?*T&t7Z|tFI!<_2ly}BTPS9Gm%~F6%hJ^n?V3aGtY~(o z)&IPcu2yOj+0RO?ZETGGXhZnq1AFsRd3hEX^C!BmwCt)C3-2~6dItrl0Uyl%Xhklm z6a&rHNP%_O#tv$fGI!Fmt6g}}&rNmT1P0#XD#NB(2yu(T8)JY9=6v9X?jD%12YdU$vsr~@i(K)A*#I;5$wt#VjtBujZL z@6GVgfLx48(;7VW-OVVdlwK?jJNJg9!vTRNPd)RancEF*)|T-e_Y3Q_c2*<#w3qQu zBqF=MEBK2mria@&@6*11(%91$Q+F+Wq`0crAKkERGsR&J^r8g65;354jo_OJFgU9I zIhU3F-jRg#xS`h!x;v?CZE}i`l#dZt@N}j;sB~I`Zb4Iy&uf@(Lyh1?qrLt8U=1JS z)9tXL37 zH{RB0{<@A196UU{($Z3JPUq5ZjgrhQg)vu-{fY+M&L3c1v%0-4oTgxnbRFPo9vqB^ zc)~z)A(}z`_s+kMkEei!mLTnp4ii(&yYuK7_wM4)F=F}oA9?$@c*X}($mvxd;)gvn zJ+oYO&=zBA{i||TG^Yrj%JBT7`gO+uZprGb4KSvd4-AW2H_Dnm?Dc7BPl(PV)wZXIbPhl|u`F%p_^@ghc1Y@-P=sl3(Y>UtMps3l!N|ra*u8na%L7Tn^s_5#y^?V;ht$ik|1#8TnBkiV|)90nJMZEKzeiPW$>2pR}Mbio^%wC%4`)dc>)_vFkYt?^w z9oi$VkvyY_(Q^L@y=#PoK`p|kaMgp*PoF;dC|nzU0nW0EBPjkj)<1aCRbcY|JjZ?O zT;vVUMakK6c}O_AIMYgeltV#<-*bJ$z0dxVg&dfa|MB#t5eqV9cxsFd12 zW)hisd92D{4$Neq%7kF?O-R?Vxh)%u^Rldr_Y{Z^{nB$V>{j1=ic{!5e-3Sd-^5pi z6lT){-DzuHfLv7eh)jPPi9e zhLM`C0IBItZ^RmmpYFm-B)wOhw#&}S5?v1yXxYLC?n#9Rnd=vw;!X0R<++bH$}pv< z1H~APt*Eo29))U9Sr%K*V8c2PvluCYNJC9b&>)*6Z;+=F0H86=y>6wac2}*&j^*f&6FqyVjuV&?`eIDcB4EV_v1kXJvJdlTCxF}B4b*e+HG-P{) zpuv@RUOq!u>YAaKE5-xt$kylsU-Hm&yDe(yP=b!D>MR#0m26Dx6nTHQ~s&CDFep3IrhVaCllnFp^z@MQ5 z^=Hqx*WIlUQDWi!rm>r8I`Q}>?Wbr091$j)P92^ZDV+shfCNUBh%a6|P;*g;qh4~x zetxvB48sT<;&tLcu|O?HJG*=dE3)?=C2_O$TN^Yl`evDI-M@0HskK#5O-A*5R!-J) zfUP6SEWD#HY~58=;NG`6iK?OLPPAn{{i3T;YpY{|p<%LrjBCqLJ)oVljOM@y6sv(l?z?OfvABZSSGCY~ zOcGXtmoPnWB)NXQHO6t`#Bx2A-TvrgY?8n{%=L&frP~w^XO%AMja8Z30eZC6KYn;@ zn})?Gq*#&-`%%zzPr!i#g{SCQr z(aeUnDB;_orH_0GCR!sfJ%D zMg7fc9vS?#X)Gvm-F6!OVCR2&ggb&s$~pJZFJRuLrNvZK>=D8nb_)mlYzxTTf#-;T z(~2CtBXz3ZUDvZD#0#z<1*ZOjTpWmJZ37=co|DNW}b?;D$1=C8U5e6!k>2P@pOFYW(qM%{7 z7+tOBaKxjMzb!hF9M~u~8+V9lu_SQ97b%k@4{O^G9+}l58`jEos0Ia7eADHrR|Jk) zlRFXzc5>(X$;vcZM`dsTvG^b-T$8Q)S=IIQfxfh6VPOHot82KpK{hY`PDq->Kz4*= z(m~1(=y8x}HFCfDaCQbL2Ep6gYjt&%WzFgMkP}j_MA8)GAdO2U-$eA$BQy}QO6+UF z&_R^4+SwNwK)fL2-d=e9k5pLifkeC`p4csh_W&>mM0v?3xe%BQud&Z*Mbl93EMG+X z_3g21YTAo^87Dil#-K>|tdrHtP!#zF&qx5g8Nw7Vp6R-C#%!=$++To9roRY(xLnb2 z_X&x1-H(@i>b-@wc&9b`$-XWz$s#QF$3jBiEL9h#v6M?+kchhv7z|GL$MMpIyVW!* zX5667cv^XQ&WmSe@w{e>#%jD&n$e`CO~uSQE1{c=*GE*UTFTWqwboE(O4!wF$;jWbgccor zp3rNcVb0T3agKi@C(FnZKUMyr$E)2<)RC&Keh@+NTao$TeCrcLw5X#{pVF8!WN+1LMZe5C>-k3NJ33*+-BK3r*ZKxZl%il!7F&3bHmitR^qf z)6*Zq8-o>qC-|ewet&ug{!t4^4`e1YL9$>1Sjaj!I<|qP4&X)v#DrI>s;oT2z`%e_ z!u2{X?jGWw2`b6?PHE zo=VEfOs2z3qeKr%dLTD9K0n<=P$vFW&TmLC|EINrPU}B4}KvV2=T;fEK zU&AMr#>UGeU%#a9Yt4JQ>_R*0SJBBiw~n_tLvc081P&;s5O#wzRhww~<7QwwByPg= z1qRfZj`we6$T~-cwHM2(U_LWC5S^(iK^}6XkpLYkAl~sHf=0pszkmNObs*LU^@KP zO_c2xdn+LX47Qesq}mlfew>9H3_o<{k(SnNF!-zjXb|zK9k0Pa+Qp0v2IwXMp?F$k zr90gkEe(4QtgGp{jzozt7H_~2+98_Z0v6$G;W$ROTD_KtdcYzi08bBPF}wkZ*@=Ky zAo-gR--(RG_P3YBA!gFBE%rPd3Y52R-!>(h<|R+!*r&IwZ2wiIed(-9TK8md;F(CN zU>z>iY^ZN+FOPQ;T<^HEf~3{tkd zFQDU6(N=RH_zDAU%WW?&)HgfN{54-^T;d=4ng!yyrHVV69bKjlrAt@QqkcJ$GOXo~ ztbzU_%wFu5>a`{q%!uc*bHLOhp0QHC)f$k@PK2V6hR{+pkiz#{$HLa^*1isJpFdR9 z{cco1V}QXKDC54i8Tix@wCi+lGuIVGh4wS>mNrf4^hOUFzyH?%v^-c2x%IhFM$5@M zhBm^|GK6*Uufbc^hL|*^98z3jOd}x}JdW$H4|Z0p_csk8v|SqF;vhB9r+xx+=CO@U zuBGH#-ZAZbFRl zKUs=;hEVf2{8S3mKrnNPI^!MyDz&iCmF=cEG<7T zRXsS1e&-HM(l~LT4uA{qBS+3^J{$q?{I3FYO}I>Oko#E=0#t_vVah~Ex@yHM^i-uR z4@g~o3ZbeT*je1dv2k&)PPioDd;sG5czpn+Jm_`7skZ&=WAp@x&>s*$C(-@p(?crn zy31>JYCl;%ut)EdS39okQcAvv!~ENjdVbFR=GjMT*0gPNbV5Y4N=73PVbYwmk%vGTS zGsq9YE&cud9I?AFOp8@3vQkn}d0|X+a%QdC0A_I5*w`k6h5i5sAZaoXKuJ!5apiGj z+u7fBl*cDRKtq3k$~v>4AQ3WBCL01j0C63{n!rr^H@1cp$?xMJgA&eF3pha`MWhj? ze|-h!WC{uj5OIm+?(UAfilU}#jUWHt zg&iHjVJ)LxI<1YLhc(mkh~`h__|7jbF3z&^CGvM?pcp_=!E82C>c|YYgKe1~awCI+ z7z?aneHsrg&&?4~Wl;jOMUBOGHFuVq!8ofOHlfchh z5)2Tm&a}FUG)0-O#Y$n?EeI!legdqva~JruE7$WbOI2;Mu_ix@ZQP-=AYr=SH`NCx z^5iHVM=sST;uNJa!-D{rHk#$uD@H^M@}TzXuup*dP}XX~__^Nr?`-favv zT<81EN*We<;iuxTH6I8N(C^3Wrl^HQ<{&X16Yu*KC4>K-{|`FZeARk&*c5_qU4`mS z4BU$m=N=Xkc^;FmwVwK9caL8Su*@R632Y#q+?O`HxV^~TuuoS4)_C0O)3!Q4I?r1+ z81-Z`CbsTD-}ZO{=B+8TnmOL-Br0P-1pR-x7HzTh!7c-_*G~>{DsnzOov?g!WqM}j zPWpGc&fdP>Ors$MY!YtC=;e_BeofK{@tfMU9=Ce?`d*msX)*(KFhTdCBHI1ptKJ)Y zCHdx0%KE#!yNzJ#r9GIj;r-6%{~#!skDPEl{(Tv4Oh83YTQkDMjaWgzc@YD}3#>II z;s0q_zg-UkH0sgd^HpywFU2JJ?_DQpI}yD&2h@RA0>$3M$Ll7$|0??Lk#9IOWlz&3 z4Bz^O`9!AC-SgUvIl3x%>8iVESHlzmYv)JOBjMPdImaz(kC?do0d&R++h)p@(FcB+ zZW~gxwBs47>aig>&=7hT9F4~t+ZgqneW!d~J+Z4TeF4pCs!3{ujH|6sQu;@gCesTG zvI#~&xU+O>oB+D{3@ax;HL7)FhW^H_w3yzyH*>wl4^+~Epz>lgUVmU`rq(brpjmv1=esTqGa=k13a*(dBp|=7o*W!LiMZnaS}Zsm4ATx+?-51&B8Tu_LfAxwQCr89T+2}n_= z2q+&ABt4E3S@Vng->l=FfL%+zMnW6m_!MSg?G)+wZ1?R|1r$%^Nr%ed?Cdrv{p#c?s;qy^Q_NLhYA~q2ys&kNhyKE?XrwhyWZfbocjx|tg$JkHS6F}Kcpw?(>rKB&dPKzB z=U{v7)~ygm-u0Ey zH#5as5IlL!F)wwjK9pY_rDC^`pgg|v?ZxlFEFtgB7S0-hYxT5i#4_Ge*Xc#t_P;{hpP;h#mxr*lQXB!g|cgj}YRNX@Go%FTm7P zkoAihCwP>5DQ(MRb+V7WL+jVb>_)a;zj>3T)9&D+ayQVe=4IbnkyMQP){&4uWZjTg zb7oc@G{&^M+0~1U+a_|k@+&-#k&KX-7`ObZi6a*vzA(?$Vqo%rNt(~PJx+;NCDrHo zX7HxOnF(aj=QGIv{iG~-o(qaNir<_lKw;#CE|C}J9GwN$i`%Ayw_5TjaXPl13xFkmSL68z1rtz{V7s6&wSbje!kJHZ1=H_&P|X7B|wut zP)uJSA*qI0M9|Di-+k-tn>Sam&7Y|8A!YgcTEO&x24zsq{{Vq@Uw=QKufW$tKno^|@p@w4tNfyXF#vR` z2VJ*7E&&wyC1~~50F2W^Ma9dmJIi>mKu^#-dq1C;6pMN(2KIHC(nSJ!h~$9=h)Nkz zydI)}h{`J9)7`IHu9oZJy&}jvp`Uc9Z-p(ge3L|Ykex|U87|6s+5Kx0ZOfTMsq!iJ z58O|ae$fbSi&VW1s6H;crK|H#myKXP57ghd)`^(W`BaEJAvMLX%KsyFQg0(W&edn>?RSC%ZZflhCK~@q- z+t-Sd%d@<==>2Z?4dt~u3$}4nri_N)YTAgs4@LMu%d=q|2*}C|zbNriuq;LYLr%p zuh{*sX1-4~>@l5!`SX>K=f-_`;lxH9p^O^Qqr4YY(a-;@l)uQo-W9d>%Vf2rZinoU zg8TAJ_KEPS1H~J~WsXC3+o43DCHu@cb)bUszYCt&?5Ed$-^7T&5B|WBUsyOYGjqBe z(y$OgR{>y!?6JE5yWzl4rMHl!BEvrs@pc$H=yK2L!AMV-q8SQ#5;e48$x!D9U={C2 z#2o9`ZfWYgYWvNl{? zTnlLZ3Q8VCFb=2Y1`EpvH#Z#Z!d|o)c05=E8FFc{``ZQ-AJ-#K8+b?tZ*JH<{$W$O z_a)+!CFffOy}fi+M1=?3uuKxst*NI?Df5tnDrK=VNzNis0e7Adyfyz)WrM4r|H8fYYf@t>* z>SicSk|eH?5xs-8;SCD>&<}?w{@7QMG}*_1qaEV!2zguL>||IX;IX*wt<&~ZV)OU! zixd=%u>Zg=u-TreqRBGy`0_YFHQ)Rt2m)f-4N<>WZ)d2N9Q_R25LDnN2(F65;5l3?hOnQUX|kdks~$H0M~LUhFX%J~J{p`T(p?B2Z60 zSJ<_N%3nhNV%nl8k1>DJQ3nT|my69|qvtXf2@@CEFw{QKTh6F4)(#p2NETg&ZRE-MreQl^}{q8O;xL(y-f7E(N zz#xcqFzW`MO!j6?Vmlqwe$?a)oi}t=4y7#oHY#CFL}G|f)2!?fy?-pIG5p7xii?wS zJfGU{GdI{)B>0+PZ?}9Io_z65`TC7P^QEraE>}l9dxU%NuBSd|u z?J^@(H$sVBRbr8HcSiv@+d9Z`MVJ>+oNr;rk9-~yMxAoq3LB1d)oqa4y{&jn@D7cy z&QxMu5kN?cz zwE>pCv$NCn&4AEuq3`+6&-b~wxSsrR;NZrEXoMi(;7JRDx&_ujEB3*=Tb~5@d)kWC z%vPtke^2u0F)7~PD=z5Xo4mh1C+G=V;jL}@bL@Ia>aH_hlobv1`ljy5HT>?4!bsTC z;Sez^dq|c*>-e@D+vzigor&KAXVE9^iE4is-~+4*Wd%7E>2@$EO6eSBw^I3 znY1zdll6YE*w<%I85xuN0O^{RKQ(@MXM;Yx35%7VGuA}=`6v5-??KU^eoCj1D3O&` zUH#brdRgT|9-Io7L9H;rw7-zmc1{ue7^LEe0fF){R={A95CA%Zq7c07S=tD6`MO>2 z3bp;vIok(t)EvukQN&1pzW)l;b%qhvmzY$C03}_W@4W;fXlV2*0)mtm;PA5RVSJ`) zi9;atUu;W~r3L*^7r<)(Zb*4L9b!Qq8)US!w2;+U(Ea@Nfl-BnkB<)#RU-K3-ALuM zuTV+wD??*2U*H!Mqjkf^F&p^dI>pHWbvY9Nq%V%?8yR6}qn+H*XwLQ&g_`#Ezz-kx zuO2;zkFO0_YG0Y_ppJk<*xeYYL1R$K^M;|XCH`L5z8tTzW57`@BgN|UV}G)k4y=P% z24`ty+$bB8mZ3Jyo^QrKK(8OuK9iZ3eO=$z7^L>20tO^0B;wtIP~E;@ zHt<2v)%5>R7%*+BPAvO>eu(9B;n7pqixyM3rEaYl;oL;+IpVxb2LLndzX-n3NX@I4 zm^C=heMFJ0M38f5V^9@qU@6ZAdgH<)dHn)#QVmH0fZ*C=#WTMFDYDJgAOJm zU)aa8tfys02SvvBd(Fy@unHOj#EGl93Th?Rt9F}9&(Bc`81prOl+vxdyqs%`SvCJB z*U|4o3Sbt%PXnmxJL$NyxqQ6jFuy}+B2LNf5Tclv7;=7xUpiN0tv=RB-uMy$ZXOH0 zMRn{L65D4U&i2&Rz5n_1DNH580ogrLu!00#@EeH2gdl(=<+Eo2k*>%p7Zf8xpV{Rm z3VbA#hPc7rv8GR>2!*Bbr`_MU2OHkT!pce;2fQY405mU+AFF+Bh+l{p*Jm?=DOi>o;xT@+SvzjZ8c2v6Zo-8 zqs+G^WjtLT)Wo(JhVa^07muFtQdPXkLVWMrW5P1>$f)wq`qqo#=1<>witb&1^9Gf6 z!Y}N}ix*ug+nR7P$+;r3hx8Kl)0kYGtA1&xvR!;~>~l-C*&$Lr0v_Q$6q}Cnn>NEbRP;CjX1|eWU@<9rA7;q9Rhx1oS{Y zH~=Uag1g}Zv0;|^un_zQXvIVZD_C6&vd9;}NLIcj;52o`PMn3BJAGg&opzRMbTC0a zAetsM`wih)6cj8%Wf3Bh20R4FPHu#{0ax=B&~%`UmR43q04hQvdLYR=cLW~wn`p@cC~j!cQ<#1HS|v(fk#3T$UnLP7-#WR-85*lib(?(7$`X`lIHkWw?m*=O)C_#Dum5Br zNT9PBqOr9eo`HlZ9mboLI_mQDLF`PQ6iZX@;0H%d5>9G?>34seQjuhSUsW`C4B`S- zys0%H`jH}KkXH4ur)2K`JcX!W0rAXs92`E5S;m(6L7gSFr*i|8qXyVA-Ea3~g6h0I zNt>bntIqr+#0`Ma_-1K8zZcD9+*jxY=0~7DI{0%!#VMDhXBjdd30&5lbBxSR|V3RRbY2j7D?COLU1hO zAY(FyYO;z|AlZk&0N6V^()J|buy(fKo+c{q@27wOB~d!AD_a*IK5-3-%%CglYcT3r zAfAPML65wG7ZU#O-$w*Oz|^QiTeMTBJ$Z`|g(1+YNKQ>2vBW?QHyv-kJkk(GoYP?l ziFiJ6u#iuDfzoH|nP2ZA`lYrvhOXj(QP6__&<4L}@tB&7#d-#Zi%4y`m1Wij8s|j(~W)e_y0By0KLpx-mTTk6UI%5UR`X6F1444gg@fNF-*|B`l zuv6wRt9{=#xn;F~p?aU~@}L+e7l_X|&9+(fTg*~5Si@!Yo$_a+m-tEzb8*3T>CNOv z*M`@;1VGOM3fb-U3!3Ld;uLx8E*|lV&eTl0#LtsgQL}LcD%^8kOmIE+39s-lz&8ge z-8qx+SLYyTjvNXQ!TCR=>S|I7=aXoK5RM+Ej0C z?^Oyz0es&kdNO(cs{xNq2ke2-45{WNboRr0LDy%zj(woM_SsFG`1a9-s`E#bvX39f)wv<7RR8$V*89(F zVlT5Xk3R>HD2s}PM-;pM@(AKck?@z@aY@HuK1F~^wN-$WmK)lCh;XZy+P>=Omb??* z_{(fn%NL_!*DH57|D+0fQKzw5<46db=}DEnu8+D61^B`G1;!b6re>igow*tPv;P?j zd~(|ms7e50%sD?uIqhcTlRxNXh#Jg(m1{JbwFnzN=h!F$y@H-!$ zTnhSfO%@hVL4cG4JfB{LJ1!hf4*<@3$rjg%=%0DR4A{3A;G+_1TtEPYbFM5c=GJM4 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

UwY4^vD>W^RFnalkUpCeVPb&7enME8jqFVR^2 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 LD)KpUw;%ow442G8 diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..1b3f5df --- /dev/null +++ b/jest.config.js @@ -0,0 +1,206 @@ +/* + * For a detailed explanation regarding each configuration property, visit: + * https://jestjs.io/docs/configuration + */ + +export default { + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after `n` failures + // bail: 0, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/tmp/jest_rs", + + // Automatically clear mock calls, instances, contexts and results before every test + // clearMocks: false, + + // Indicates whether the coverage information should be collected while executing the test + collectCoverage: true, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: undefined, + + // The directory where Jest should output its coverage files + coverageDirectory: "coverage", + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // Indicates which provider should be used to instrument code for coverage + coverageProvider: "v8", + + // A list of reporter names that Jest uses when writing coverage reports + // coverageReporters: [ + // "json", + // "text", + // "lcov", + // "clover" + // ], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // The default configuration for fake timers + // fakeTimers: { + // "enableGlobally": false + // }, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // maxWorkers: "50%", + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // "node_modules" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "mjs", + // "cjs", + // "jsx", + // "ts", + // "tsx", + // "json", + // "node" + // ], + + // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module + moduleNameMapper: { + "^(\\.{1,2}/.*)\\.js$": "$1", + }, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: "failure-change", + + // A preset that is used as a base for Jest's configuration + preset: "ts-jest/presets/default-esm", + + // Run tests from one or more projects + // projects: undefined, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state before every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: undefined, + + // Automatically restore mock state and implementation before every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // A list of paths to directories that Jest should use to search for files in + roots: ["./test"], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: "jest-runner", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + setupFilesAfterEnv: ["./jest.setup.js"], + + // The number of seconds after which a test is considered as slow and reported as such in the results. + // slowTestThreshold: 5, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + // testEnvironment: "jest-environment-node", + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + // testMatch: [ + // "**/__tests__/**/*.[jt]s?(x)", + // "**/?(*.)+(spec|test).[tj]s?(x)" + // ], + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // "/node_modules/" + // ], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // This option allows use of a custom test runner + // testRunner: "jest-circus/runner", + + // A map from regular expressions to paths to transformers + transform: { + // '^.+\\.[tj]sx?$' to process js/ts with `ts-jest` + // '^.+\\.m?[tj]sx?$' to process js/ts/mjs/mts with `ts-jest` + "^.+\\.tsx?$": [ + "ts-jest", + { + useESM: true, + }, + ], + }, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/", + // "\\.pnp\\.[^\\/]+$" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: undefined, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, + + extensionsToTreatAsEsm: [".ts"], +}; diff --git a/jest.setup.js b/jest.setup.js new file mode 100644 index 0000000..2cc5f63 --- /dev/null +++ b/jest.setup.js @@ -0,0 +1,3 @@ +import { jest } from "@jest/globals"; + +jest.setTimeout(30000); diff --git a/lib/amm_dex_v2/math.ak b/lib/amm_dex_v2/math.ak index e8523da..ff2875f 100644 --- a/lib/amm_dex_v2/math.ak +++ b/lib/amm_dex_v2/math.ak @@ -1,4 +1,5 @@ use aiken/list +use amm_dex_v2/utils pub fn calculate_sqrt(x: Int) -> Int { if x < 0 { @@ -48,33 +49,47 @@ pub fn calculate_initial_liquidity(out_a: Int, out_b: Int) -> Int { } } +test test_calculate_initial_liquidity() { + let data = + [(1_000_000, 1_000_000, 1_000_000), (1_000, 1_000_000, 31_623)] + list.all( + data, + fn(item) { + let (a, b, lp) = item + calculate_initial_liquidity(a, b) == lp + }, + ) +} + +// Minswap Fee Sharing takes a proportion of the Trading Fee as Protocol Revenue. +// This proportion is defined by the @fee_sharing_numerator_opt variable. pub fn calculate_earned_fee_in_fraction( amount_in_numerator: Int, amount_in_denominator: Int, trading_fee_numerator: Int, - trading_fee_denominator: Int, - fee_sharing_opt: Option<(Int, Int)>, + fee_sharing_numerator_opt: Option, ) -> Int { - when fee_sharing_opt is { + when fee_sharing_numerator_opt is { None -> 0 - Some((fee_sharing_numerator, fee_sharing_denominator)) -> + Some(fee_sharing_numerator) -> amount_in_numerator * trading_fee_numerator * fee_sharing_numerator / ( - amount_in_denominator * trading_fee_denominator * fee_sharing_denominator + amount_in_denominator * utils.default_fee_denominator * utils.default_fee_denominator ) } } +// Minswap Fee Sharing takes a proportion of the Trading Fee as Protocol Revenue. +// This proportion is defined by the @fee_sharing_numerator_opt variable. pub fn calculate_earned_fee_in( amount_in: Int, trading_fee_numerator: Int, - trading_fee_denominator: Int, - fee_sharing_opt: Option<(Int, Int)>, + fee_sharing_numerator_opt: Option, ) -> Int { - when fee_sharing_opt is { + when fee_sharing_numerator_opt is { None -> 0 - Some((fee_sharing_numerator, fee_sharing_denominator)) -> + Some(fee_sharing_numerator) -> amount_in * trading_fee_numerator * fee_sharing_numerator / ( - trading_fee_denominator * fee_sharing_denominator + utils.default_fee_denominator * utils.default_fee_denominator ) } } @@ -83,32 +98,32 @@ test test_calculate_earned_fee_in() { let x = calculate_earned_fee_in( amount_in: 100000000, - trading_fee_numerator: 3, - trading_fee_denominator: 1000, - fee_sharing_opt: Some((1, 6)), - ) == 50000 + trading_fee_numerator: 30, + fee_sharing_numerator_opt: Some(1666), + ) == 49980 let y = calculate_earned_fee_in_fraction( amount_in_numerator: 100000000, amount_in_denominator: 1, - trading_fee_numerator: 3, - trading_fee_denominator: 1000, - fee_sharing_opt: Some((1, 6)), - ) == 50000 + trading_fee_numerator: 30, + fee_sharing_numerator_opt: Some(1666), + ) == 49980 x && y } +// Calculate the amount that traders receive after swapping @amount_in. +// Each swap incurs a Trading Fee based on the input amount. +// Refer to "formula.md", section "1. Swap Exact In" for the detailed formula. pub fn calculate_amount_out( reserve_in: Int, reserve_out: Int, amount_in: Int, trading_fee_numerator: Int, - trading_fee_denominator: Int, ) -> Int { - let diff = trading_fee_denominator - trading_fee_numerator + let diff = utils.default_fee_denominator - trading_fee_numerator let in_with_fee = diff * amount_in let numerator = in_with_fee * reserve_out - let denominator = trading_fee_denominator * reserve_in + in_with_fee + let denominator = utils.default_fee_denominator * reserve_in + in_with_fee numerator / denominator } @@ -118,72 +133,78 @@ test test_calculate_amount_out() { reserve_in: 25434557769208, reserve_out: 413300185707175, amount_in: 1000000000, - trading_fee_numerator: 3, - trading_fee_denominator: 1000, + trading_fee_numerator: 30, ) out == 16200168971 } +// Calculate the maximum amount that traders can swap to meet the expected rate between input and output. +// Each swap incurs a Trading Fee based on the input amount. +// Refer to "formula.md", section "7. Partial Swap" for the detailed formula. pub fn calculate_max_in_swap( reserve_in: Int, reserve_out: Int, trading_fee_numerator: Int, - trading_fee_denominator: Int, io_ratio_numerator: Int, io_ratio_denominator: Int, ) -> Int { - let diff = trading_fee_denominator - trading_fee_numerator + let diff = utils.default_fee_denominator - trading_fee_numerator let numerator = - io_ratio_numerator * diff * reserve_out - io_ratio_denominator * trading_fee_denominator * reserve_in + io_ratio_numerator * diff * reserve_out - io_ratio_denominator * utils.default_fee_denominator * reserve_in let denominator = io_ratio_denominator * diff let max_in_swap = numerator / denominator expect max_in_swap > 0 max_in_swap } -pub fn calculate_amount_out_fraction( - reserve_in: Int, - reserve_out: Int, - amount_in_numerator: Int, - amount_in_denominator: Int, - trading_fee_numerator: Int, - trading_fee_denominator: Int, -) -> (Int, Int) { - let diff = trading_fee_denominator - trading_fee_numerator - let numerator = amount_in_numerator * diff * reserve_out - let denominator = - trading_fee_denominator * amount_in_denominator * reserve_in + amount_in_numerator * diff - (numerator, denominator) +test test_calculate_max_in_swap() { + let max_swap_amount = + calculate_max_in_swap( + reserve_in: 1_000_000_000, + reserve_out: 1_000_000_000, + trading_fee_numerator: 30, + io_ratio_numerator: 10, + io_ratio_denominator: 9, + ) + max_swap_amount == 108102084 } +// Calculate the amount that traders need to swap to receive the exact @amount_out. +// Each swap incurs a Trading Fee based on the input amount. +// Refer to "formula.md", section "2. Swap Exact Out" for the detailed formula. pub fn calculate_amount_in( reserve_in: Int, reserve_out: Int, amount_out: Int, trading_fee_numerator: Int, - trading_fee_denominator: Int, ) -> Int { expect amount_out < reserve_out - let diff = trading_fee_denominator - trading_fee_numerator - let numerator = reserve_in * amount_out * trading_fee_denominator + let diff = utils.default_fee_denominator - trading_fee_numerator + let numerator = reserve_in * amount_out * utils.default_fee_denominator let denominator = ( reserve_out - amount_out ) * diff numerator / denominator + 1 } -// Calculate which amount will be swapped to supply enough amount for depositing -// Refer: https://blog.alphafinance.io/onesideduniswap/ -// Final formular: +test test_calculate_amount_in() { + let amount_in = calculate_amount_in(1_000_000_000, 1_000_000_000, 1_000, 30) + amount_in == 1004 +} + +// According to the constant product formula, depositing to the Liquidity Pool requires that the supplied amount of two tokens be equal to the ratio of the Pool's reserves. +// To accommodate both the Zap (depositing with a ratio of 1:0) and depositing with a custom ratio of two tokens, a portion of token A needs to be swapped for token B, and vice versa. +// Here is the final formula to calculate the necessary swap amount during the deposit: // swap_amount ^ 2 * ( 1 - f ) * ( amount_out + reserve_out ) // + swap_amount * ( 2 - f ) * reserve_in * ( amount_out + reserve_out ) -// + ( reserve_in ^ 2 * amount_out - reserve_in * reserve_out * amount_out ) +// + ( reserve_in ^ 2 * amount_out - reserve_in * reserve_out * amount_in ) // = 0 +// Refer to "formula.md", section "3. Deposit" for the detailed formula. +// The formula is inspired by Alpha Finance: https://blog.alphaventuredao.io/onesideduniswap/ pub fn calculate_deposit_swap_amount( amount_in: Int, amount_out: Int, reserve_in: Int, reserve_out: Int, trading_fee_numerator: Int, - trading_fee_denominator: Int, ) -> (Int, Int) { let x = ( amount_out + reserve_out ) * reserve_in let y = @@ -191,25 +212,39 @@ pub fn calculate_deposit_swap_amount( amount_out * calculate_pow(reserve_in) - amount_in * reserve_in * reserve_out ) let z = 2 * ( amount_out + reserve_out ) - let b = ( 2 * trading_fee_denominator - trading_fee_numerator ) * x + let b = ( 2 * utils.default_fee_denominator - trading_fee_numerator ) * x let a = - calculate_pow(b) - y * trading_fee_denominator * ( - trading_fee_denominator - trading_fee_numerator + calculate_pow(b) - y * utils.default_fee_denominator * ( + utils.default_fee_denominator - trading_fee_numerator ) let numerator = calculate_sqrt(a) - b - let denominator = z * ( trading_fee_denominator - trading_fee_numerator ) + let denominator = + z * ( utils.default_fee_denominator - trading_fee_numerator ) (numerator, denominator) } +test test_calculate_deposit_swap_amount() { + let result = + calculate_deposit_swap_amount( + amount_in: 5000, + amount_out: 2000, + reserve_in: 1_000_000, + reserve_out: 1_000_000, + trading_fee_numerator: 30, + ) + result == (29932544594688, 19979880000) +} + +// Calculate LP Token that Liquidity Providers receives after supplying @amount_a and @amount_b pub fn calculate_deposit_amount( amount_a: Int, amount_b: Int, reserve_a: Int, reserve_b: Int, total_liquidity: Int, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing_opt: Option<(Int, Int)>, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, ) -> (Int, Int, Int) { let ratio_a = amount_a * total_liquidity / reserve_a let ratio_b = amount_b * total_liquidity / reserve_b @@ -221,29 +256,18 @@ pub fn calculate_deposit_amount( amount_out: amount_b, reserve_in: reserve_a, reserve_out: reserve_b, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - ) - let (receive_amount_b_numerator, receive_amount_b_denominator) = - calculate_amount_out_fraction( - reserve_in: reserve_a, - reserve_out: reserve_b, - amount_in_numerator: swap_amount_a_numerator, - amount_in_denominator: swap_amount_a_denominator, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_numerator: trading_fee_a_numerator, ) let earned_fee_a = calculate_earned_fee_in_fraction( amount_in_numerator: swap_amount_a_numerator, amount_in_denominator: swap_amount_a_denominator, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + trading_fee_numerator: trading_fee_a_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) let lp_amount = - ( amount_b * receive_amount_b_denominator + receive_amount_b_numerator ) * total_liquidity / ( - reserve_b * receive_amount_b_denominator - receive_amount_b_numerator + ( amount_a * swap_amount_a_denominator - swap_amount_a_numerator ) * total_liquidity / ( + reserve_a * swap_amount_a_denominator + swap_amount_a_numerator ) (earned_fee_a, 0, lp_amount) } else if ratio_a < ratio_b { @@ -254,29 +278,18 @@ pub fn calculate_deposit_amount( amount_out: amount_a, reserve_in: reserve_b, reserve_out: reserve_a, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - ) - let (receive_amount_a_numerator, receive_amount_a_denominator) = - calculate_amount_out_fraction( - reserve_in: reserve_b, - reserve_out: reserve_a, - amount_in_numerator: swap_amount_b_numerator, - amount_in_denominator: swap_amount_b_denominator, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_numerator: trading_fee_b_numerator, ) let earned_fee_b = calculate_earned_fee_in_fraction( amount_in_numerator: swap_amount_b_numerator, amount_in_denominator: swap_amount_b_denominator, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + trading_fee_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) let lp_amount = - ( amount_a * receive_amount_a_denominator + receive_amount_a_numerator ) * total_liquidity / ( - reserve_a * receive_amount_a_denominator - receive_amount_a_numerator + ( amount_b * swap_amount_b_denominator - swap_amount_b_numerator ) * total_liquidity / ( + reserve_b * swap_amount_b_denominator + swap_amount_b_numerator ) (0, earned_fee_b, lp_amount) } else { @@ -284,6 +297,36 @@ pub fn calculate_deposit_amount( } } +test test_calculate_deposit_amount() { + //swap amount is(29932544594688 / 19979880000) ~ 1498 + let result1 = + calculate_deposit_amount( + amount_a: 5000, + amount_b: 2000, + reserve_a: 1_000_000, + reserve_b: 1_000_000, + total_liquidity: 1_000_000, + trading_fee_a_numerator: 30, + trading_fee_b_numerator: 100, + fee_sharing_numerator_opt: Some(5000), + ) + // swap amount is 29826937927508 / 19839600000 ~ 1503 + let result2 = + calculate_deposit_amount( + amount_a: 2000, + amount_b: 5000, + reserve_a: 1_000_000, + reserve_b: 1_000_000, + total_liquidity: 1_000_000, + trading_fee_a_numerator: 30, + trading_fee_b_numerator: 100, + fee_sharing_numerator_opt: Some(5000), + ) + result1 == (2, 0, 3496) && result2 == (0, 7, 3491) +} + +// Calculate amount of Token A and Token B after Liquidity Providers withdraw @withdrawal_lp_amount of LP Token +// Refer to "formula.md", section "4. Withdraw" for the detailed formula. pub fn calculate_withdraw( reserve_a: Int, reserve_b: Int, @@ -295,15 +338,29 @@ pub fn calculate_withdraw( (amount_a, amount_b) } +test test_calculate_withdraw() { + let result = + calculate_withdraw( + reserve_a: 1_000_000, + reserve_b: 213_231_211, + withdrawal_lp_amount: 123_456, + total_liquidity: 12_345_678, + ) + result == (9999, 2132298) +} + +// Determine the quantity of Token A or Token B remaining after Liquidity Providers withdraw @withdrawal_lp_amount of LP Tokens. +// Following the withdrawal, one of the Tokens is exchanged for the other. +// For detailed calculation, please refer to "formula.md", section "4. Zap Out". pub fn calculate_zap_out( withdrawal_lp_amount: Int, reserve_a: Int, reserve_b: Int, total_liquidity: Int, a_to_b_direction: Bool, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing_opt: Option<(Int, Int)>, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, ) -> (Int, Int, Int) { let (withdrawal_asset_a_amount, withdrawal_asset_b_amount) = calculate_withdraw( @@ -320,15 +377,13 @@ pub fn calculate_zap_out( reserve_in: reserve_a_after_withdraw, reserve_out: reserve_b_after_withdraw, amount_in: withdrawal_asset_a_amount, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_numerator: trading_fee_a_numerator, ) let earned_fee_a = calculate_earned_fee_in( amount_in: withdrawal_asset_a_amount, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + trading_fee_numerator: trading_fee_a_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) (earned_fee_a, 0, withdrawal_asset_b_amount + extra_amount_out) } else { @@ -337,29 +392,60 @@ pub fn calculate_zap_out( reserve_in: reserve_b_after_withdraw, reserve_out: reserve_a_after_withdraw, amount_in: withdrawal_asset_b_amount, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_numerator: trading_fee_b_numerator, ) let earned_fee_b = calculate_earned_fee_in( amount_in: withdrawal_asset_b_amount, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + trading_fee_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) (0, earned_fee_b, withdrawal_asset_a_amount + extra_amount_out) } } -// Base formula: -// ( amount_in - swap_amount_in) / (amount_out + receive_amount_out) = expect_io_ratio_numerator / expect_io_ratio_denominator (1) -// receive_amount_out = fee_diff * swap_amount_in * reserve_out / (fee_denominator * reserve_in + fee_diff * swap_amount_in) (2) -// (1) & (2) =>>>>> -// a * swap_amount_in ^ 2 + b * swap_amount_in + c = 0 -// Where: -// - a = fee_diff * expect_io_ratio_denominator -// - b = expect_io_ratio_numerator * fee_diff ( reserve_out + amount_out ) + expect_io_ratio_denominator * (fee_denominator * reserve_in - fee_diff * amount_in) -// - c = fee_denominator * reserve_in * (expect_io_ratio_numerator * amount_out - expect_io_ratio_denominator * amount_in) +test test_calculate_zap_out() { + // amount out (9999, 2132298) + // 9999 A -> 2104508 B + let result1 = + calculate_zap_out( + reserve_a: 1_000_000, + reserve_b: 213_231_211, + withdrawal_lp_amount: 123_456, + total_liquidity: 12_345_678, + a_to_b_direction: True, + trading_fee_a_numerator: 30, + trading_fee_b_numerator: 100, + fee_sharing_numerator_opt: Some(5000), + ) + // amount out (9999, 2132298) + // 2132298 B ->9801 A + let result2 = + calculate_zap_out( + reserve_a: 1_000_000, + reserve_b: 213_231_211, + withdrawal_lp_amount: 123_456, + total_liquidity: 12_345_678, + a_to_b_direction: False, + trading_fee_a_numerator: 30, + trading_fee_b_numerator: 100, + fee_sharing_numerator_opt: Some(5000), + ) + result1 == (14, 0, 4236806) && result2 == (0, 10661, 19800) +} + +// According to the constant product formula, withdrawing from the Liquidity Pool requires that the withdrawal amount of two tokens be equal to the ratio of the Pool's reserves. +// To satisfy the expected ratio between Token A and Token B after withdrawal, a portion of token A needs to be swapped for token B, and vice versa. +// Here is the final formula to calculate the necessary swap amount during the withdrawal: +// ( amount_in - swap_amount_in) / (amount_out + receive_amount_out) = expect_io_ratio_numerator / expect_io_ratio_denominator (1) +// receive_amount_out = fee_diff * swap_amount_in * reserve_out / (fee_denominator * reserve_in + fee_diff * swap_amount_in) (2) +// (1) & (2) =>>>>> +// a * swap_amount_in ^ 2 + b * swap_amount_in + c = 0 +// Where: +// - a = fee_diff * expect_io_ratio_denominator +// - b = expect_io_ratio_numerator * fee_diff ( reserve_out + amount_out ) + expect_io_ratio_denominator * (fee_denominator * reserve_in - fee_diff * amount_in) +// - c = fee_denominator * reserve_in * (expect_io_ratio_numerator * amount_out - expect_io_ratio_denominator * amount_in) +// Refer to "formula.md", section "6. Withdraw Imbalance" for the detailed formula. fn calculate_withdraw_swap_amount( amount_in: Int, amount_out: Int, @@ -368,16 +454,15 @@ fn calculate_withdraw_swap_amount( expect_io_ratio_numerator: Int, expect_io_ratio_denominator: Int, trading_fee_numerator: Int, - trading_fee_denominator: Int, ) -> Int { - let diff = trading_fee_denominator - trading_fee_numerator + let diff = utils.default_fee_denominator - trading_fee_numerator let a = expect_io_ratio_denominator * diff let b = expect_io_ratio_numerator * diff * ( reserve_out + amount_out ) + expect_io_ratio_denominator * ( - reserve_in * trading_fee_denominator - diff * amount_in + reserve_in * utils.default_fee_denominator - diff * amount_in ) let c = - trading_fee_denominator * reserve_in * ( + utils.default_fee_denominator * reserve_in * ( expect_io_ratio_numerator * amount_out - expect_io_ratio_denominator * amount_in ) // a*x^2+b*x+c=0 @@ -387,17 +472,31 @@ fn calculate_withdraw_swap_amount( ( calculate_sqrt(delta) - b ) / ( 2 * a ) } +test test_calculate_withdraw_swap_amount() { + let swap_amount = + calculate_withdraw_swap_amount( + amount_in: 1_000, + amount_out: 1_000, + reserve_in: 1_000_000, + reserve_out: 1_000_000, + expect_io_ratio_numerator: 2, + expect_io_ratio_denominator: 3, + trading_fee_numerator: 30, + ) + swap_amount == 200 +} + // return earning fee(a,b)+ amount out(a,b) pub fn calculate_withdraw_imbalance( expect_ab_ratio_numerator: Int, expect_ab_ratio_denominator: Int, reserve_a: Int, reserve_b: Int, - trading_fee_numerator: Int, - trading_fee_denominator: Int, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, withdrawal_lp_amount: Int, total_liquidity: Int, - profit_sharing_opt: Option<(Int, Int)>, + fee_sharing_numerator_opt: Option, ) -> (Int, Int, Int, Int) { let (withdrawal_asset_a_amount, withdrawal_asset_b_amount) = calculate_withdraw( @@ -420,8 +519,7 @@ pub fn calculate_withdraw_imbalance( reserve_out: reserve_b_after_withdraw, expect_io_ratio_numerator: expect_ab_ratio_numerator, expect_io_ratio_denominator: expect_ab_ratio_denominator, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_numerator: trading_fee_a_numerator, ) let receive_amount_b = @@ -429,15 +527,13 @@ pub fn calculate_withdraw_imbalance( reserve_in: reserve_a_after_withdraw, reserve_out: reserve_b_after_withdraw, amount_in: swap_amount_a, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_numerator: trading_fee_a_numerator, ) let earned_fee_a = calculate_earned_fee_in( amount_in: swap_amount_a, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + trading_fee_numerator: trading_fee_a_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) ( earned_fee_a, @@ -455,8 +551,7 @@ pub fn calculate_withdraw_imbalance( reserve_out: reserve_a_after_withdraw, expect_io_ratio_numerator: expect_ab_ratio_denominator, expect_io_ratio_denominator: expect_ab_ratio_numerator, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_numerator: trading_fee_b_numerator, ) let receive_amount_a = @@ -464,15 +559,13 @@ pub fn calculate_withdraw_imbalance( reserve_in: reserve_b_after_withdraw, reserve_out: reserve_a_after_withdraw, amount_in: swap_amount_b, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_numerator: trading_fee_b_numerator, ) let earned_fee_b = calculate_earned_fee_in( amount_in: swap_amount_b, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + trading_fee_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) ( 0, @@ -485,60 +578,31 @@ pub fn calculate_withdraw_imbalance( } } -test test_calculate_withdraw_swap_amount() { - let reserve_a = 1_000_000_000 - let reserve_b = 1_000_000_000 - let total_liquidity = 1_000_000_000 - let trading_fee_numerator = 3 - let trading_fee_denominator = 1000 - let withdrawal_lp_amount = 1000 - let asset_a_ratio = 3 - let asset_b_ratio = 1 - - let (withdrawal_asset_a_amount, withdrawal_asset_b_amount) = - calculate_withdraw( - reserve_a: reserve_a, - reserve_b: reserve_b, - withdrawal_lp_amount: withdrawal_lp_amount, - total_liquidity: total_liquidity, +test test_calculate_withdraw_imbalance() { + // swap amount is 2004 + let result1 = + calculate_withdraw_imbalance( + expect_ab_ratio_numerator: 2, + expect_ab_ratio_denominator: 3, + reserve_a: 1_000_000, + reserve_b: 1_000_000, + trading_fee_a_numerator: 30, + trading_fee_b_numerator: 100, + withdrawal_lp_amount: 10_000, + total_liquidity: 1_000_000, + fee_sharing_numerator_opt: Some(5000), ) - let reserve_a_after_withdraw = reserve_a - withdrawal_asset_a_amount - let reserve_b_after_withdraw = reserve_b - withdrawal_asset_b_amount - // b -> a - let swap_amount_b = - calculate_withdraw_swap_amount( - amount_in: withdrawal_asset_b_amount, - amount_out: withdrawal_asset_a_amount, - reserve_in: reserve_b_after_withdraw, - reserve_out: reserve_a_after_withdraw, - expect_io_ratio_numerator: asset_b_ratio, - expect_io_ratio_denominator: asset_a_ratio, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + let result2 = + calculate_withdraw_imbalance( + expect_ab_ratio_numerator: 2, + expect_ab_ratio_denominator: 3, + reserve_a: 1_000_000, + reserve_b: 1_000_000, + trading_fee_a_numerator: 100, + trading_fee_b_numerator: 30, + withdrawal_lp_amount: 10_000, + total_liquidity: 1_000_000, + fee_sharing_numerator_opt: Some(5000), ) - swap_amount_b == 500 && withdrawal_asset_a_amount == 1000 && withdrawal_asset_a_amount == 1000 -} - -test test_calculate_withdraw_imbalance() { - let reserve_a = 1_000_000_000 - let reserve_b = 1_000_000_000 - let total_liquidity = 1_000_000_000 - let trading_fee_numerator = 3 - let trading_fee_denominator = 1000 - let withdrawal_lp_amount = 1000 - let asset_a_ratio = 3 - let asset_b_ratio = 1 - let profit_sharing_opt = None - - calculate_withdraw_imbalance( - expect_ab_ratio_numerator: asset_a_ratio, - expect_ab_ratio_denominator: asset_b_ratio, - reserve_a: reserve_a, - reserve_b: reserve_b, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - withdrawal_lp_amount: withdrawal_lp_amount, - total_liquidity: total_liquidity, - profit_sharing_opt: profit_sharing_opt, - ) == (0, 0, 1498, 500) + result1 == (3, 0, 7996, 11993) && result2 == (10, 0, 7991, 11984) } diff --git a/lib/amm_dex_v2/order_validation.ak b/lib/amm_dex_v2/order_validation.ak index e8b194b..efe96dd 100644 --- a/lib/amm_dex_v2/order_validation.ak +++ b/lib/amm_dex_v2/order_validation.ak @@ -5,15 +5,22 @@ use aiken/transaction.{Datum, DatumHash, InlineDatum, Input, NoDatum, Output} use aiken/transaction/credential.{ Address, ScriptCredential, VerificationKeyCredential, } -use aiken/transaction/value.{Value, ada_asset_name, ada_policy_id} +use aiken/transaction/value.{ + AssetName, PolicyId, Value, ada_asset_name, ada_policy_id, +} use amm_dex_v2/math use amm_dex_v2/types.{ - Asset, BatchingPool, CustomDatumHash, DatumMap, Deposit, OCO, OrderDatum, - PartialSwap, PoolState, StopLoss, SwapExactIn, SwapExactOut, SwapMultiRouting, - SwapRouting, Withdraw, WithdrawImbalance, ZapOut, + Asset, BatchingPool, DAOAll, DAOSpecificAmount, DatumMap, Deposit, + DepositAmountOption, Donation, EODDatumHash, EODInlineDatum, EODNoDatum, + ExtraOrderDatum, OCO, OrderDatum, PartialSwap, PoolState, SAOAll, + SAOSpecificAmount, SortedValueList, StopLoss, SwapAmountOption, SwapExactIn, + SwapExactOut, SwapMultiRouting, SwapRouting, WAOAll, WAOSpecificAmount, + Withdraw, WithdrawAmountOption, WithdrawImbalance, ZapOut, } use amm_dex_v2/utils +// Construct the value when order is cancelled by the batcher +// Only batcher fee is deducted from the order value fn get_returnable_value(order_in_value: Value, used_batcher_fee: Int) -> Value { value.add( order_in_value, @@ -23,21 +30,166 @@ fn get_returnable_value(order_in_value: Value, used_batcher_fee: Int) -> Value { ) } +// Ad hoc solution for predicting order output value. +// This function only handles ADA pairs and has strict asset requirements in the value. +fn get_optimized_swap_output_value( + order_in_value: Value, + used_batcher_fee: Int, + asset_a_policy_id: PolicyId, + asset_a_asset_name: AssetName, + asset_b_policy_id: PolicyId, + asset_b_asset_name: AssetName, + amount_in: Int, + amount_out: Int, + a_to_b: Bool, +) -> Option { + // Ensure that asset A is ADA + if asset_a_policy_id == #"" && asset_a_asset_name == #"" { + let order_in_value_list = order_in_value |> utils.value_to_list + let ada_entry = builtin.head_list(order_in_value_list) + let rest_0 = builtin.tail_list(order_in_value_list) + let asset_a_amount = + builtin.snd_pair(builtin.head_list(builtin.snd_pair(ada_entry))) + when rest_0 is { + // If the input value contains only ADA and the swap direction is A To B, + // subtract the batcher fee and swap amount of ADA, then add asset B to the output value. + [] -> + if a_to_b { + Some( + [ + (#"", [(#"", asset_a_amount - ( used_batcher_fee + amount_in ))]), + (asset_b_policy_id, [(asset_b_asset_name, amount_out)]), + ], + ) + } else { + fail + } + // If the input value contains ADA and one additional asset, with Asset B being swapped for Asset A, + // subtract the batcher fee and add the output amount to the ADA portion, then subtract the swap amount of Asset B. + [(asset_pid, [(asset_tn, asset_amount)])] -> + if + !a_to_b && asset_pid == asset_b_policy_id && asset_tn == asset_b_asset_name{ + + // Asset B have change + if asset_amount > amount_in { + Some( + [ + (#"", [(#"", asset_a_amount - used_batcher_fee + amount_out)]), + (asset_pid, [(asset_tn, asset_amount - amount_in)]), + ], + ) + } else if asset_amount == amount_in { + // Asset B have no change + Some( + [(#"", [(#"", asset_a_amount - used_batcher_fee + amount_out)])], + ) + } else { + fail + } + } else { + None + } + _ -> None + } + } else { + None + } +} + +fn get_swap_output_value( + order_in_value: Value, + used_batcher_fee: Int, + asset_in_policy_id: PolicyId, + asset_in_asset_name: AssetName, + asset_out_policy_id: PolicyId, + asset_out_asset_name: AssetName, + amount_in: Int, + amount_out: Int, +) -> Value { + if utils.is_ada_asset(asset_in_policy_id, asset_in_asset_name) { + order_in_value + |> value.add(ada_policy_id, ada_asset_name, -(used_batcher_fee + amount_in)) + |> value.add(asset_out_policy_id, asset_out_asset_name, amount_out) + } else if utils.is_ada_asset(asset_out_policy_id, asset_out_asset_name) { + order_in_value + |> value.add(ada_policy_id, ada_asset_name, amount_out - used_batcher_fee) + |> value.add(asset_in_policy_id, asset_in_asset_name, -amount_in) + } else { + order_in_value + |> value.add(ada_policy_id, ada_asset_name, -used_batcher_fee) + |> value.add(asset_in_policy_id, asset_in_asset_name, -amount_in) + |> value.add(asset_out_policy_id, asset_out_asset_name, amount_out) + } +} + +fn compare_swap_output_value( + order_in_value: Value, + order_out_value: Value, + used_batcher_fee: Int, + asset_a: Asset, + asset_b: Asset, + a_to_b_direction: Bool, + amount_in: Int, + amount_out: Int, +) -> Bool { + when + get_optimized_swap_output_value( + order_in_value: order_in_value, + used_batcher_fee: used_batcher_fee, + asset_a_policy_id: asset_a.policy_id, + asset_a_asset_name: asset_a.asset_name, + asset_b_policy_id: asset_b.policy_id, + asset_b_asset_name: asset_b.asset_name, + amount_in: amount_in, + amount_out: amount_out, + a_to_b: a_to_b_direction, + ) + is { + Some(v) -> v == ( order_out_value |> utils.value_to_list ) + None -> { + let (asset_in, asset_out) = + if a_to_b_direction { + (asset_a, asset_b) + } else { + (asset_b, asset_a) + } + let Asset { + policy_id: asset_in_policy_id, + asset_name: asset_in_asset_name, + } = asset_in + let Asset { + policy_id: asset_out_policy_id, + asset_name: asset_out_asset_name, + } = asset_out + order_out_value == get_swap_output_value( + order_in_value: order_in_value, + used_batcher_fee: used_batcher_fee, + asset_in_policy_id: asset_in_policy_id, + asset_in_asset_name: asset_in_asset_name, + asset_out_policy_id: asset_out_policy_id, + asset_out_asset_name: asset_out_asset_name, + amount_in: amount_in, + amount_out: amount_out, + ) + } + } +} + fn validate_swap_exact_in( order_in_value: Value, order_output: Output, - sender: Address, - sender_datum_hash_opt: Option, - receiver: Address, - receiver_datum_hash_opt: Option, + refund_receiver: Address, + refund_receiver_datum: ExtraOrderDatum, + success_receiver: Address, + success_receiver_datum: ExtraOrderDatum, a_to_b_direction: Bool, - swap_amount: Int, + swap_amount_option: SwapAmountOption, asset_a: Asset, asset_b: Asset, used_batcher_fee: Int, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing_opt: Option<(Int, Int)>, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, pool_state: PoolState, kill_on_failed: Bool, is_slippage_satisfied: fn(Int) -> Bool, @@ -49,46 +201,63 @@ fn validate_swap_exact_in( value_reserve_b, total_liquidity, ) = pool_state - let (asset_in, asset_out, reserve_in, reserve_out) = + let (asset_in, reserve_in, reserve_out, trading_fee_numerator) = if a_to_b_direction { - (asset_a, asset_b, datum_reserve_a, datum_reserve_b) + (asset_a, datum_reserve_a, datum_reserve_b, trading_fee_a_numerator) } else { - (asset_b, asset_a, datum_reserve_b, datum_reserve_a) + (asset_b, datum_reserve_b, datum_reserve_a, trading_fee_b_numerator) } let Asset { policy_id: asset_in_policy_id, asset_name: asset_in_asset_name } = asset_in - let Asset { policy_id: asset_out_policy_id, asset_name: asset_out_asset_name } = - asset_out + let swap_amount = + when swap_amount_option is { + SAOSpecificAmount(am) -> am + SAOAll(deducted_amount) -> { + // deducted amount must be non-negative + expect deducted_amount >= 0 + value.quantity_of( + order_in_value, + asset_in_policy_id, + asset_in_asset_name, + ) - deducted_amount + } + } + + // swap amout must be positive + expect swap_amount > 0 let amount_out = math.calculate_amount_out( reserve_in: reserve_in, reserve_out: reserve_out, amount_in: swap_amount, trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, ) let earned_fee_in = math.calculate_earned_fee_in( amount_in: swap_amount, trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) let slippage_satisfied = is_slippage_satisfied(amount_out) if slippage_satisfied { - let expect_order_value_out = - order_in_value - |> value.add(ada_policy_id, ada_asset_name, -used_batcher_fee) - |> value.add(asset_in_policy_id, asset_in_asset_name, -swap_amount) - |> value.add(asset_out_policy_id, asset_out_asset_name, amount_out) - expect - validate_order_output( - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - value: expect_order_value_out, - output: order_output, - ) + expect and { + validate_order_output_except_value( + receiver: success_receiver, + receiver_datum: success_receiver_datum, + output: order_output, + ), + compare_swap_output_value( + order_in_value: order_in_value, + order_out_value: order_output.value, + used_batcher_fee: used_batcher_fee, + asset_a: asset_a, + asset_b: asset_b, + a_to_b_direction: a_to_b_direction, + amount_in: swap_amount, + amount_out: amount_out, + ), + } if a_to_b_direction { ( datum_reserve_a + swap_amount - earned_fee_in, @@ -110,8 +279,8 @@ fn validate_swap_exact_in( expect and { kill_on_failed, validate_order_output( - receiver: sender, - receiver_datum_hash_opt: sender_datum_hash_opt, + receiver: refund_receiver, + receiver_datum: refund_receiver_datum, value: get_returnable_value( order_in_value: order_in_value, used_batcher_fee: used_batcher_fee, @@ -126,19 +295,19 @@ fn validate_swap_exact_in( fn validate_swap_exact_out( order_in_value: Value, order_output: Output, - sender: Address, - sender_datum_hash_opt: Option, - receiver: Address, - receiver_datum_hash_opt: Option, + refund_receiver: Address, + refund_receiver_datum: ExtraOrderDatum, + success_receiver: Address, + success_receiver_datum: ExtraOrderDatum, a_to_b_direction: Bool, - maximum_swap_amount: Int, + maximum_swap_amount_option: SwapAmountOption, expected_receive: Int, asset_a: Asset, asset_b: Asset, used_batcher_fee: Int, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing_opt: Option<(Int, Int)>, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, kill_on_failed: Bool, pool_state: PoolState, ) -> PoolState { @@ -149,11 +318,23 @@ fn validate_swap_exact_out( value_reserve_b, total_liquidity, ) = pool_state - let (asset_in, asset_out, reserve_in, reserve_out) = + let (asset_in, asset_out, reserve_in, reserve_out, trading_fee_numerator) = if a_to_b_direction { - (asset_a, asset_b, datum_reserve_a, datum_reserve_b) + ( + asset_a, + asset_b, + datum_reserve_a, + datum_reserve_b, + trading_fee_a_numerator, + ) } else { - (asset_b, asset_a, datum_reserve_b, datum_reserve_a) + ( + asset_b, + asset_a, + datum_reserve_b, + datum_reserve_a, + trading_fee_b_numerator, + ) } let Asset { policy_id: asset_in_policy_id, asset_name: asset_in_asset_name } = asset_in @@ -165,26 +346,45 @@ fn validate_swap_exact_out( reserve_out, expected_receive, trading_fee_numerator, - trading_fee_denominator, ) let earned_fee_in = math.calculate_earned_fee_in( amount_in: necessary_amount_in, trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) + let maximum_swap_amount = + when maximum_swap_amount_option is { + SAOSpecificAmount(am) -> am + SAOAll(deducted_amount) -> { + // deducted amount must be non-negative + expect deducted_amount >= 0 + value.quantity_of( + order_in_value, + asset_in_policy_id, + asset_in_asset_name, + ) - deducted_amount + } + } + // maximum swap amount must be non-negative + expect maximum_swap_amount > 0 let slippage_satisfied = necessary_amount_in <= maximum_swap_amount if slippage_satisfied { let expect_order_value_out = - order_in_value - |> value.add(ada_policy_id, ada_asset_name, -used_batcher_fee) - |> value.add(asset_in_policy_id, asset_in_asset_name, -necessary_amount_in) - |> value.add(asset_out_policy_id, asset_out_asset_name, expected_receive) + get_swap_output_value( + order_in_value: order_in_value, + used_batcher_fee: used_batcher_fee, + asset_in_policy_id: asset_in_policy_id, + asset_in_asset_name: asset_in_asset_name, + asset_out_policy_id: asset_out_policy_id, + asset_out_asset_name: asset_out_asset_name, + amount_in: necessary_amount_in, + amount_out: expected_receive, + ) expect validate_order_output( - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, + receiver: success_receiver, + receiver_datum: success_receiver_datum, value: expect_order_value_out, output: order_output, ) @@ -209,8 +409,8 @@ fn validate_swap_exact_out( expect and { kill_on_failed, validate_order_output( - receiver: sender, - receiver_datum_hash_opt: sender_datum_hash_opt, + receiver: refund_receiver, + receiver_datum: refund_receiver_datum, value: get_returnable_value( order_in_value: order_in_value, used_batcher_fee: used_batcher_fee, @@ -225,20 +425,19 @@ fn validate_swap_exact_out( fn validate_deposit( order_in_value: Value, order_output: Output, - sender: Address, - sender_datum_hash_opt: Option, - receiver: Address, - receiver_datum_hash_opt: Option, - deposit_amount_a: Int, - deposit_amount_b: Int, + refund_receiver: Address, + refund_receiver_datum: ExtraOrderDatum, + success_receiver: Address, + success_receiver_datum: ExtraOrderDatum, + deposit_amount_option: DepositAmountOption, minimum_lp: Int, asset_a: Asset, asset_b: Asset, lp_asset: Asset, used_batcher_fee: Int, - profit_sharing_opt: Option<(Int, Int)>, - trading_fee_numerator: Int, - trading_fee_denominator: Int, + fee_sharing_numerator_opt: Option, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, kill_on_failed: Bool, pool_state: PoolState, ) -> PoolState { @@ -255,6 +454,38 @@ fn validate_deposit( asset_b let Asset { policy_id: lp_asset_policy_id, asset_name: lp_asset_asset_name } = lp_asset + let (deposit_amount_a, deposit_amount_b) = + when deposit_amount_option is { + DAOSpecificAmount(am_a, am_b) -> (am_a, am_b) + DAOAll(deducted_amount_a, deducted_amount_b) -> { + // deducted amount a & b must be non-negative + expect and { + deducted_amount_a >= 0, + deducted_amount_b >= 0, + } + let am_a = + value.quantity_of( + order_in_value, + asset_a_policy_id, + asset_a_asset_name, + ) - deducted_amount_a + let am_b = + value.quantity_of( + order_in_value, + asset_b_policy_id, + asset_b_asset_name, + ) - deducted_amount_b + (am_a, am_b) + } + } + + // amount a and b must be non-negative and sum of them must be positive + // if amount a or amount b is zero, it's one side deposit case + expect and { + deposit_amount_a >= 0, + deposit_amount_b >= 0, + deposit_amount_a + deposit_amount_b > 0, + } let (earned_fee_a, earned_fee_b, lp_amount) = math.calculate_deposit_amount( @@ -263,9 +494,9 @@ fn validate_deposit( reserve_a: datum_reserve_a, reserve_b: datum_reserve_b, total_liquidity: total_liquidity, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) let slippage_satisfied = lp_amount >= minimum_lp if slippage_satisfied { @@ -277,8 +508,8 @@ fn validate_deposit( |> value.add(lp_asset_policy_id, lp_asset_asset_name, lp_amount) expect validate_order_output( - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, + receiver: success_receiver, + receiver_datum: success_receiver_datum, value: expect_order_value_out, output: order_output, ) @@ -293,8 +524,8 @@ fn validate_deposit( expect and { kill_on_failed, validate_order_output( - receiver: sender, - receiver_datum_hash_opt: sender_datum_hash_opt, + receiver: refund_receiver, + receiver_datum: refund_receiver_datum, value: get_returnable_value( order_in_value: order_in_value, used_batcher_fee: used_batcher_fee, @@ -309,11 +540,11 @@ fn validate_deposit( fn validate_withdraw( order_in_value: Value, order_output: Output, - sender: Address, - sender_datum_hash_opt: Option, - receiver: Address, - receiver_datum_hash_opt: Option, - withdrawal_lp_amount: Int, + refund_receiver: Address, + refund_receiver_datum: ExtraOrderDatum, + success_receiver: Address, + success_receiver_datum: ExtraOrderDatum, + withdrawal_amount_option: WithdrawAmountOption, minimum_amount_a: Int, minimum_amount_b: Int, asset_a: Asset, @@ -335,6 +566,18 @@ fn validate_withdraw( let Asset { policy_id: asset_b_policy_id, asset_name: asset_b_asset_name } = asset_b let Asset { policy_id: lp_policy_id, asset_name: lp_asset_name } = lp_asset + let withdrawal_lp_amount = + when withdrawal_amount_option is { + WAOSpecificAmount(am) -> am + WAOAll(deducted_amount) -> { + // deducted amount must be non-negative + expect deducted_amount >= 0 + value.quantity_of(order_in_value, lp_policy_id, lp_asset_name) - deducted_amount + } + } + + // withdrawal amount must be positive + expect withdrawal_lp_amount > 0 let (amount_a_out, amount_b_out) = math.calculate_withdraw( datum_reserve_a, @@ -355,8 +598,8 @@ fn validate_withdraw( |> value.add(asset_b_policy_id, asset_b_asset_name, amount_b_out) expect validate_order_output( - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, + receiver: success_receiver, + receiver_datum: success_receiver_datum, value: expect_order_value_out, output: order_output, ) @@ -371,8 +614,8 @@ fn validate_withdraw( expect and { kill_on_failed, validate_order_output( - receiver: sender, - receiver_datum_hash_opt: sender_datum_hash_opt, + receiver: refund_receiver, + receiver_datum: refund_receiver_datum, value: get_returnable_value( order_in_value: order_in_value, used_batcher_fee: used_batcher_fee, @@ -387,20 +630,20 @@ fn validate_withdraw( fn validate_zap_out( order_in_value: Value, order_output: Output, - sender: Address, - sender_datum_hash_opt: Option, - receiver: Address, - receiver_datum_hash_opt: Option, + refund_receiver: Address, + refund_receiver_datum: ExtraOrderDatum, + success_receiver: Address, + success_receiver_datum: ExtraOrderDatum, minimum_receive: Int, a_to_b_direction: Bool, - withdrawal_lp_amount: Int, + withdrawal_amount_option: WithdrawAmountOption, asset_a: Asset, asset_b: Asset, lp_asset: Asset, used_batcher_fee: Int, - profit_sharing_opt: Option<(Int, Int)>, - trading_fee_numerator: Int, - trading_fee_denominator: Int, + fee_sharing_numerator_opt: Option, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, kill_on_failed: Bool, pool_state: PoolState, ) -> PoolState { @@ -420,7 +663,18 @@ fn validate_zap_out( let Asset { policy_id: asset_out_policy_id, asset_name: asset_out_asset_name } = asset_out let Asset { policy_id: lp_policy_id, asset_name: lp_asset_name } = lp_asset + let withdrawal_lp_amount = + when withdrawal_amount_option is { + WAOSpecificAmount(am) -> am + WAOAll(deducted_amount) -> { + // deducted amount must be non-negative + expect deducted_amount >= 0 + value.quantity_of(order_in_value, lp_policy_id, lp_asset_name) - deducted_amount + } + } + // withdrawal amount must be positive + expect withdrawal_lp_amount > 0 let (earned_fee_a, earned_fee_b, amount_out) = math.calculate_zap_out( withdrawal_lp_amount: withdrawal_lp_amount, @@ -428,9 +682,9 @@ fn validate_zap_out( reserve_b: datum_reserve_b, total_liquidity: total_liquidity, a_to_b_direction: a_to_b_direction, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) let slippage_satisfied = amount_out >= minimum_receive if slippage_satisfied { @@ -441,8 +695,8 @@ fn validate_zap_out( |> value.add(asset_out_policy_id, asset_out_asset_name, amount_out) expect validate_order_output( - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, + receiver: success_receiver, + receiver_datum: success_receiver_datum, value: expect_order_value_out, output: order_output, ) @@ -467,8 +721,8 @@ fn validate_zap_out( expect and { kill_on_failed, validate_order_output( - receiver: sender, - receiver_datum_hash_opt: sender_datum_hash_opt, + receiver: refund_receiver, + receiver_datum: refund_receiver_datum, value: get_returnable_value( order_in_value: order_in_value, used_batcher_fee: used_batcher_fee, @@ -492,9 +746,9 @@ fn validate_partial_swap( asset_a: Asset, asset_b: Asset, used_batcher_fee: Int, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing_opt: Option<(Int, Int)>, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, pool_state: PoolState, ) -> (Int, Int, Int, Int, Int, Int, Bool) { let ( @@ -504,11 +758,23 @@ fn validate_partial_swap( value_reserve_b, total_liquidity, ) = pool_state - let (asset_in, asset_out, reserve_in, reserve_out) = + let (asset_in, asset_out, reserve_in, reserve_out, trading_fee_numerator) = if a_to_b_direction { - (asset_a, asset_b, datum_reserve_a, datum_reserve_b) + ( + asset_a, + asset_b, + datum_reserve_a, + datum_reserve_b, + trading_fee_a_numerator, + ) } else { - (asset_b, asset_a, datum_reserve_b, datum_reserve_a) + ( + asset_b, + asset_a, + datum_reserve_b, + datum_reserve_a, + trading_fee_b_numerator, + ) } let Asset { policy_id: asset_in_policy_id, asset_name: asset_in_asset_name } = asset_in @@ -519,7 +785,6 @@ fn validate_partial_swap( reserve_in: reserve_in, reserve_out: reserve_out, trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, io_ratio_numerator: io_ratio_numerator, io_ratio_denominator: io_ratio_denominator, ) @@ -536,20 +801,24 @@ fn validate_partial_swap( reserve_out: reserve_out, amount_in: swapable_amount_in, trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, ) let earned_fee_in = math.calculate_earned_fee_in( amount_in: swapable_amount_in, trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing_opt, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) let expect_order_value_out = - order_in_value - |> value.add(ada_policy_id, ada_asset_name, -used_batcher_fee) - |> value.add(asset_in_policy_id, asset_in_asset_name, -swapable_amount_in) - |> value.add(asset_out_policy_id, asset_out_asset_name, amount_out) + get_swap_output_value( + order_in_value: order_in_value, + used_batcher_fee: used_batcher_fee, + asset_in_policy_id: asset_in_policy_id, + asset_in_asset_name: asset_in_asset_name, + asset_out_policy_id: asset_out_policy_id, + asset_out_asset_name: asset_out_asset_name, + amount_in: swapable_amount_in, + amount_out: amount_out, + ) expect and { swapable_amount_in > 0, swapable_amount_in >= minimum_swap_amount_required, @@ -583,11 +852,11 @@ fn validate_partial_swap( fn validate_withdraw_imbalance( order_in_value: Value, order_output: Output, - sender: Address, - sender_datum_hash_opt: Option, - receiver: Address, - receiver_datum_hash_opt: Option, - withdrawal_lp_amount: Int, + refund_receiver: Address, + refund_receiver_datum: ExtraOrderDatum, + success_receiver: Address, + success_receiver_datum: ExtraOrderDatum, + withdrawal_amount_option: WithdrawAmountOption, ratio_asset_a: Int, ratio_asset_b: Int, minimum_amount_a: Int, @@ -595,9 +864,9 @@ fn validate_withdraw_imbalance( asset_b: Asset, lp_asset: Asset, used_batcher_fee: Int, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing_opt: Option<(Int, Int)>, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, kill_on_failed: Bool, pool_state: PoolState, ) -> PoolState { @@ -613,17 +882,28 @@ fn validate_withdraw_imbalance( let Asset { policy_id: asset_b_policy_id, asset_name: asset_b_asset_name } = asset_b let Asset { policy_id: lp_policy_id, asset_name: lp_asset_name } = lp_asset + let withdrawal_lp_amount = + when withdrawal_amount_option is { + WAOSpecificAmount(am) -> am + WAOAll(deducted_amount) -> { + // deducted amount must be non-negative + expect deducted_amount >= 0 + value.quantity_of(order_in_value, lp_policy_id, lp_asset_name) - deducted_amount + } + } + // withdrawal amount must be positive + expect withdrawal_lp_amount > 0 let (earned_fee_a, earned_fee_b, amount_a_out, amount_b_out) = math.calculate_withdraw_imbalance( expect_ab_ratio_numerator: ratio_asset_a, expect_ab_ratio_denominator: ratio_asset_b, reserve_a: datum_reserve_a, reserve_b: datum_reserve_b, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, withdrawal_lp_amount: withdrawal_lp_amount, total_liquidity: total_liquidity, - profit_sharing_opt: profit_sharing_opt, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) let slippage_satisfied = amount_a_out >= minimum_amount_a if slippage_satisfied { @@ -635,8 +915,8 @@ fn validate_withdraw_imbalance( |> value.add(asset_b_policy_id, asset_b_asset_name, amount_b_out) expect validate_order_output( - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, + receiver: success_receiver, + receiver_datum: success_receiver_datum, value: expect_order_value_out, output: order_output, ) @@ -651,8 +931,8 @@ fn validate_withdraw_imbalance( expect and { kill_on_failed, validate_order_output( - receiver: sender, - receiver_datum_hash_opt: sender_datum_hash_opt, + receiver: refund_receiver, + receiver_datum: refund_receiver_datum, value: get_returnable_value( order_in_value: order_in_value, used_batcher_fee: used_batcher_fee, @@ -664,6 +944,49 @@ fn validate_withdraw_imbalance( } } +fn validate_donation( + order_in_value: Value, + asset_a: Asset, + asset_b: Asset, + used_batcher_fee: Int, + pool_state: PoolState, +) -> PoolState { + let ( + datum_reserve_a, + datum_reserve_b, + value_reserve_a, + value_reserve_b, + total_liquidity, + ) = pool_state + let Asset { policy_id: asset_a_policy_id, asset_name: asset_a_asset_name } = + asset_a + let Asset { policy_id: asset_b_policy_id, asset_name: asset_b_asset_name } = + asset_b + let temp_amount_a = + order_in_value |> value.quantity_of(asset_a_policy_id, asset_a_asset_name) + let amount_a = + if utils.is_ada_asset(asset_a_policy_id, asset_a_asset_name) { + temp_amount_a - used_batcher_fee + } else { + temp_amount_a + } + let amount_b = + order_in_value |> value.quantity_of(asset_b_policy_id, asset_b_asset_name) + + expect and { + amount_a >= 0, + amount_b >= 0, + amount_a + amount_b > 0, + } + ( + datum_reserve_a + amount_a, + datum_reserve_b + amount_b, + value_reserve_a + amount_a, + value_reserve_b + amount_b, + total_liquidity, + ) +} + fn get_multi_routing_swap_amount_out( amount_in: Int, pool: BatchingPool, @@ -673,9 +996,9 @@ fn get_multi_routing_swap_amount_out( pool_state_in, pool_state_out, lp_asset: pool_lp_asset, - trading_fee_numerator, - trading_fee_denominator, - profit_sharing, + trading_fee_a_numerator, + trading_fee_b_numerator, + fee_sharing_numerator_opt, .. } = pool let ( @@ -694,11 +1017,11 @@ fn get_multi_routing_swap_amount_out( ) = pool_state_out let SwapRouting { lp_asset: routing_lp_asset, a_to_b_direction } = routing expect pool_lp_asset == routing_lp_asset - let (reserve_in, reserve_out) = + let (reserve_in, reserve_out, trading_fee_numerator) = if a_to_b_direction { - (old_datum_reserve_a, old_datum_reserve_b) + (old_datum_reserve_a, old_datum_reserve_b, trading_fee_a_numerator) } else { - (old_datum_reserve_b, old_datum_reserve_a) + (old_datum_reserve_b, old_datum_reserve_a, trading_fee_b_numerator) } expect amount_in > 0 @@ -708,14 +1031,12 @@ fn get_multi_routing_swap_amount_out( reserve_out: reserve_out, amount_in: amount_in, trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, ) let earned_fee_in = math.calculate_earned_fee_in( amount_in: amount_in, trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - fee_sharing_opt: profit_sharing, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, ) expect amount_out > 0 expect @@ -761,7 +1082,7 @@ pub fn validate_swap_multi_routing_order( routings: List, order_in_value: Value, order_out_value: Value, - swap_amount: Int, + swap_amount_option: SwapAmountOption, minimum_receive: Int, used_batcher_fee: Int, ) -> Bool { @@ -800,6 +1121,21 @@ pub fn validate_swap_multi_routing_order( asset_in let Asset { policy_id: asset_out_policy_id, asset_name: asset_out_asset_name } = asset_out + let swap_amount = + when swap_amount_option is { + SAOSpecificAmount(am) -> am + SAOAll(deducted_amount) -> { + // deducted amount must be non-negative + expect deducted_amount >= 0 + value.quantity_of( + order_in_value, + asset_in_policy_id, + asset_in_asset_name, + ) - deducted_amount + } + } + // swap amount must be positive + expect swap_amount > 0 let amount_out = get_swap_multi_amount_out( amount_in: swap_amount, @@ -817,20 +1153,20 @@ pub fn validate_swap_multi_routing_order( } } -fn is_valid_datum( - raw_datum: Datum, - datum_hash_opt: Option, -) -> Bool { - when raw_datum is { - NoDatum -> None - DatumHash(dh) -> Some(dh) - InlineDatum(dat) -> Some(hash.blake2b_256(builtin.serialise_data(dat))) - } == datum_hash_opt +fn is_valid_datum(raw_datum: Datum, extra_order_datum: ExtraOrderDatum) -> Bool { + let expect_extra_order_datum = + when raw_datum is { + NoDatum -> EODNoDatum + DatumHash(dh) -> EODDatumHash(dh) + InlineDatum(dat) -> + EODInlineDatum(hash.blake2b_256(builtin.serialise_data(dat))) + } + extra_order_datum == expect_extra_order_datum } pub fn validate_order_receiver( receiver: Address, - receiver_datum_hash_opt: Option, + receiver_datum: ExtraOrderDatum, output: Output, ) -> Bool { let Output { address: output_address, datum: raw_order_output_datum, .. } = @@ -843,7 +1179,7 @@ pub fn validate_order_receiver( is_correct_address, is_valid_datum( raw_datum: raw_order_output_datum, - datum_hash_opt: receiver_datum_hash_opt, + extra_order_datum: receiver_datum, ), } } @@ -851,7 +1187,7 @@ pub fn validate_order_receiver( fn validate_order_output( receiver: Address, - receiver_datum_hash_opt: Option, + receiver_datum: ExtraOrderDatum, value: Value, output: Output, ) -> Bool { @@ -873,7 +1209,28 @@ fn validate_order_output( is_correct_address_and_value, is_valid_datum( raw_datum: raw_order_output_datum, - datum_hash_opt: receiver_datum_hash_opt, + extra_order_datum: receiver_datum, + ), + } + } +} + +fn validate_order_output_except_value( + receiver: Address, + receiver_datum: ExtraOrderDatum, + output: Output, +) -> Bool { + let Output { address: output_address, datum: raw_order_output_datum, .. } = + output + + let Address { payment_credential: receiver_payment_cred, .. } = receiver + when receiver_payment_cred is { + VerificationKeyCredential(_) -> receiver == output_address + ScriptCredential(_) -> and { + receiver == output_address, + is_valid_datum( + raw_datum: raw_order_output_datum, + extra_order_datum: receiver_datum, ), } } @@ -884,17 +1241,16 @@ pub fn apply_orders( asset_a: Asset, asset_b: Asset, lp_asset: Asset, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing_opt: Option<(Int, Int)>, - end_valid_time_range: Int, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, + current_time_approximation: Int, order_inputs: List, - order_outputs: List, + all_outputs: List, orders_fee: List, pool_state: PoolState, ) -> PoolState { expect [input, ..rest_inputs] = order_inputs - expect [output, ..rest_outputs] = order_outputs expect [used_batcher_fee, ..rest_batcher_fees] = orders_fee let Input { @@ -906,15 +1262,15 @@ pub fn apply_orders( }, .. } = input - let Output { value: order_out_value, .. } = output expect order_in_datum: OrderDatum = utils.must_find_script_datum(datum_map, raw_order_in_datum) let OrderDatum { - sender, - sender_datum_hash_opt, - receiver, - receiver_datum_hash_opt, + canceller, + refund_receiver, + refund_receiver_datum, + success_receiver, + success_receiver_datum, step: order_step, max_batcher_fee, lp_asset: order_lp_asset, @@ -928,222 +1284,230 @@ pub fn apply_orders( used_batcher_fee <= max_batcher_fee, // lp_asset must be the same with processing Liquidity Pool lp_asset == order_lp_asset, + // In case expired setting is turned on, the execution time must not exceed the expired_time when expiry_setting_opt is { None -> True - Some((expired_time, _)) -> end_valid_time_range <= expired_time + Some((expired_time, _)) -> current_time_approximation <= expired_time }, } - let new_state = + let (new_state, rest_outs) = when order_step is { SwapExactIn( a_to_b_direction, - swap_amount, + swap_amount_option, minimum_receive, order_killable, ) -> { - expect and { - swap_amount > 0, - minimum_receive > 0, - } - validate_swap_exact_in( - order_in_value: order_in_value, - order_output: output, - sender: sender, - sender_datum_hash_opt: sender_datum_hash_opt, - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - a_to_b_direction: a_to_b_direction, - swap_amount: swap_amount, - asset_a: asset_a, - asset_b: asset_b, - used_batcher_fee: used_batcher_fee, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, - pool_state: pool_state, - kill_on_failed: order_killable, - is_slippage_satisfied: fn(amount_out) { - amount_out >= minimum_receive - }, + expect [output, ..rest_outputs] = all_outputs + expect minimum_receive > 0 + ( + validate_swap_exact_in( + order_in_value: order_in_value, + order_output: output, + refund_receiver: refund_receiver, + refund_receiver_datum: refund_receiver_datum, + success_receiver: success_receiver, + success_receiver_datum: success_receiver_datum, + a_to_b_direction: a_to_b_direction, + swap_amount_option: swap_amount_option, + asset_a: asset_a, + asset_b: asset_b, + used_batcher_fee: used_batcher_fee, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + pool_state: pool_state, + kill_on_failed: order_killable, + is_slippage_satisfied: fn(amount_out) { + amount_out >= minimum_receive + }, + ), + rest_outputs, ) } - StopLoss(a_to_b_direction, swap_amount, stop_loss_receive, order_killable) -> { - expect and { - swap_amount > 0, - stop_loss_receive > 0, - } - validate_swap_exact_in( - order_in_value: order_in_value, - order_output: output, - sender: sender, - sender_datum_hash_opt: sender_datum_hash_opt, - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - a_to_b_direction: a_to_b_direction, - swap_amount: swap_amount, - asset_a: asset_a, - asset_b: asset_b, - used_batcher_fee: used_batcher_fee, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, - pool_state: pool_state, - kill_on_failed: order_killable, - is_slippage_satisfied: fn(amount_out) { - amount_out <= stop_loss_receive - }, + StopLoss(a_to_b_direction, swap_amount_option, stop_loss_receive) -> { + expect [output, ..rest_outputs] = all_outputs + expect stop_loss_receive > 0 + ( + validate_swap_exact_in( + order_in_value: order_in_value, + order_output: output, + refund_receiver: refund_receiver, + refund_receiver_datum: refund_receiver_datum, + success_receiver: success_receiver, + success_receiver_datum: success_receiver_datum, + a_to_b_direction: a_to_b_direction, + swap_amount_option: swap_amount_option, + asset_a: asset_a, + asset_b: asset_b, + used_batcher_fee: used_batcher_fee, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + pool_state: pool_state, + kill_on_failed: False, + is_slippage_satisfied: fn(amount_out) { + amount_out <= stop_loss_receive + }, + ), + rest_outputs, ) } OCO( a_to_b_direction, - swap_amount, + swap_amount_option, minimum_receive, stop_loss_receive, - order_killable, ) -> { + expect [output, ..rest_outputs] = all_outputs expect and { - swap_amount > 0, minimum_receive > 0, stop_loss_receive > 0, } - validate_swap_exact_in( - order_in_value: order_in_value, - order_output: output, - sender_datum_hash_opt: sender_datum_hash_opt, - sender: sender, - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - a_to_b_direction: a_to_b_direction, - swap_amount: swap_amount, - asset_a: asset_a, - asset_b: asset_b, - used_batcher_fee: used_batcher_fee, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, - pool_state: pool_state, - kill_on_failed: order_killable, - is_slippage_satisfied: fn(amount_out) { - amount_out >= minimum_receive || amount_out <= stop_loss_receive - }, + ( + validate_swap_exact_in( + order_in_value: order_in_value, + order_output: output, + refund_receiver: refund_receiver, + refund_receiver_datum: refund_receiver_datum, + success_receiver: success_receiver, + success_receiver_datum: success_receiver_datum, + a_to_b_direction: a_to_b_direction, + swap_amount_option: swap_amount_option, + asset_a: asset_a, + asset_b: asset_b, + used_batcher_fee: used_batcher_fee, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + pool_state: pool_state, + kill_on_failed: False, + is_slippage_satisfied: fn(amount_out) { + amount_out >= minimum_receive || amount_out <= stop_loss_receive + }, + ), + rest_outputs, ) } SwapExactOut( a_to_b_direction, - maximum_swap_amount, + maximum_swap_amount_option, expected_receive, order_killable, ) -> { - expect and { - maximum_swap_amount > 0, - expected_receive > 0, - } - validate_swap_exact_out( - order_in_value: order_in_value, - order_output: output, - sender: sender, - sender_datum_hash_opt: sender_datum_hash_opt, - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - a_to_b_direction: a_to_b_direction, - maximum_swap_amount: maximum_swap_amount, - expected_receive: expected_receive, - asset_a: asset_a, - asset_b: asset_b, - used_batcher_fee: used_batcher_fee, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, - kill_on_failed: order_killable, - pool_state: pool_state, + expect [output, ..rest_outputs] = all_outputs + expect expected_receive > 0 + ( + validate_swap_exact_out( + order_in_value: order_in_value, + order_output: output, + refund_receiver: refund_receiver, + refund_receiver_datum: refund_receiver_datum, + success_receiver: success_receiver, + success_receiver_datum: success_receiver_datum, + a_to_b_direction: a_to_b_direction, + maximum_swap_amount_option: maximum_swap_amount_option, + expected_receive: expected_receive, + asset_a: asset_a, + asset_b: asset_b, + used_batcher_fee: used_batcher_fee, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + kill_on_failed: order_killable, + pool_state: pool_state, + ), + rest_outputs, ) } - Deposit(deposit_amount_a, deposit_amount_b, minimum_lp, order_killable) -> { - expect and { - deposit_amount_a >= 0, - deposit_amount_b >= 0, - deposit_amount_a + deposit_amount_b > 0, - minimum_lp > 0, - } - validate_deposit( - order_in_value: order_in_value, - order_output: output, - sender: sender, - sender_datum_hash_opt: sender_datum_hash_opt, - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - deposit_amount_a: deposit_amount_a, - deposit_amount_b: deposit_amount_b, - minimum_lp: minimum_lp, - asset_a: asset_a, - asset_b: asset_b, - lp_asset: lp_asset, - used_batcher_fee: used_batcher_fee, - profit_sharing_opt: profit_sharing_opt, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - kill_on_failed: order_killable, - pool_state: pool_state, + Deposit(deposit_amount_option, minimum_lp, order_killable) -> { + expect [output, ..rest_outputs] = all_outputs + expect minimum_lp > 0 + ( + validate_deposit( + order_in_value: order_in_value, + order_output: output, + refund_receiver: refund_receiver, + refund_receiver_datum: refund_receiver_datum, + success_receiver: success_receiver, + success_receiver_datum: success_receiver_datum, + deposit_amount_option: deposit_amount_option, + minimum_lp: minimum_lp, + asset_a: asset_a, + asset_b: asset_b, + lp_asset: lp_asset, + used_batcher_fee: used_batcher_fee, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + kill_on_failed: order_killable, + pool_state: pool_state, + ), + rest_outputs, ) } Withdraw( - withdrawal_lp_amount, + withdrawal_amount_option, minimum_asset_a, minimum_asset_b, order_killable, ) -> { + expect [output, ..rest_outputs] = all_outputs expect and { - withdrawal_lp_amount > 0, minimum_asset_a > 0, minimum_asset_b > 0, } - validate_withdraw( - order_in_value: order_in_value, - order_output: output, - sender: sender, - sender_datum_hash_opt: sender_datum_hash_opt, - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - withdrawal_lp_amount: withdrawal_lp_amount, - minimum_amount_a: minimum_asset_a, - minimum_amount_b: minimum_asset_b, - asset_a: asset_a, - asset_b: asset_b, - lp_asset: lp_asset, - used_batcher_fee: used_batcher_fee, - kill_on_failed: order_killable, - pool_state: pool_state, + ( + validate_withdraw( + order_in_value: order_in_value, + order_output: output, + refund_receiver: refund_receiver, + refund_receiver_datum: refund_receiver_datum, + success_receiver: success_receiver, + success_receiver_datum: success_receiver_datum, + withdrawal_amount_option: withdrawal_amount_option, + minimum_amount_a: minimum_asset_a, + minimum_amount_b: minimum_asset_b, + asset_a: asset_a, + asset_b: asset_b, + lp_asset: lp_asset, + used_batcher_fee: used_batcher_fee, + kill_on_failed: order_killable, + pool_state: pool_state, + ), + rest_outputs, ) } ZapOut( a_to_b_direction, - withdrawal_lp_amount, + withdrawal_amount_option, minimum_receive, order_killable, ) -> { - expect and { - withdrawal_lp_amount > 0, - minimum_receive > 0, - } - validate_zap_out( - order_in_value: order_in_value, - order_output: output, - sender: sender, - sender_datum_hash_opt: sender_datum_hash_opt, - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - minimum_receive: minimum_receive, - a_to_b_direction: a_to_b_direction, - withdrawal_lp_amount: withdrawal_lp_amount, - asset_a: asset_a, - asset_b: asset_b, - lp_asset: lp_asset, - used_batcher_fee: used_batcher_fee, - profit_sharing_opt: profit_sharing_opt, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - kill_on_failed: order_killable, - pool_state: pool_state, + expect [output, ..rest_outputs] = all_outputs + expect minimum_receive > 0 + ( + validate_zap_out( + order_in_value: order_in_value, + order_output: output, + refund_receiver: refund_receiver, + refund_receiver_datum: refund_receiver_datum, + success_receiver: success_receiver, + success_receiver_datum: success_receiver_datum, + minimum_receive: minimum_receive, + a_to_b_direction: a_to_b_direction, + withdrawal_amount_option: withdrawal_amount_option, + asset_a: asset_a, + asset_b: asset_b, + lp_asset: lp_asset, + used_batcher_fee: used_batcher_fee, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + kill_on_failed: order_killable, + pool_state: pool_state, + ), + rest_outputs, ) } PartialSwap( @@ -1155,6 +1519,8 @@ pub fn apply_orders( minimum_swap_amount_required, max_batcher_fee_each_time, ) -> { + expect [output, ..rest_outputs] = all_outputs + let Output { value: order_out_value, .. } = output expect and { io_ratio_numerator > 0, io_ratio_denominator > 0, @@ -1184,9 +1550,9 @@ pub fn apply_orders( asset_a: asset_a, asset_b: asset_b, used_batcher_fee: used_batcher_fee, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, pool_state: pool_state, ) expect @@ -1200,10 +1566,11 @@ pub fn apply_orders( utils.must_find_script_datum(datum_map, raw_order_out_datum) let expected_order_out_datum = OrderDatum { - sender, - sender_datum_hash_opt, - receiver, - receiver_datum_hash_opt, + canceller, + refund_receiver, + refund_receiver_datum, + success_receiver, + success_receiver_datum, lp_asset: order_lp_asset, step: PartialSwap { a_to_b_direction, @@ -1222,56 +1589,73 @@ pub fn apply_orders( order_in_address == order_out_address, } } else { - // Order Output must be returned to receiver and might have receiver_datum_hash_opt + // Order Output must be returned to receiver and might have receiver_datum validate_order_receiver( - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, + receiver: success_receiver, + receiver_datum: success_receiver_datum, output: output, ) } ( - new_reserve_a, - new_reserve_b, - new_total_liquidity, - new_liquidity_share, - new_root_k_last, + ( + new_reserve_a, + new_reserve_b, + new_total_liquidity, + new_liquidity_share, + new_root_k_last, + ), + rest_outputs, ) } WithdrawImbalance( - withdrawal_lp_amount, + withdrawal_amount_option, ratio_asset_a, ratio_asset_b, minimum_asset_a, order_killable, ) -> { + expect [output, ..rest_outputs] = all_outputs expect and { - withdrawal_lp_amount > 0, ratio_asset_a > 0, ratio_asset_b > 0, minimum_asset_a > 0, } - validate_withdraw_imbalance( - order_in_value: order_in_value, - order_output: output, - sender: sender, - sender_datum_hash_opt: sender_datum_hash_opt, - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - withdrawal_lp_amount: withdrawal_lp_amount, - ratio_asset_a: ratio_asset_a, - ratio_asset_b: ratio_asset_b, - minimum_amount_a: minimum_asset_a, - asset_a: asset_a, - asset_b: asset_b, - lp_asset: lp_asset, - used_batcher_fee: used_batcher_fee, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, - kill_on_failed: order_killable, - pool_state: pool_state, + ( + validate_withdraw_imbalance( + order_in_value: order_in_value, + order_output: output, + refund_receiver: refund_receiver, + refund_receiver_datum: refund_receiver_datum, + success_receiver: success_receiver, + success_receiver_datum: success_receiver_datum, + withdrawal_amount_option: withdrawal_amount_option, + ratio_asset_a: ratio_asset_a, + ratio_asset_b: ratio_asset_b, + minimum_amount_a: minimum_asset_a, + asset_a: asset_a, + asset_b: asset_b, + lp_asset: lp_asset, + used_batcher_fee: used_batcher_fee, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + kill_on_failed: order_killable, + pool_state: pool_state, + ), + rest_outputs, ) } + Donation -> + ( + validate_donation( + order_in_value: order_in_value, + asset_a: asset_a, + asset_b: asset_b, + used_batcher_fee: used_batcher_fee, + pool_state: pool_state, + ), + all_outputs, + ) SwapMultiRouting(_, _, _) -> fail } @@ -1283,12 +1667,12 @@ pub fn apply_orders( asset_a: asset_a, asset_b: asset_b, lp_asset: lp_asset, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing_opt, - end_valid_time_range: end_valid_time_range, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + current_time_approximation: current_time_approximation, order_inputs: rest_inputs, - order_outputs: rest_outputs, + all_outputs: rest_outs, orders_fee: rest_batcher_fees, pool_state: new_state, ) @@ -1317,15 +1701,19 @@ pub fn validate_cancel_expired_orders( expect order_in_datum: OrderDatum = utils.must_find_script_datum(datum_map, order_in_datum_raw) - let OrderDatum { sender, sender_datum_hash_opt, expiry_setting_opt, .. } = - order_in_datum + let OrderDatum { + refund_receiver, + refund_receiver_datum, + expiry_setting_opt, + .. + } = order_in_datum expect Some((expired_time, max_tip)) = expiry_setting_opt expect and { // the transaction must be created after expired time expired_time < start_valid_time_range, // the output have to paid back to sender - sender == order_out_address, + refund_receiver == order_out_address, // ADA in the order might be deducted for tipping a canceller // The tip must not exceed the maximum tip // Other tokens must be returned to sender @@ -1336,7 +1724,7 @@ pub fn validate_cancel_expired_orders( // If sender is script address, the output have to attach the defined datum is_valid_datum( raw_datum: raw_order_output_datum, - datum_hash_opt: sender_datum_hash_opt, + extra_order_datum: refund_receiver_datum, ), } if rest_order_inputs == [] { diff --git a/lib/amm_dex_v2/pool_validation.ak b/lib/amm_dex_v2/pool_validation.ak index 87eb235..50358f0 100644 --- a/lib/amm_dex_v2/pool_validation.ak +++ b/lib/amm_dex_v2/pool_validation.ak @@ -1,11 +1,7 @@ -use aiken/builtin use aiken/dict.{Dict} use aiken/hash.{Blake2b_224, Hash} -use aiken/interval.{Finite, Interval, IntervalBound} use aiken/list -use aiken/transaction.{ - Input, Output, OutputReference, Redeemer, ScriptPurpose, Spend, ValidityRange, -} +use aiken/transaction.{Input, Output} use aiken/transaction/credential.{ Address, Inline, PaymentCredential, ScriptCredential, StakeCredential, VerificationKey, VerificationKeyCredential, @@ -13,119 +9,138 @@ use aiken/transaction/credential.{ use aiken/transaction/value.{ AssetName, PolicyId, Value, ada_asset_name, ada_policy_id, } -use amm_dex_v2/order_validation use amm_dex_v2/types.{ - Asset, BatchingPool, DatumMap, OrderDatum, PoolDatum, SwapMultiRouting, - UpdatePoolFee, UpdatePoolFeeOrStakeCredentialAction, UpdatePoolStakeCredential, + Asset, BatchingPool, GlobalSetting, PoolDatum, UpdateDynamicFee, UpdatePoolFee, + UpdatePoolParametersAction, UpdatePoolStakeCredential, } use amm_dex_v2/utils -pub fn validate_license_expiration_and_find_license_holder( - license_pid: PolicyId, - license_input: Input, - validity_range: ValidityRange, -) -> (Address, Int) { +// Global Setting must be provided through the @reference_inputs +// and has to keep the Global Setting NFT in its value +pub fn get_and_validate_global_setting( + reference_inputs: List, + authen_policy_id: PolicyId, +) -> GlobalSetting { + expect Some(global_input) = + reference_inputs + |> list.find( + fn(input) { + let Input { + output: Output { + address: Address { payment_credential: payment_cred, .. }, + .. + }, + .. + } = input + when payment_cred is { + ScriptCredential(hash) -> hash == authen_policy_id + _ -> False + } + }, + ) let Input { - output: Output { address: license_holder_addr, value: license_value, .. }, + output: Output { + value: global_setting_value, + datum: global_setting_datum_raw, + .. + }, .. - } = license_input - expect [(license_asset_name, license_amount)] = - license_value - |> value.tokens(license_pid) - |> dict.to_list() - let license_deadline = utils.bytearray_to_positive_int(license_asset_name) - let Interval { - lower_bound: IntervalBound { bound_type: lower_bound_type, .. }, - upper_bound: IntervalBound { bound_type: upper_bound_type, .. }, - } = validity_range - expect Finite(start_valid_time_range) = lower_bound_type - expect Finite(end_valid_time_range) = upper_bound_type - // - Only Batcher with valid license token can trigger @ApplyPool redeemer validation. - // - A valid license token is the token with @tokenName (representing for expired milliseconds) - // and must be within the time range from current_time to current_time + maximum_deadline_range - expect and { - license_amount == 1, - license_deadline >= end_valid_time_range, - license_deadline <= start_valid_time_range + utils.maximum_deadline_range, - } - (license_holder_addr, end_valid_time_range) + } = global_input + expect + ( + global_setting_value + |> value.quantity_of(authen_policy_id, utils.global_setting_asset_name) + ) == 1 + expect global_setting_datum: GlobalSetting = + utils.must_find_script_inline_datum(global_setting_datum_raw) + global_setting_datum } -fn find_pool_input_and_output_in_batching( - pool_input_ref: OutputReference, - inputs: List, - outputs: List, -) -> (Output, Output) { - expect Some(pool_input) = - list.find( - inputs, - fn(input) { - let Input { output_reference: out_ref, .. } = input - pool_input_ref == out_ref - }, - ) - let Input { output: pool_in_output, .. } = pool_input - let Output { address: pool_in_address, .. } = pool_in_output - let Address { payment_credential: pool_payment_credential, .. } = - pool_in_address - - // Batching transaction requires single Pool UTxO in both Inputs and Outputs - let pool_output = - get_single_pool_output( - all_outputs: outputs, - pool_payment_credential: pool_payment_credential, - ) - let Output { address: pool_out_address, .. } = pool_output - expect pool_out_address == pool_in_address - // Due to combination with Minswap Stake Address, Pool Contract can have multiple Base Addresses - // This logic will verify that the transaction is processing in single Pool - // Verify that having only one Pool Input and Pool Output in the transaction - expect [_] = - list.filter( - inputs, - fn(input) { - let Input { output: o, .. } = input - let Output { address: addr, .. } = o - let Address { payment_credential: payment_cred, .. } = addr - payment_cred == pool_payment_credential - }, - ) - (pool_in_output, pool_output) +pub fn authorize_license_holder( + license_address: Address, + transaction_inputs: List, + withdrawals: Dict, + extra_signatories: List>, +) -> Bool { + let Address { payment_credential: license_holder_payment_cred, .. } = + license_address + when license_holder_payment_cred is { + //If the Authorizer is controlled by a PubKey wallet, + // the owners of the UTxO must sign the transaction with their private key. Otherwise, such action must be prohibited. + VerificationKeyCredential(pub_key_hash) -> + list.has(extra_signatories, pub_key_hash) + // If the Authorizer is controlled by a Script wallet, + // the smart contract must incorporate a Withdrawal or a Spend function and execute sufficient conditions to facilitate its operation + ScriptCredential(script_hash) -> { + let authorized_via_withdrawal = + dict.has_key(withdrawals, Inline(ScriptCredential(script_hash))) + if authorized_via_withdrawal { + True + } else { + list.any( + transaction_inputs, + fn(input) { + let Input { output, .. } = input + let Output { address: out_address, .. } = output + let Address { payment_credential: out_payment_credential, .. } = + out_address + out_payment_credential == license_holder_payment_cred + }, + ) + } + } + } } -fn get_batching_pool( +pub fn get_batching_pool( + stake_credential: StakeCredential, pool_input: Output, pool_output: Output, authen_policy_id: PolicyId, - pool_in_datum: PoolDatum, - datum_map: DatumMap, require_total_liquidity_unchange: Bool, + vol_fee: Option, ) -> BatchingPool { - let Output { address: pool_in_address, value: pool_in_value, .. } = pool_input - let Output { value: pool_out_value, datum: pool_out_datum_raw, .. } = - pool_output + let Output { + address: pool_in_address, + value: pool_in_value, + datum: pool_in_datum_raw, + .. + } = pool_input + let Output { + address: pool_out_address, + value: pool_out_value, + datum: pool_out_datum_raw, + .. + } = pool_output + + expect pool_in_datum: PoolDatum = + utils.must_find_script_inline_datum(pool_in_datum_raw) let PoolDatum { + pool_batching_stake_credential: pool_in_stake_credential, asset_a: pool_in_asset_a, asset_b: pool_in_asset_b, total_liquidity: pool_in_total_liquidity, reserve_a: pool_in_datum_reserve_a, reserve_b: pool_in_datum_reserve_b, - trading_fee_numerator: pool_in_trading_fee_numerator, - trading_fee_denominator: pool_in_trading_fee_denominator, - profit_sharing_opt: pool_in_profit_sharing_opt, + base_fee_a_numerator: pool_in_base_fee_a_numerator, + base_fee_b_numerator: pool_in_base_fee_b_numerator, + fee_sharing_numerator_opt: pool_in_fee_sharing_numerator_opt, + allow_dynamic_fee: pool_in_allow_dynamic_fee, } = pool_in_datum expect pool_out_datum: PoolDatum = - utils.must_find_script_datum(datum_map, pool_out_datum_raw) + utils.must_find_script_inline_datum(pool_out_datum_raw) let PoolDatum { + pool_batching_stake_credential: pool_out_stake_credential, asset_a: pool_out_asset_a, asset_b: pool_out_asset_b, total_liquidity: pool_out_total_liquidity, reserve_a: pool_out_datum_reserve_a, reserve_b: pool_out_datum_reserve_b, - trading_fee_numerator: pool_out_trading_fee_numerator, - trading_fee_denominator: pool_out_trading_fee_denominator, - profit_sharing_opt: pool_out_profit_sharing_opt, + base_fee_a_numerator: pool_out_base_fee_a_numerator, + base_fee_b_numerator: pool_out_base_fee_b_numerator, + fee_sharing_numerator_opt: pool_out_fee_sharing_numerator_opt, + allow_dynamic_fee: pool_out_allow_dynamic_fee, } = pool_out_datum expect @@ -135,11 +150,15 @@ fn get_batching_pool( True } expect and { + pool_in_stake_credential == pool_out_stake_credential, + pool_in_stake_credential == stake_credential, + pool_in_address == pool_out_address, pool_in_asset_a == pool_out_asset_a, pool_in_asset_b == pool_out_asset_b, - pool_in_trading_fee_numerator == pool_out_trading_fee_numerator, - pool_in_trading_fee_denominator == pool_out_trading_fee_denominator, - pool_in_profit_sharing_opt == pool_out_profit_sharing_opt, + pool_in_base_fee_a_numerator == pool_out_base_fee_a_numerator, + pool_in_base_fee_b_numerator == pool_out_base_fee_b_numerator, + pool_in_fee_sharing_numerator_opt == pool_out_fee_sharing_numerator_opt, + pool_in_allow_dynamic_fee == pool_out_allow_dynamic_fee, } let Asset { policy_id: asset_a_policy_id, asset_name: asset_a_asset_name } = pool_in_asset_a @@ -163,8 +182,8 @@ fn get_batching_pool( let (value_reserve_a_in, value_reserve_a_out) = if utils.is_ada_asset(asset_a_policy_id, asset_a_asset_name) { ( - estimate_value_reserve_a_in - 3000000, - estimate_value_reserve_a_out - 3000000, + estimate_value_reserve_a_in - utils.min_pool_ada, + estimate_value_reserve_a_out - utils.min_pool_ada, ) } else { (estimate_value_reserve_a_in, estimate_value_reserve_a_out) @@ -180,14 +199,14 @@ fn get_batching_pool( value.quantity_of(pool_out_value, authen_policy_id, lp_asset_name) let estimate_pool_in_value = value.zero() - |> value.add(ada_policy_id, ada_asset_name, 3000000) + |> value.add(ada_policy_id, ada_asset_name, utils.min_pool_ada) |> value.add(authen_policy_id, utils.pool_auth_asset_name, 1) |> value.add(asset_a_policy_id, asset_a_asset_name, value_reserve_a_in) |> value.add(asset_b_policy_id, asset_b_asset_name, value_reserve_b_in) |> value.add(authen_policy_id, lp_asset_name, remaining_liquidity_supply_in) let estimate_pool_out_value = value.zero() - |> value.add(ada_policy_id, ada_asset_name, 3000000) + |> value.add(ada_policy_id, ada_asset_name, utils.min_pool_ada) |> value.add(authen_policy_id, utils.pool_auth_asset_name, 1) |> value.add(asset_a_policy_id, asset_a_asset_name, value_reserve_a_out) |> value.add(asset_b_policy_id, asset_b_asset_name, value_reserve_b_out) @@ -197,14 +216,26 @@ fn get_batching_pool( estimate_pool_out_value == pool_out_value, remaining_liquidity_supply_out - remaining_liquidity_supply_in == pool_in_total_liquidity - pool_out_total_liquidity, } + + let trading_fee_a_numerator = + get_trading_fee_numerator( + base_fee_num: pool_in_base_fee_a_numerator, + vol_fee_opt: vol_fee, + allow_dynamic_fee: pool_in_allow_dynamic_fee, + ) + let trading_fee_b_numerator = + get_trading_fee_numerator( + base_fee_num: pool_in_base_fee_b_numerator, + vol_fee_opt: vol_fee, + allow_dynamic_fee: pool_in_allow_dynamic_fee, + ) BatchingPool { asset_a: pool_in_asset_a, asset_b: pool_in_asset_b, lp_asset, - trading_fee_numerator: pool_in_trading_fee_numerator, - trading_fee_denominator: pool_in_trading_fee_denominator, - profit_sharing: pool_in_profit_sharing_opt, - address: pool_in_address, + trading_fee_a_numerator, + trading_fee_b_numerator, + fee_sharing_numerator_opt: pool_in_fee_sharing_numerator_opt, pool_state_in: ( pool_in_datum_reserve_a, pool_in_datum_reserve_b, @@ -222,290 +253,12 @@ fn get_batching_pool( } } -pub fn validate_batching( - authen_policy_id: PolicyId, - all_inputs: List, - all_outputs: List, - all_datums: DatumMap, - pool_input_ref: OutputReference, - pool_in_datum: PoolDatum, - batcher_address: Address, - end_valid_time_range: Int, - input_indexes: List, - orders_fee: List, -) -> Bool { - let (pool_input, pool_output) = - find_pool_input_and_output_in_batching( - pool_input_ref: pool_input_ref, - inputs: all_inputs, - outputs: all_outputs, - ) - let BatchingPool { - asset_a, - asset_b, - lp_asset, - trading_fee_numerator, - trading_fee_denominator, - profit_sharing, - address: pool_address, - pool_state_in, - pool_state_out, - } = - get_batching_pool( - pool_input: pool_input, - pool_output: pool_output, - authen_policy_id: authen_policy_id, - pool_in_datum: pool_in_datum, - datum_map: all_datums, - require_total_liquidity_unchange: False, - ) - let user_inputs = - list.filter( - all_inputs, - fn(input) { - let Input { output: out, .. } = input - let Output { address: addr, .. } = out - addr != pool_address && addr != batcher_address - }, - ) - // Currently, transaction inputs will be sorted by TxId and TxIndex of UTxO. - // We have to calculate indexes of orders inputs sorting by the ASC created time - // on the off-chain and on-chain will sort the TxIns by the indexes - // Input Indexes in parameter will be reversed indexs of @order_inputs to reduce calculate step in On-Chain - let sorted_user_inputs = - list.foldl( - input_indexes, - [], - fn(idx, ips) { list.push(ips, utils.list_at_index(user_inputs, idx)) }, - ) - - // Order Outputs are Outputs which aren't Pool & Batcher UTxOs - // Their ordering must be the same with @sorted_order_inputs, so @order_outputs at index i is the output if @sorted_order_inputs at index i - let user_outputs = - list.filter( - all_outputs, - fn(output) { - let Output { address: addr, .. } = output - addr != pool_address && addr != batcher_address - }, - ) - - expect and { - // User Inputs and Input Indexes must have the same length - utils.compare_list_length(input_indexes, user_inputs), - // User Inputs and Outputs must have the same length - utils.compare_list_length(sorted_user_inputs, user_outputs), - } - pool_state_out == order_validation.apply_orders( - datum_map: all_datums, - asset_a: asset_a, - asset_b: asset_b, - lp_asset: lp_asset, - trading_fee_numerator: trading_fee_numerator, - trading_fee_denominator: trading_fee_denominator, - profit_sharing_opt: profit_sharing, - end_valid_time_range: end_valid_time_range, - order_inputs: sorted_user_inputs, - order_outputs: user_outputs, - orders_fee: orders_fee, - pool_state: pool_state_in, - ) -} - -pub fn validate_swap_multi_routing( - authen_policy_id: PolicyId, - all_inputs: List, - all_outputs: List, - all_datums: DatumMap, - pool_input_ref: OutputReference, - batcher_address: Address, - end_valid_time_range: Int, - routing_in_indexes: List, - routing_out_indexes: List, - order_fee: Int, -) -> Bool { - let batching_pools = - find_multi_routing_pools( - authen_policy_id: authen_policy_id, - pool_input_ref: pool_input_ref, - inputs: all_inputs, - outputs: all_outputs, - routing_in_indexes: routing_in_indexes, - routing_out_indexes: routing_out_indexes, - datum_map: all_datums, - ) - - let BatchingPool { - address: Address { payment_credential: pool_payment_credential, .. }, - lp_asset: pool_lp_asset, - .. - } = batching_pools |> builtin.head_list - - expect [order_input] = - list.filter( - all_inputs, - fn(input) { - let Input { output: Output { address: addr, .. }, .. } = input - let Address { payment_credential: payment_cred, .. } = addr - addr != batcher_address && payment_cred != pool_payment_credential - }, - ) - expect [order_output] = - list.filter( - all_outputs, - fn(output) { - let Output { address: addr, .. } = output - let Address { payment_credential: payment_cred, .. } = addr - addr != batcher_address && payment_cred != pool_payment_credential - }, - ) - let Input { - output: Output { value: order_in_value, datum: raw_order_in_datum, .. }, - .. - } = order_input - let Output { value: order_out_value, .. } = order_output - expect order_in_datum: OrderDatum = - utils.must_find_script_datum(all_datums, raw_order_in_datum) - let OrderDatum { - receiver, - receiver_datum_hash_opt, - step: order_step, - max_batcher_fee, - lp_asset: order_lp_asset, - expiry_setting_opt, - .. - } = order_in_datum - expect and { - // max_batcher_fee must be positive - max_batcher_fee > 0, - // Used Batcher Fee must be positive and less than or equal batcher fee - order_fee > 0, - order_fee <= max_batcher_fee, - // Order Output must be returned to receiver and might have receiver_datum_hash_opt - order_validation.validate_order_receiver( - receiver: receiver, - receiver_datum_hash_opt: receiver_datum_hash_opt, - output: order_output, - ), - // lp_asset in OrderDatum must be the same with LP Asset of first Liquidity Pool in routing list - pool_lp_asset == order_lp_asset, - when expiry_setting_opt is { - None -> True - Some((expired_time, _)) -> end_valid_time_range <= expired_time - }, - } - when order_step is { - SwapMultiRouting(routings, swap_amount, minimum_receive) -> { - expect and { - swap_amount > 0, - minimum_receive > 0, - // The number of Pool Inputs and Pool Outputs must be the same with _routings_ length - utils.compare_list_length(batching_pools, routings), - } - order_validation.validate_swap_multi_routing_order( - pools: batching_pools, - routings: routings, - order_in_value: order_in_value, - order_out_value: order_out_value, - swap_amount: swap_amount, - minimum_receive: minimum_receive, - used_batcher_fee: order_fee, - ) - } - _ -> False - } -} - -fn find_multi_routing_pools( - authen_policy_id: PolicyId, - pool_input_ref: OutputReference, - inputs: List, - outputs: List, - routing_in_indexes: List, - routing_out_indexes: List, - datum_map: DatumMap, -) -> List { - let pool_ins = - list.map(routing_in_indexes, fn(idx) { utils.list_at_index(inputs, idx) }) - - let pool_outs = - list.map(routing_out_indexes, fn(idx) { utils.list_at_index(outputs, idx) }) - - let pool_len = list.length(pool_ins) - - // find input of current script - expect [own_pool_input] = - list.filter( - inputs, - fn(input) { - let Input { output_reference: out_ref, .. } = input - pool_input_ref == out_ref - }, - ) - let Input { - output: Output { - address: Address { payment_credential: own_pool_payment_credential, .. }, - .. - }, - .. - } = own_pool_input - // verify that the number of pool's utxo in the inputs must be matched with @pool_len - expect - list.length( - list.filter( - inputs, - fn(input) { - let Input { - output: Output { address: Address { payment_credential, .. }, .. }, - .. - } = input - payment_credential == own_pool_payment_credential - }, - ), - ) == pool_len - // verify that the number of pool's utxo in the outputs must be matched with @pool_len - expect - list.length( - list.filter( - outputs, - fn(output) { - let Output { address: Address { payment_credential, .. }, .. } = - output - payment_credential == own_pool_payment_credential - }, - ), - ) == pool_len - utils.zip_with( - pool_ins, - pool_outs, - fn(pool_in, pool_out) { - let Input { output: pool_in_output, .. } = pool_in - let Output { address: pool_in_address, datum: pool_in_datum_raw, .. } = - pool_in_output - let Output { address: pool_out_address, .. } = pool_out - expect pool_in_datum: PoolDatum = - utils.must_find_script_datum(datum_map, pool_in_datum_raw) - - expect pool_in_address == pool_out_address - get_batching_pool( - pool_input: pool_in_output, - pool_output: pool_out, - authen_policy_id: authen_policy_id, - pool_in_datum: pool_in_datum, - datum_map: datum_map, - require_total_liquidity_unchange: True, - ) - }, - ) -} - -pub fn validate_update_pool_datum_or_stake_credential( - action: UpdatePoolFeeOrStakeCredentialAction, +pub fn validate_update_pool_parameters( + action: UpdatePoolParametersAction, authen_policy_id: PolicyId, pool_input: Input, pool_in_datum: PoolDatum, all_outputs: List, - all_datums: DatumMap, ) -> Bool { let Input { output: pool_in_output, .. } = pool_input let Output { address: pool_in_address, value: pool_in_value, .. } = @@ -535,107 +288,106 @@ pub fn validate_update_pool_datum_or_stake_credential( pool_in_value == pool_out_value, } expect pool_out_datum: PoolDatum = - utils.must_find_script_datum(all_datums, raw_pool_out_datum) + utils.must_find_script_inline_datum(raw_pool_out_datum) + let PoolDatum { + pool_batching_stake_credential: pool_in_stake_credential, + asset_a: pool_in_asset_a, + asset_b: pool_in_asset_b, + total_liquidity: pool_in_total_liquidity, + reserve_a: pool_in_reserve_a, + reserve_b: pool_in_reserve_b, + base_fee_a_numerator: pool_in_base_fee_a_numerator, + base_fee_b_numerator: pool_in_base_fee_b_numerator, + fee_sharing_numerator_opt: pool_in_fee_sharing_numerator_opt, + allow_dynamic_fee: pool_in_allow_dynamic_fee, + } = pool_in_datum + let PoolDatum { + pool_batching_stake_credential: pool_out_stake_credential, + asset_a: pool_out_asset_a, + asset_b: pool_out_asset_b, + total_liquidity: pool_out_total_liquidity, + reserve_a: pool_out_reserve_a, + reserve_b: pool_out_reserve_b, + base_fee_a_numerator: pool_out_base_fee_a_numerator, + base_fee_b_numerator: pool_out_base_fee_b_numerator, + fee_sharing_numerator_opt: pool_out_fee_sharing_numerator_opt, + allow_dynamic_fee: pool_out_allow_dynamic_fee, + } = pool_out_datum when action is { UpdatePoolFee -> { - let PoolDatum { - asset_a: pool_in_asset_a, - asset_b: pool_in_asset_b, - total_liquidity: pool_in_total_liquidity, - reserve_a: pool_in_reserve_a, - reserve_b: pool_in_reserve_b, - .. - } = pool_in_datum - let PoolDatum { - asset_a: pool_out_asset_a, - asset_b: pool_out_asset_b, - total_liquidity: pool_out_total_liquidity, - reserve_a: pool_out_reserve_a, - reserve_b: pool_out_reserve_b, - trading_fee_numerator: pool_out_trading_fee_numerator, - trading_fee_denominator: pool_out_trading_fee_denominator, - profit_sharing_opt: pool_out_profit_sharing_opt, - } = pool_out_datum - // Profit Sharing can be on/off by setting profit_sharing_opt is None or Some. - // Profit Sharing must be between **16.66%** and **50%** + // Profit Sharing can be on/off by setting fee_sharing_numerator_opt is None or Some. + // Profit Sharing numerator must be between **1666** and **5000** let is_valid_fee_sharing = - when pool_out_profit_sharing_opt is { + when pool_out_fee_sharing_numerator_opt is { None -> True - Some(pool_out_profit_sharing) -> { - let ( - pool_out_fee_sharing_numerator, - pool_out_fee_sharing_denominator, - ) = pool_out_profit_sharing - validate_fee_sharing_percent( - fee_sharing_numerator: pool_out_fee_sharing_numerator, - fee_sharing_denominator: pool_out_fee_sharing_denominator, + Some(pool_out_fee_sharing_numerator) -> + validate_fee_percent( + fee_num: pool_out_fee_sharing_numerator, + max_fee_num: utils.max_fee_sharing_numerator, + min_fee_num: utils.min_fee_sharing_numerator, ) - } } and { // Irrelevant fields on Pool Datum must be unchanged + pool_in_stake_credential == pool_out_stake_credential, pool_in_asset_a == pool_out_asset_a, pool_in_asset_b == pool_out_asset_b, pool_in_total_liquidity == pool_out_total_liquidity, pool_in_reserve_a == pool_out_reserve_a, pool_in_reserve_b == pool_out_reserve_b, + pool_in_allow_dynamic_fee == pool_out_allow_dynamic_fee, // Pool Address must be unchanged (both Payment and Stake Credential) pool_in_address == pool_out_address, - // Trading Fee must be between **0.05%** and **10%** - validate_trading_fee_percent( - trading_fee_numerator: pool_out_trading_fee_numerator, - trading_fee_denominator: pool_out_trading_fee_denominator, + // Trading Fee must be between **0.05%** and **20%** + validate_fee_percent( + fee_num: pool_out_base_fee_a_numerator, + max_fee_num: utils.max_base_fee_numerator, + min_fee_num: utils.min_base_fee_numerator, + ), + validate_fee_percent( + fee_num: pool_out_base_fee_b_numerator, + max_fee_num: utils.max_base_fee_numerator, + min_fee_num: utils.min_base_fee_numerator, ), is_valid_fee_sharing, } } - // Pool Datum must be unchanged + UpdateDynamicFee -> and { + // Irrelevant fields on Pool Datum must be unchanged + pool_in_stake_credential == pool_out_stake_credential, + pool_in_asset_a == pool_out_asset_a, + pool_in_asset_b == pool_out_asset_b, + pool_in_total_liquidity == pool_out_total_liquidity, + pool_in_reserve_a == pool_out_reserve_a, + pool_in_reserve_b == pool_out_reserve_b, + pool_in_base_fee_a_numerator == pool_out_base_fee_a_numerator, + pool_in_base_fee_b_numerator == pool_out_base_fee_b_numerator, + pool_in_fee_sharing_numerator_opt == pool_out_fee_sharing_numerator_opt, + // Pool Address must be unchanged (both Payment and Stake Credential) + pool_in_address == pool_out_address, + } UpdatePoolStakeCredential -> pool_in_datum == pool_out_datum } } -pub fn validate_trading_fee_percent( - trading_fee_numerator: Int, - trading_fee_denominator: Int, +pub fn validate_fee_percent( + fee_num: Int, + max_fee_num: Int, + min_fee_num: Int, ) -> Bool { - expect trading_fee_denominator > 0 - // Max 10%, Min 0.05% - let max_trading_fee_numerator = 1 - let max_trading_fee_denominator = 10 - let min_trading_fee_numerator = 5 - let min_trading_fee_denominator = 10000 - - let less_than_max = - trading_fee_numerator * max_trading_fee_denominator <= trading_fee_denominator * max_trading_fee_numerator - let greater_than_min = - trading_fee_numerator * min_trading_fee_denominator >= trading_fee_denominator * min_trading_fee_numerator - less_than_max && greater_than_min -} - -pub fn validate_fee_sharing_percent( - fee_sharing_numerator: Int, - fee_sharing_denominator: Int, -) -> Bool { - expect fee_sharing_denominator > 0 - // Max 50%, Min 16.66% - let max_fee_sharing_numerator = 1 - let max_fee_sharing_denominator = 2 - let min_fee_sharing_numerator = 1 - let min_fee_sharing_denominator = 6 - - let less_than_max = - fee_sharing_numerator * max_fee_sharing_denominator <= fee_sharing_denominator * max_fee_sharing_numerator - let greater_than_min = - fee_sharing_numerator * min_fee_sharing_denominator >= fee_sharing_denominator * min_fee_sharing_numerator - less_than_max && greater_than_min + and { + // less than max + fee_num <= max_fee_num, + // greater than min + fee_num >= min_fee_num, + } } -pub fn validate_withdraw_liquidity_share( +pub fn validate_withdraw_fee_sharing( authen_policy_id: PolicyId, pool_input: Input, pool_in_datum: PoolDatum, all_outputs: List, - all_datums: DatumMap, ) -> Bool { let Input { output: Output { address: pool_in_address, value: pool_in_value, .. }, @@ -655,7 +407,7 @@ pub fn validate_withdraw_liquidity_share( pool_payment_credential: pool_in_payment_credential, ) expect pool_out_datum: PoolDatum = - utils.must_find_script_datum(all_datums, raw_pool_out_datum) + utils.must_find_script_inline_datum(raw_pool_out_datum) expect and { // Pool Input and Output Address must be unchanged (both Payment and Stake Credential) pool_in_address == pool_out_address, @@ -682,7 +434,7 @@ pub fn validate_withdraw_liquidity_share( value.quantity_of(pool_in_value, asset_a_policy_id, asset_a_asset_name) let value_reserve_a_in = if utils.is_ada_asset(asset_a_policy_id, asset_a_asset_name) { - temp_value_reserve_a_in - 3000000 + temp_value_reserve_a_in - utils.min_pool_ada } else { temp_value_reserve_a_in } @@ -736,65 +488,120 @@ fn get_single_pool_output( pool_output } -pub fn has_single_spending(redeemers: Dict) -> Bool { +pub fn get_trading_fee_numerator( + base_fee_num: Int, + vol_fee_opt: Option, + allow_dynamic_fee: Bool, +) -> Int { + let trading_fee_num = + if allow_dynamic_fee { + when vol_fee_opt is { + None -> base_fee_num + Some(vol_fee_num) -> { + expect + validate_fee_percent( + fee_num: vol_fee_num, + max_fee_num: utils.max_vol_fee_numerator, + min_fee_num: utils.min_vol_fee_numerator, + ) + vol_fee_num + base_fee_num + } + } + } else { + base_fee_num + } + + expect + validate_fee_percent( + fee_num: trading_fee_num, + max_fee_num: utils.max_trading_fee_numerator, + min_fee_num: utils.min_trading_fee_numerator, + ) + trading_fee_num +} + +test test_get_trading_fee_numerator() { + and { + get_trading_fee_numerator( + base_fee_num: utils.max_base_fee_numerator, + vol_fee_opt: None, + allow_dynamic_fee: False, + ) == utils.max_base_fee_numerator, + get_trading_fee_numerator( + base_fee_num: utils.max_base_fee_numerator, + vol_fee_opt: Some(utils.max_vol_fee_numerator), + allow_dynamic_fee: False, + ) == utils.max_base_fee_numerator, + get_trading_fee_numerator( + base_fee_num: utils.max_base_fee_numerator - 200, + vol_fee_opt: Some(200), + allow_dynamic_fee: True, + ) == utils.max_base_fee_numerator, + get_trading_fee_numerator( + base_fee_num: 900, + vol_fee_opt: Some(100), + allow_dynamic_fee: True, + ) == 1000, + } +} + +test test_get_trading_fee_numerator_fail_1() fail { + get_trading_fee_numerator( + base_fee_num: 1900, + vol_fee_opt: Some(300), + allow_dynamic_fee: True, + ) == 2200 +} + +test test_get_trading_fee_numerator_fail_2() fail { + get_trading_fee_numerator( + base_fee_num: 2100, + vol_fee_opt: Some(200), + allow_dynamic_fee: True, + ) == 2300 +} + +test test_get_trading_fee_numerator_fail_3() fail { + get_trading_fee_numerator( + base_fee_num: 1900, + vol_fee_opt: Some(200), + allow_dynamic_fee: True, + ) == 2100 +} + +// Verify that the transaction spends only one Single Pool Script and does not contain any other scripts in its inputs, except for the Author, in cases where the Author is a script +pub fn has_only_pool_and_author( + inputs: List, + pool_address: Address, + author_address: Address, +) -> Bool { + let Address { payment_credential: pool_payment_cred, .. } = pool_address + // Having single pool input expect [_] = - redeemers - |> dict.to_list + inputs |> list.filter( - fn(r) { - let (p, _) = r - when p is { - Spend(_) -> True - _ -> False - } + fn(input) { + let Input { + output: Output { + address: Address { payment_credential: payment_cred, .. }, + .. + }, + .. + } = input + pool_payment_cred == payment_cred }, ) - True -} - -// Validate the admin is authorized by the PubKey wallet's signature or Script wallet validation -pub fn is_admin_existence( - admin_policy_id: PolicyId, - reference_inputs: List, - withdrawals: Dict, - signatories: List>, - validity_range: ValidityRange, -) -> Bool { - // The UTxO is holding Admin token must be represented in the transaction's reference inputs - let admin_input_opt = - list.find( - reference_inputs, - fn(input) { - let Input { output: Output { value: val, .. }, .. } = input - ( val |> value.tokens(admin_policy_id) |> dict.size() ) > 0 - }, - ) - when admin_input_opt is { - Some(admin_input) -> { - // A valid license token is the token having expired timestamp as TokenName and must be within current time and current time + _maximum_deadline_range_ - let (_, _) = - validate_license_expiration_and_find_license_holder( - license_pid: admin_policy_id, - license_input: admin_input, - validity_range: validity_range, - ) - let Input { - output: Output { - address: Address { payment_credential: payment_cred, .. }, - .. - }, - .. - } = admin_input - when payment_cred is { - //If the Admin function is controlled by a PubKey wallet, - // the owners of the UTxO must sign the transaction with their private key. Otherwise, such action must be prohibited. - VerificationKeyCredential(pub_key_hash) -> - list.has(signatories, pub_key_hash) - // If the Admin function is controlled by a Script wallet, - // the smart contract must incorporate a Withdrawal function and execute sufficient conditions to facilitate its operation - ScriptCredential(_) -> dict.has_key(withdrawals, Inline(payment_cred)) - } - } - _ -> False - } + // All inputs does not contain other scripts except for the Pool and Author + inputs + |> list.all( + fn(input) { + let Input { output: Output { address: addr, .. }, .. } = input + let Address { payment_credential: payment_cred, .. } = addr + when payment_cred is { + ScriptCredential(_) -> + payment_cred == pool_payment_cred || addr == author_address + VerificationKeyCredential(_) -> True + } + }, + ) } diff --git a/lib/amm_dex_v2/types.ak b/lib/amm_dex_v2/types.ak index b1b2026..abd2a38 100644 --- a/lib/amm_dex_v2/types.ak +++ b/lib/amm_dex_v2/types.ak @@ -1,6 +1,8 @@ use aiken/dict.{Dict} use aiken/hash.{Blake2b_224, Blake2b_256, Hash} -use aiken/transaction/credential.{Address, Script, VerificationKey} +use aiken/transaction/credential.{ + Address, Script, StakeCredential, VerificationKey, +} use aiken/transaction/value.{AssetName, PolicyId} pub type CustomDatumHash = @@ -12,6 +14,9 @@ pub type ValidatorHash = pub type PubKeyHash = Hash +pub type SortedValueList = + List<(ByteArray, List<(ByteArray, Int)>)> + pub type Asset { policy_id: PolicyId, asset_name: AssetName, @@ -20,42 +25,37 @@ pub type Asset { pub type DatumMap = Dict, Data> -// Profit Sharing Numerator & Denominator -pub type ProfitSharing = - (Int, Int) - pub type PoolDatum { + pool_batching_stake_credential: StakeCredential, asset_a: Asset, asset_b: Asset, total_liquidity: Int, reserve_a: Int, reserve_b: Int, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing_opt: Option, + base_fee_a_numerator: Int, + base_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, + allow_dynamic_fee: Bool, } -pub type UpdatePoolFeeOrStakeCredentialAction { +pub type UpdatePoolParametersAction { UpdatePoolFee + UpdateDynamicFee UpdatePoolStakeCredential } pub type PoolRedeemer { - Batching { - input_indexes: List, - orders_fee: List, - license_index: Int, - } - MultiRouting { - license_index: Int, - routing_in_indexes: List, - routing_out_indexes: List, - order_fee: Int, - } - UpdatePoolFeeOrStakeCredential { - action: UpdatePoolFeeOrStakeCredentialAction, - } - WithdrawLiquidityShare + Batching + UpdatePoolParameters { action: UpdatePoolParametersAction } + WithdrawFeeSharing +} + +pub type PoolBatchingRedeemer { + batcher_index: Int, + orders_fee: List, + input_indexes: ByteArray, + pool_input_indexes_opt: Option, + vol_fees: List>, } pub type SwapRouting { @@ -63,6 +63,36 @@ pub type SwapRouting { a_to_b_direction: Bool, } +// Option when someone want to swap a token +pub type SwapAmountOption { + // Swap a specific amount of token + SAOSpecificAmount { swap_amount: Int } + // Swap a all amount of the token that is available on the order's value + // @deducted_amount will be subtract from the amount + // This option is useful for integration where the creator doesn't know the exact amount that will be swapped + SAOAll { deducted_amount: Int } +} + +// Option when someone want to deposit tokens +pub type DepositAmountOption { + // Deposit specific amount of tokens + DAOSpecificAmount { deposit_amount_a: Int, deposit_amount_b: Int } + // Deposit all amount of the tokens that are available on the order's value + // @deducted_amount_a and @deducted_amount_b will be subtract from the amount + // This option is useful for integration where the creator doesn't know the exact amount that will be deposited + DAOAll { deducted_amount_a: Int, deducted_amount_b: Int } +} + +// Option when someone want to withdraw tokens +pub type WithdrawAmountOption { + // Withdraw specific amount of LP Token + WAOSpecificAmount { withdrawal_lp_amount: Int } + // Withdrawl all amount of the LP token that is available on the order's value + // @deducted_amount_lp will be subtract from the amount + // This option is useful for integration where the creator doesn't know the exact amount that will be withdrawn + WAOAll { deducted_amount_lp: Int } +} + pub type OrderStep { // SwapExactIn is used for exchanging specific amount of single asset in the liquidity pool. // The order will be executed if the received amount is greater than or equal to `minimum_receive`. @@ -70,7 +100,7 @@ pub type OrderStep { // The AToB direction of swap request. True for A -> B and False for B -> A a_to_b_direction: Bool, // Amount of Asset In which users want to exchange - swap_amount: Int, + swap_amount_option: SwapAmountOption, // Minimum amount of Asset Out which users want to receive after exchanging minimum_receive: Int, // Decide the Order behavior in case Order is not meet the slippage tolerance @@ -82,11 +112,9 @@ pub type OrderStep { // The AToB direction of swap request. True for A -> B and False for B -> A a_to_b_direction: Bool, // Amount of Asset In which users want to exchange - swap_amount: Int, + swap_amount_option: SwapAmountOption, // Maximum amount of Asset Out which users want to receive after exchanging stop_loss_receive: Int, - // Decide the Order behavior in case Order is not meet the slippage tolerance - killable: Bool, } // OCO is used for exchanging specific amount of single asset in the liquidity pool. // The order will be executed if the received amount is less than or equal to `stop_loss_receive` @@ -95,13 +123,11 @@ pub type OrderStep { // The AToB direction of swap request. True for A -> B and False for B -> A a_to_b_direction: Bool, // Amount of Asset In which users want to exchange - swap_amount: Int, + swap_amount_option: SwapAmountOption, // Minimum amount of Asset Out which users want to receive after exchanging minimum_receive: Int, // Maximum amount of Asset Out which users want to receive after exchanging stop_loss_receive: Int, - // Decide the Order behavior in case Order is not meet the slippage tolerance - killable: Bool, } // SwapExactOut is used for exchanging single asset in the liquidity pool and receiving the exact amout of other asset. // The order will be executed if the received amount is equal to `expected_receive` @@ -109,7 +135,7 @@ pub type OrderStep { // The AToB direction of swap request. True for A -> B and False for B -> A a_to_b_direction: Bool, // Maximum amount of Asset In which users want to exchange - maximum_swap_amount: Int, + maximum_swap_amount_option: SwapAmountOption, // The exact amount of Asset Out which users want to receive after exchanging expected_receive: Int, // Decide the Order behavior in case Order is not meet the slippage tolerance @@ -117,10 +143,8 @@ pub type OrderStep { } // Deposit is used for depositing pool's assets and receiving LP Token Deposit { - // Amount of Asset A which users want to deposit - deposit_amount_a: Int, - // Amount of Asset B which users want to deposit - deposit_amount_b: Int, + // Amount of Asset A and B which users want to deposit + deposit_amount_option: DepositAmountOption, // The minimum amount of LP Token which users want to receive after depositing minimum_lp: Int, // Decide the Order behavior in case Order is not meet the slippage tolerance @@ -129,7 +153,7 @@ pub type OrderStep { // Withdraw is used for withdrawing pool's asset with the exact assets ratio of the liquidity pool at that time Withdraw { // Amount of LP Asset which users want to withdraw - withdrawal_lp_amount: Int, + withdrawal_amount_option: WithdrawAmountOption, // minimum received amounts of Asset A minimum_asset_a: Int, // minimum received amounts of Asset B @@ -142,7 +166,7 @@ pub type OrderStep { // The AToB direction of ZapOut request. `True` in case Asset Out is B and vice versa a_to_b_direction: Bool, // Amount of LP Asset which users want to withdraw - withdrawal_lp_amount: Int, + withdrawal_amount_option: WithdrawAmountOption, // Minimum amount of Asset Out which users want to receive after withdrawing minimum_receive: Int, // Decide the Order behavior in case Order is not meet the slippage tolerance @@ -169,7 +193,7 @@ pub type OrderStep { // WithdrawImbalance is used for withdrawing custom amount of assets. WithdrawImbalance { // Amount of LP Asset which users want to withdraw - withdrawal_lp_amount: Int, + withdrawal_amount_option: WithdrawAmountOption, // The ratio of Asset A and Asset B users want to receive after withdrawing ratio_asset_a: Int, ratio_asset_b: Int, @@ -186,21 +210,37 @@ pub type OrderStep { // which is defined Liquidity Pools the swap is routing through routings: List, // Amount of Asset In which users want to exchange - swap_amount: Int, + swap_amount_option: SwapAmountOption, // Minimum amount of Asset Out which users want to receive after exchanging minimum_receive: Int, } + Donation +} + +pub type ExtraOrderDatum { + EODNoDatum + EODDatumHash { hash: CustomDatumHash } + EODInlineDatum { hash: CustomDatumHash } +} + +pub type OrderAuthorizationMethod { + OAMSignature { pub_key_hash: PubKeyHash } + OAMSpendScript { script_hash: ValidatorHash } + OAMWithdrawScript { script_hash: ValidatorHash } + OAMMintScript { script_hash: ValidatorHash } } pub type OrderDatum { - // The address of order's creator, only sender can cancel the order immediately - sender: Address, + // The address's payment credential that can cancel the order, can by PubKey or Script + canceller: OrderAuthorizationMethod, + // The address of the output after being killed by Batcher or cancelled by bots (order is expired) + refund_receiver: Address, // The datum hash of the output after being killed by Batcher or cancelled by bots (order is expired) - sender_datum_hash_opt: Option, + refund_receiver_datum: ExtraOrderDatum, // The address which receives the funds after order is processed - receiver: Address, + success_receiver: Address, // The datum hash of the output after order is processed. - receiver_datum_hash_opt: Option, + success_receiver_datum: ExtraOrderDatum, // The Liquidity Pool's LP Asset that the order will be applied to lp_asset: Asset, // The information about Order Type @@ -231,23 +271,17 @@ pub type FactoryRedeemer { } pub type AuthenRedeemer { - MintFactoryAuthen + DexInitialization CreatePool } -pub type OrderSpendingRedeemer { - // it's used for finding Pool Input faster - pool_input_index: Int, -} - pub type BatchingPool { asset_a: Asset, asset_b: Asset, lp_asset: Asset, - trading_fee_numerator: Int, - trading_fee_denominator: Int, - profit_sharing: Option<(Int, Int)>, - address: Address, + trading_fee_a_numerator: Int, + trading_fee_b_numerator: Int, + fee_sharing_numerator_opt: Option, pool_state_in: PoolState, pool_state_out: PoolState, } @@ -259,3 +293,20 @@ pub type BatchingPool { // Total Liquidity pub type PoolState = (Int, Int, Int, Int, Int) + +// This setting grants permissions to authorized actors who can interact with Liquidity Pool features. +pub type GlobalSetting { + // List of authorized batchers who can process orders. + batchers: List

, + // The actor who can update the Pool's base fee and fee sharing. + pool_fee_updater: Address, + // The actor who can withdraw the Pool's fee sharing. + fee_sharing_taker: Address, + // The actor who can change the Pool's stake key. + pool_stake_key_updater: Address, + // The actor who can update the Pool's dynamic fee. + pool_dynamic_fee_updater: Address, + // The actor who can update the addresses mentioned above. + // This admin can be transferred to another wallet and should be stored in the most secure location. + admin: Address, +} diff --git a/lib/amm_dex_v2/utils.ak b/lib/amm_dex_v2/utils.ak index 0c46486..0ac7070 100644 --- a/lib/amm_dex_v2/utils.ak +++ b/lib/amm_dex_v2/utils.ak @@ -2,34 +2,57 @@ use aiken/builtin use aiken/bytearray use aiken/dict use aiken/hash -use aiken/string -use aiken/transaction.{Datum, DatumHash, InlineDatum, NoDatum} -use aiken/transaction/value.{AssetName, PolicyId, ada_asset_name, ada_policy_id} -use amm_dex_v2/types.{Asset, DatumMap} - -const zero_ascii_code = 48 - -const nine_ascii_code = 57 - -// Policy ID managed by the Minswap team, used for minting Batcher License -pub const batcher_license_policy_id = - #"229013ad3a22d2d051a28e7f9214a32444ecf19998f7bdf0c2849862" +use aiken/interval.{Finite, Interval, IntervalBound} +use aiken/list +use aiken/transaction.{Datum, DatumHash, InlineDatum, NoDatum, ValidityRange} +use aiken/transaction/value.{ + AssetName, PolicyId, Value, ada_asset_name, ada_policy_id, +} +use amm_dex_v2/types.{Asset, DatumMap, SortedValueList} // the legitimate Pool TokenName pub const pool_auth_asset_name = #"4d5350" // the legitimate Factory TokenName -pub const factory_auth_asset_name = #"4d53" +pub const factory_auth_asset_name = #"4d5346" -// Policy ID managed by the Minswap team, used for minting Admin License assets -pub const admin_policy_id = - #"f8c20eb8b2e773e21cf41ab6354cf09bd255ebed0bd8847c655e67b4" - -// Maximum expiration time of Batcher license from now (to prevent minting infinity license) -pub const maximum_deadline_range = 77760000000 +// the legitimate Global Setting TokenName +pub const global_setting_asset_name = #"4d534753" pub const default_burn_liquidity = 10 +pub const default_fee_denominator = 10000 + +// Base Fee constraint +// Max 20% +pub const max_base_fee_numerator = 2000 + +// Min 0.05% +pub const min_base_fee_numerator = 5 + +// Vol Fee constraint +// Max 2% +pub const max_vol_fee_numerator = 200 + +// Min 0% +pub const min_vol_fee_numerator = 0 + +// Trading Fee constraint +// Max 20% +pub const max_trading_fee_numerator = 2000 + +// Min 0.05% +pub const min_trading_fee_numerator = 5 + +// Fee Sharing constraint +// Max 50% +pub const max_fee_sharing_numerator = 5000 + +// Min 16.66% +pub const min_fee_sharing_numerator = 1666 + +pub const min_pool_ada = 4500000 + pub fn sorted_asset(asset_a: Asset, asset_b: Asset) -> Bool { let Asset { policy_id: asset_a_policy_id, asset_name: asset_a_asset_name } = asset_a @@ -90,33 +113,13 @@ test test_compute_lp_asset_name() { lp_asset_name == #"82e2b1fd27a7712a1a9cf750dfbea1a5778611b20e06dd6a611df7a643f8cb75" } -pub fn bytearray_to_positive_int(byte_arr: ByteArray) -> Int { - let byte_len = builtin.length_of_bytearray(byte_arr) - do_bytearray_positive_int(byte_arr, byte_len - 1) -} - -pub fn do_bytearray_positive_int(byte_arr: ByteArray, idx: Int) -> Int { - let byte = builtin.index_bytearray(byte_arr, idx) - if zero_ascii_code <= byte && byte <= nine_ascii_code { - if idx == 0 { - byte - zero_ascii_code - } else { - do_bytearray_positive_int(byte_arr, idx - 1) * 10 + ( - byte - zero_ascii_code - ) - } - } else { - fail +pub fn must_find_script_inline_datum(datum: Datum) -> Data { + when datum is { + InlineDatum(dat) -> dat + _ -> fail } } -test test_bytearray_to_positive_int() { - let r1 = bytearray_to_positive_int(string.to_bytearray(@"123")) - let r2 = bytearray_to_positive_int(string.to_bytearray(@"111")) - let r3 = bytearray_to_positive_int(string.to_bytearray(@"9013")) - r1 == 123 && r2 == 111 && r3 == 9013 -} - pub fn must_find_script_datum(datums: DatumMap, datum: Datum) -> Data { when datum is { InlineDatum(dat) -> dat @@ -233,36 +236,23 @@ test test_list_at_index() { pub fn zip_with( arr1: List, arr2: List, - predicate: fn(a, b) -> result, + arr3: List, + predicate: fn(a, b, c) -> result, ) -> List { expect [x, ..xs] = arr1 expect [y, ..ys] = arr2 + expect [z, ..zs] = arr3 if xs == [] { - expect [] = ys - [predicate(x, y)] + expect and { + [] == ys, + [] == zs, + } + [predicate(x, y, z)] } else { - [predicate(x, y), ..zip_with(xs, ys, predicate)] + [predicate(x, y, z), ..zip_with(xs, ys, zs, predicate)] } } -test test_zip_with() { - let arr1 = - [1, 2, 3] - let arr2 = - [4, 5, 6] - let z1 = zip_with(arr1, arr2, fn(a1, a2) { a1 + a2 }) - let z2 = zip_with(arr1, arr2, fn(a1, a2) { a1 * a2 }) - z1 == [5, 7, 9] && z2 == [4, 10, 18] -} - -test test_zip_with_throw_err() fail { - let arr1 = - [1, 2, 3] - let arr2 = - [4, 5, 6, 6] - zip_with(arr1, arr2, fn(a1, a2) { a1 + a2 }) == [] -} - pub fn compare_list_length(arr1: List, arr2: List) -> Bool { when arr1 is { [] -> arr2 == [] @@ -310,17 +300,207 @@ test test_compare_list_length_3() { !compare_list_length(arr1, arr2) } -fn contains_element(list: List, elem: a) -> Bool { - when list is { - [] -> False - [x, ..xs] -> elem == x || contains_element(xs, elem) +const empty_mark = + #[0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ] + +fn do_is_unique_bytearray_unsorted( + self: ByteArray, + acc: ByteArray, + index: Int, + length: Int, +) { + if index >= length { + True + } else { + let value_as_index = builtin.index_bytearray(self, index) + let acc_value = builtin.index_bytearray(acc, value_as_index) + if acc_value == 1 { + False + } else { + let left_slice = builtin.slice_bytearray(0, value_as_index, acc) + let righ_slice = builtin.slice_bytearray(value_as_index + 1, 64, acc) + let new_acc = + builtin.append_bytearray( + left_slice, + builtin.cons_bytearray(1, righ_slice), + ) + do_is_unique_bytearray_unsorted(self, new_acc, index + 1, length) + } + } +} + +pub fn is_unique_bytearray_unsorted(array: ByteArray) -> Bool { + let length = builtin.length_of_bytearray(array) + if length > 0 { + do_is_unique_bytearray_unsorted(array, empty_mark, 0, length) + } else { + False } } -pub fn is_list_unique(list: List) -> Bool { - when list is { - [] -> True - [_] -> True - [x, ..xs] -> !contains_element(xs, x) && is_list_unique(xs) +test test_unique_bytearray_unsorted_1() { + let array = + #[1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + ] + is_unique_bytearray_unsorted(array) +} + +test test_unique_bytearray_unsorted_2() { + let array = #[1, 2, 3, 4, 5, 6, 5] + !is_unique_bytearray_unsorted(array) +} + +test test_unique_bytearray_unsorted_3() { + let array = #[0, 1, 2, 3, 4, 5, 6, 0] + !is_unique_bytearray_unsorted(array) +} + +test test_unique_bytearray_unsorted_4() fail { + let array = #[0, 1, 2, 3, 4, 5, 64, 0] + !is_unique_bytearray_unsorted(array) +} + +test test_unique_bytearray_unsorted_5() { + let array = #[] + !is_unique_bytearray_unsorted(array) +} + +// Approximate the current time by obtaining the upper and lower bounds of the validity range. +// Ensure that the bounds do not exceed 10 minutes. +pub fn must_get_current_time_approximation(validity_range: ValidityRange) -> Int { + let Interval { + lower_bound: IntervalBound { bound_type: lower_bound_type, .. }, + upper_bound: IntervalBound { bound_type: upper_bound_type, .. }, + } = validity_range + expect Finite(start_valid_time_range) = lower_bound_type + expect Finite(end_valid_time_range) = upper_bound_type + if end_valid_time_range - start_valid_time_range <= 10 * 60 * 1000 { + ( end_valid_time_range - start_valid_time_range ) / 2 + start_valid_time_range + } else { + fail } } + +pub fn must_get_finite_start_validity(validity_range: ValidityRange) -> Int { + let Interval { + lower_bound: IntervalBound { bound_type: lower_bound_type, .. }, + .. + } = validity_range + expect Finite(start_valid_time_range) = lower_bound_type + start_valid_time_range +} + +pub fn value_to_list(val: Value) -> SortedValueList { + val + |> value.to_dict + |> dict.to_list + |> list.map( + fn(e) { + let (k, v) = e + (k, dict.to_list(v)) + }, + ) +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2cb31c4 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6981 @@ +{ + "name": "@minswap/sdk", + "version": "0.2.2-beta", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@minswap/sdk", + "version": "0.2.2-beta", + "license": "MIT", + "dependencies": { + "@blockfrost/blockfrost-js": "^5.3.1", + "@minswap/tiny-invariant": "^1.2.0", + "big.js": "^6.1.1", + "lucid-cardano": "^0.10.7", + "sha3": "^2.1.4" + }, + "devDependencies": { + "@types/big.js": "^6.1.3", + "@types/jest": "^27.5.2", + "@types/json-bigint": "^1.0.1", + "@typescript-eslint/eslint-plugin": "^5.20.0", + "@typescript-eslint/parser": "^5.20.0", + "esbuild": "^0.14.38", + "eslint": "^8.13.0", + "eslint-plugin-simple-import-sort": "^7.0.0", + "eslint-plugin-unicorn": "^48.0.1", + "eslint-plugin-unused-imports": "^2.0.0", + "jest": "^29.3.1", + "json-bigint": "^1.0.0", + "prettier": "3.0.0", + "rollup": "^2.70.2", + "rollup-plugin-dts": "^4.2.1", + "rollup-plugin-esbuild": "^4.9.1", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.1", + "typescript": "^4.6.3" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", + "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.9.tgz", + "integrity": "sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.9", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.9", + "@babel/parser": "^7.17.9", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.9", + "@babel/types": "^7.17.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.9.tgz", + "integrity": "sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", + "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", + "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", + "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", + "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.9", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", + "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.9.tgz", + "integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.9", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.9", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@blockfrost/blockfrost-js": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@blockfrost/blockfrost-js/-/blockfrost-js-5.4.0.tgz", + "integrity": "sha512-al9rAlwXFsuLOCoY1yG5ib73BqCzY8hP/oVAIbmLlkRwUut+wDOxv8SDkr4jrW80vW7Grom1TbpNEPSWRqgsUg==", + "dependencies": { + "@blockfrost/openapi": "0.1.59", + "@emurgo/cardano-serialization-lib-nodejs": "^11.4.0", + "@emurgo/cip14-js": "3.0.1", + "bottleneck": "^2.19.5", + "form-data": "^4.0.0", + "got": "^11.8.6", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@blockfrost/openapi": { + "version": "0.1.59", + "resolved": "https://registry.npmjs.org/@blockfrost/openapi/-/openapi-0.1.59.tgz", + "integrity": "sha512-Ia3pwPekwOFQDYJZtPch6N9ZcL35R0lEoIxqsXun/M4nE89eM09fORCVWnQy9QjaADDFA5tSIJqhg3L7wHtUKA==", + "dependencies": { + "ajv": "^8.11.2", + "cbor": "^8.1.0", + "yaml": "^2.2.1" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@emurgo/cardano-serialization-lib-nodejs": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-11.4.0.tgz", + "integrity": "sha512-dMiofDcqv+IrAITCgWBZmsMLqwv2xImDsJDSrKiYYG1zRKaL8XfMOxx6S0WEnKVj5/343Q5FFURYcSu3iBRNMQ==" + }, + "node_modules/@emurgo/cip14-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@emurgo/cip14-js/-/cip14-js-3.0.1.tgz", + "integrity": "sha512-u0XobeajNSlmeGBmY3ntA+NE/Vns7hKP0xrFzWyAO7YubETOifTjUddJN4gpvXE4S08DPUcNBVe3sx1m5GPIOg==", + "dependencies": { + "bech32": "2.0.0", + "blake2b": "2.1.3" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", + "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", + "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.2.tgz", + "integrity": "sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.6.2", + "jest-util": "^29.6.2", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.2.tgz", + "integrity": "sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.2", + "@jest/reporters": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.6.2", + "jest-haste-map": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.2", + "jest-resolve-dependencies": "^29.6.2", + "jest-runner": "^29.6.2", + "jest-runtime": "^29.6.2", + "jest-snapshot": "^29.6.2", + "jest-util": "^29.6.2", + "jest-validate": "^29.6.2", + "jest-watcher": "^29.6.2", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.2", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@jest/environment": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.2.tgz", + "integrity": "sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.6.2", + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-mock": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.2.tgz", + "integrity": "sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg==", + "dev": true, + "dependencies": { + "expect": "^29.6.2", + "jest-snapshot": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.2.tgz", + "integrity": "sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.2.tgz", + "integrity": "sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.6.2", + "jest-mock": "^29.6.2", + "jest-util": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.2.tgz", + "integrity": "sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.2", + "@jest/expect": "^29.6.2", + "@jest/types": "^29.6.1", + "jest-mock": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.2.tgz", + "integrity": "sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.6.2", + "jest-util": "^29.6.2", + "jest-worker": "^29.6.2", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.0.tgz", + "integrity": "sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.2.tgz", + "integrity": "sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.2", + "@jest/types": "^29.6.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.2.tgz", + "integrity": "sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.6.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.2", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.2.tgz", + "integrity": "sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.2", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@jest/types": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@minswap/tiny-invariant": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@minswap/tiny-invariant/-/tiny-invariant-1.2.0.tgz", + "integrity": "sha512-m4CMTsZ4MDB2WLND6rV0eti+f2WcMPhKvXf9ZHXlQMqvNmgoX1z//84FpEX0D1vVTPfJtNS8XIoIQ9pm6X590A==" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz", + "integrity": "sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==", + "dependencies": { + "asn1js": "^3.0.5", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@peculiar/asn1-schema/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@peculiar/json-schema/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/@peculiar/webcrypto": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz", + "integrity": "sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==", + "dependencies": { + "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/json-schema": "^1.1.12", + "pvtsutils": "^1.3.2", + "tslib": "^2.5.0", + "webcrypto-core": "^1.7.7" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@peculiar/webcrypto/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/big.js": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@types/big.js/-/big.js-6.1.3.tgz", + "integrity": "sha512-fHh2h1cFlvGP0kFCqoAsnuQoM0n3xHB6HxgZvELt7dji+BtK/j938MRL0nG5AA45EgibuFcPjgLlkqfUPCyoKw==", + "dev": true + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "dev": true, + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/json-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/json-bigint/-/json-bigint-1.0.1.tgz", + "integrity": "sha512-zpchZLNsNuzJHi6v64UBoFWAvQlPhch7XAi36FkH6tL1bbbmimIF+cS7vwkzY4u5RaSWMoflQfu+TshMPPw8uw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.4.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", + "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.20.0.tgz", + "integrity": "sha512-fapGzoxilCn3sBtC6NtXZX6+P/Hef7VDbyfGqTTpzYydwhlkevB+0vE0EnmHPVTVSy68GUncyJ/2PcrFBeCo5Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.20.0", + "@typescript-eslint/type-utils": "5.20.0", + "@typescript-eslint/utils": "5.20.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.20.0.tgz", + "integrity": "sha512-UWKibrCZQCYvobmu3/N8TWbEeo/EPQbS41Ux1F9XqPzGuV7pfg6n50ZrFo6hryynD8qOTTfLHtHjjdQtxJ0h/w==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.20.0", + "@typescript-eslint/types": "5.20.0", + "@typescript-eslint/typescript-estree": "5.20.0", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.20.0.tgz", + "integrity": "sha512-h9KtuPZ4D/JuX7rpp1iKg3zOH0WNEa+ZIXwpW/KWmEFDxlA/HSfCMhiyF1HS/drTICjIbpA6OqkAhrP/zkCStg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.20.0", + "@typescript-eslint/visitor-keys": "5.20.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.20.0.tgz", + "integrity": "sha512-WxNrCwYB3N/m8ceyoGCgbLmuZwupvzN0rE8NBuwnl7APgjv24ZJIjkNzoFBXPRCGzLNkoU/WfanW0exvp/+3Iw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.20.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.20.0.tgz", + "integrity": "sha512-+d8wprF9GyvPwtoB4CxBAR/s0rpP25XKgnOvMf/gMXYDvlUC3rPFHupdTQ/ow9vn7UDe5rX02ovGYQbv/IUCbg==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.20.0.tgz", + "integrity": "sha512-36xLjP/+bXusLMrT9fMMYy1KJAGgHhlER2TqpUVDYUQg4w0q/NW/sg4UGAgVwAqb8V4zYg43KMUpM8vV2lve6w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.20.0", + "@typescript-eslint/visitor-keys": "5.20.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.20.0.tgz", + "integrity": "sha512-lHONGJL1LIO12Ujyx8L8xKbwWSkoUKFSO+0wDAqGXiudWB2EO7WEUT+YZLtVbmOmSllAjLb9tpoIPwpRe5Tn6w==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.20.0", + "@typescript-eslint/types": "5.20.0", + "@typescript-eslint/typescript-estree": "5.20.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.20.0.tgz", + "integrity": "sha512-1flRpNF+0CAQkMNlTJ6L/Z5jiODG/e5+7mk6XwtPOUS3UrTz3UOiAg9jG2VtKsWI6rZQfy4C6a232QNRZTRGlg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.20.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1js": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", + "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", + "dependencies": { + "pvtsutils": "^1.3.2", + "pvutils": "^1.1.3", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/asn1js/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/babel-jest": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.2.tgz", + "integrity": "sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.6.2", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" + }, + "node_modules/big.js": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.1.1.tgz", + "integrity": "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", + "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==", + "engines": { + "node": "*" + } + }, + "node_modules/blake2b": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.3.tgz", + "integrity": "sha512-pkDss4xFVbMb4270aCyGD3qLv92314Et+FsKzilCLxDz5DuZ2/1g3w4nmBbu6nKApPspnjG7JcwTjGZnduB1yg==", + "dependencies": { + "blake2b-wasm": "^1.1.0", + "nanoassert": "^1.0.0" + } + }, + "node_modules/blake2b-wasm": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-1.1.7.tgz", + "integrity": "sha512-oFIHvXhlz/DUgF0kq5B1CqxIDjIJwh9iDeUUGQUcvgiGz7Wdw03McEO7CfLBy7QKGdsydcMCgO9jFNBAFCtFcA==", + "dependencies": { + "nanoassert": "^1.0.0" + } + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", + "escalade": "^3.1.1", + "node-releases": "^2.0.3", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001332", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz", + "integrity": "sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.0.tgz", + "integrity": "sha512-3sSQTYoWKGcRHmHl6Y6opLpRJH55bxeGQ0Y1LCI5pZzUXvokVkj0FC4bi7uEwazxA9FQZ0Nv067Zt5kSUvXxEA==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.122", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.122.tgz", + "integrity": "sha512-VuLNxTIt8sBWIT2sd186xPd18Y8KcK8myLd9nMdSJOYZwFUxxbLVmX/T1VX+qqaytRlrYYQv39myxJdXtu7Ysw==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.38.tgz", + "integrity": "sha512-12fzJ0fsm7gVZX1YQ1InkOE5f9Tl7cgf6JPYXRJtPIoE0zkWAbHdPHVPPaLi9tYAcEBqheGzqLn/3RdTOyBfcA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "esbuild-android-64": "0.14.38", + "esbuild-android-arm64": "0.14.38", + "esbuild-darwin-64": "0.14.38", + "esbuild-darwin-arm64": "0.14.38", + "esbuild-freebsd-64": "0.14.38", + "esbuild-freebsd-arm64": "0.14.38", + "esbuild-linux-32": "0.14.38", + "esbuild-linux-64": "0.14.38", + "esbuild-linux-arm": "0.14.38", + "esbuild-linux-arm64": "0.14.38", + "esbuild-linux-mips64le": "0.14.38", + "esbuild-linux-ppc64le": "0.14.38", + "esbuild-linux-riscv64": "0.14.38", + "esbuild-linux-s390x": "0.14.38", + "esbuild-netbsd-64": "0.14.38", + "esbuild-openbsd-64": "0.14.38", + "esbuild-sunos-64": "0.14.38", + "esbuild-windows-32": "0.14.38", + "esbuild-windows-64": "0.14.38", + "esbuild-windows-arm64": "0.14.38" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.38.tgz", + "integrity": "sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.38.tgz", + "integrity": "sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.38.tgz", + "integrity": "sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.38.tgz", + "integrity": "sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.38.tgz", + "integrity": "sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.38.tgz", + "integrity": "sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.38.tgz", + "integrity": "sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.38.tgz", + "integrity": "sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.38.tgz", + "integrity": "sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.38.tgz", + "integrity": "sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.38.tgz", + "integrity": "sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.38.tgz", + "integrity": "sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.38.tgz", + "integrity": "sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.38.tgz", + "integrity": "sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.38.tgz", + "integrity": "sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.38.tgz", + "integrity": "sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz", + "integrity": "sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.38.tgz", + "integrity": "sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.38.tgz", + "integrity": "sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.38", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.38.tgz", + "integrity": "sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", + "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.1", + "@eslint/js": "^8.46.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.2", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-simple-import-sort": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz", + "integrity": "sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==", + "dev": true, + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "48.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-48.0.1.tgz", + "integrity": "sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "@eslint-community/eslint-utils": "^4.4.0", + "ci-info": "^3.8.0", + "clean-regexp": "^1.0.0", + "esquery": "^1.5.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.1", + "jsesc": "^3.0.2", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.10.0", + "semver": "^7.5.4", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=8.44.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/regjsparser": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/eslint-plugin-unused-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz", + "integrity": "sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==", + "dev": true, + "dependencies": { + "eslint-rule-composer": "^0.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, + "node_modules/eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.2.tgz", + "integrity": "sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.6.2", + "@types/node": "*", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-util": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expect/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/jest-diff": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.2.tgz", + "integrity": "sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/jest-matcher-utils": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz", + "integrity": "sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.6.2", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.2.tgz", + "integrity": "sha512-8eQg2mqFbaP7CwfsTpCxQ+sHzw1WuNWL5UUvjnWP4hx2riGz9fPSzYOaU5q8/GqWn1TfgZIVTqYJygbGbWAANg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.2", + "@jest/types": "^29.6.1", + "import-local": "^3.0.2", + "jest-cli": "^29.6.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.2.tgz", + "integrity": "sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.2", + "@jest/expect": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.6.2", + "jest-matcher-utils": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-runtime": "^29.6.2", + "jest-snapshot": "^29.6.2", + "jest-util": "^29.6.2", + "p-limit": "^3.1.0", + "pretty-format": "^29.6.2", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-diff": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.2.tgz", + "integrity": "sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-matcher-utils": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz", + "integrity": "sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.6.2", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-cli": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.2.tgz", + "integrity": "sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/types": "^29.6.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.6.2", + "jest-util": "^29.6.2", + "jest-validate": "^29.6.2", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.2.tgz", + "integrity": "sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.6.2", + "@jest/types": "^29.6.1", + "babel-jest": "^29.6.2", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.6.2", + "jest-environment-node": "^29.6.2", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.2", + "jest-runner": "^29.6.2", + "jest-util": "^29.6.2", + "jest-validate": "^29.6.2", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.6.2", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.2.tgz", + "integrity": "sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.6.2", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-environment-node": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.2.tgz", + "integrity": "sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.2", + "@jest/fake-timers": "^29.6.2", + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-mock": "^29.6.2", + "jest-util": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.2.tgz", + "integrity": "sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.2", + "jest-worker": "^29.6.2", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.2.tgz", + "integrity": "sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.2.tgz", + "integrity": "sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.2.tgz", + "integrity": "sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-util": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.2.tgz", + "integrity": "sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.2", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.6.2", + "jest-validate": "^29.6.2", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.2.tgz", + "integrity": "sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.2.tgz", + "integrity": "sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.2", + "@jest/environment": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.6.2", + "jest-haste-map": "^29.6.2", + "jest-leak-detector": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-resolve": "^29.6.2", + "jest-runtime": "^29.6.2", + "jest-util": "^29.6.2", + "jest-watcher": "^29.6.2", + "jest-worker": "^29.6.2", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.2.tgz", + "integrity": "sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.2", + "@jest/fake-timers": "^29.6.2", + "@jest/globals": "^29.6.2", + "@jest/source-map": "^29.6.0", + "@jest/test-result": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-mock": "^29.6.2", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.2", + "jest-snapshot": "^29.6.2", + "jest-util": "^29.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.2.tgz", + "integrity": "sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.6.2", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.6.2", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-util": "^29.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^29.6.2", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.2.tgz", + "integrity": "sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz", + "integrity": "sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.6.2", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.2.tgz", + "integrity": "sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.2.tgz", + "integrity": "sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.6.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-watcher": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.2.tgz", + "integrity": "sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.6.2", + "@jest/types": "^29.6.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.6.2", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.2.tgz", + "integrity": "sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.6.2", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lucid-cardano": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/lucid-cardano/-/lucid-cardano-0.10.7.tgz", + "integrity": "sha512-hxJRMWj8VH+SGFqsVMG6T3LSRuxzwFbWOQ5DTGQQUyR/20FL7bjiVL+2ivMJF52tAbFKcwqpRD4fddR7LbqcAw==", + "dependencies": { + "@peculiar/webcrypto": "^1.4.0", + "node-fetch": "^3.2.3", + "ws": "^8.10.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/magic-string": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.1.tgz", + "integrity": "sha512-ndThHmvgtieXe8J/VGPjG+Apu7v7ItcD5mhEIvOscWjPF/ccOiLxHaSuCAS2G+3x4GKsAbT8u7zdyamupui8Tg==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoassert": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", + "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40=" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.3.tgz", + "integrity": "sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw==", + "dev": true + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "engines": { + "node": ">=12.19" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pvtsutils": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.2.tgz", + "integrity": "sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/pvtsutils/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "2.70.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.2.tgz", + "integrity": "sha512-EitogNZnfku65I1DD5Mxe8JYRUCy0hkK5X84IlDtUs+O6JRMpRciXTzyCUuX11b5L5pvjH+OmFXiQ3XjabcXgg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-dts": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.2.1.tgz", + "integrity": "sha512-eaxQZNUJ5iQcxNGlpJ1CUgG4OSVqWjDZ3nNSWBIoGrpcote2aNphSe1RJOaSYkb8dwn3o+rYm1vvld/5z3EGSQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.26.1" + }, + "engines": { + "node": ">=v12.22.11" + }, + "funding": { + "url": "https://github.com/sponsors/Swatinem" + }, + "optionalDependencies": { + "@babel/code-frame": "^7.16.7" + }, + "peerDependencies": { + "rollup": "^2.70", + "typescript": "^4.6" + } + }, + "node_modules/rollup-plugin-esbuild": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-4.9.1.tgz", + "integrity": "sha512-qn/x7Wz9p3Xnva99qcb+nopH0d2VJwVnsxJTGEg+Sh2Z3tqQl33MhOwzekVo1YTKgv+yAmosjcBRJygMfGrtLw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^4.1.1", + "debug": "^4.3.3", + "es-module-lexer": "^0.9.3", + "joycon": "^3.0.1", + "jsonc-parser": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "esbuild": ">=0.10.1", + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sha3": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/sha3/-/sha3-2.1.4.tgz", + "integrity": "sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==", + "dependencies": { + "buffer": "6.0.3" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webcrypto-core": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.7.tgz", + "integrity": "sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==", + "dependencies": { + "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/json-schema": "^1.1.12", + "asn1js": "^3.0.1", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } + }, + "node_modules/webcrypto-core/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..185d466 --- /dev/null +++ b/package.json @@ -0,0 +1,70 @@ +{ + "name": "@minswap/sdk", + "version": "0.2.2-beta", + "description": "Query Minswap data and build transactions", + "type": "module", + "types": "./build/index.d.ts", + "exports": { + ".": { + "types": "./build/index.d.ts", + "import": "./build/index.es.js" + } + }, + "files": [ + "build" + ], + "scripts": { + "build": "rimraf build && rollup -c rollup.config.js", + "test": "NODE_OPTIONS=--experimental-vm-modules jest && tsc", + "lint": "eslint src --ext .ts", + "format": "prettier --write **/*.ts && eslint src --fix --ext .ts", + "check-format": "prettier --check **/*.ts && eslint src --ext .ts", + "exec": "ts-node --esm --experimental-specifier-resolution=node" + }, + "keywords": [ + "minswap", + "cardano", + "blockfrost", + "dex", + "blockchain", + "lucid" + ], + "author": "Minswap Labs", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/minswap/sdk.git" + }, + "bugs": { + "url": "https://github.com/minswap/sdk/issues" + }, + "homepage": "https://github.com/minswap/sdk#readme", + "dependencies": { + "@blockfrost/blockfrost-js": "^5.3.1", + "@minswap/tiny-invariant": "^1.2.0", + "big.js": "^6.1.1", + "lucid-cardano": "^0.10.7", + "sha3": "^2.1.4" + }, + "devDependencies": { + "@types/big.js": "^6.1.3", + "@types/jest": "^27.5.2", + "@types/json-bigint": "^1.0.1", + "@typescript-eslint/eslint-plugin": "^5.20.0", + "@typescript-eslint/parser": "^5.20.0", + "esbuild": "^0.14.38", + "eslint": "^8.13.0", + "eslint-plugin-simple-import-sort": "^7.0.0", + "eslint-plugin-unicorn": "^48.0.1", + "eslint-plugin-unused-imports": "^2.0.0", + "jest": "^29.3.1", + "json-bigint": "^1.0.0", + "prettier": "3.0.0", + "rollup": "^2.70.2", + "rollup-plugin-dts": "^4.2.1", + "rollup-plugin-esbuild": "^4.9.1", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.1", + "typescript": "^4.6.3" + } +} diff --git a/plutus.json b/plutus.json index 6050d9b..c9de813 100644 --- a/plutus.json +++ b/plutus.json @@ -6,11 +6,28 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.21-alpha+4b04517" + "version": "v1.0.24-alpha+982eff4" }, "license": "Apache-2.0" }, "validators": [ + { + "title": "always_success.spend", + "datum": { + "title": "_d", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "583c0100003232323232222533300432323253330073370e900118041baa00114a22c60120026012002600c6ea8004526136565734aae7555cf2ba157441", + "hash": "b2501c9e7fd3545b47071b5eb5e657eb121e99c442537defcd503889" + }, { "title": "authen_minting_policy.validate_authen", "redeemer": { @@ -27,8 +44,33 @@ } } ], - "compiledCode": "59083901000032323232323232323222232533300732323232533300b3370e900018050008991919191919299980899b87480080104c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc08cc0980084c8c8c8c94ccc09cc0a80084c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0c8c8c8c8c8c8c8c8c94ccc0e8cdc7803801899b9000500113372000e0066eb8c0f8004c0f8008dd7181e000981a0069bae303a001303a002375c6070002606001626466ebcdd3181280e1ba632323333001333300133330014bd6f7b630014a441024d5300480080a52201034d535000480080a400d20feffffffffffffffff01222253330383370e00290000802099191980080080311299981f00089981f99bb0375200c6e9800d2f5bded8c0264646464a66607e66ebccc03002800930103d8798000133043337606ea4028dd30038028a99981f99b8f00a0021323253330413370e900000089982299bb03752018608c607e00400a200a607e00264a666080a66608600229445280a60103d87a800013374a9000198221ba60014bd70191980080080111299982200089982299bb037520166ea00292f5bded8c0264646464a66608a66ebccc04803c00930103d8798000133049337606ea403cdd40070028a99982299b8f00f0021323253330473370e900000089982599bb037520226098608a00400a200a608a00264a66608c66e1c005200014c103d87a800013374a9000198251ba80014bd7019b8000100e133049337606ea4008dd4000998030030019bad3046003375c60880046090004608c00226608666ec0dd48011ba600133006006003375660800066eb8c0f8008c108008c100004c8c8008c8cc004004008894ccc0f8004526132533303f00114984c8c8c8c8c8c8c94ccc10ccdc3a40000022660140146608e00c00a2c60820026601c0040026eb8c10400cdd7182000198220019821001182080118208009981e19bb037520046ea00052f5bded8c044a66606a66e400080045300103d8798000153330353371e0040022980103d87a800014c103d87b80003232300233001300233001009007300233001005003223371400400246e4c00458dd7181b000981b0011bae3034001302c005375c606400260640046eb8c0c0004c0a000cc0b8004c0b8008c0b0004c090008c8c94ccc09ccdc3a4000002264646464a66605c60620042646493180380118030018b18178009817801181680098128018b1812801119299981399b87480000044c8c8c8c94ccc0b8c0c400852616375c605e002605e0046eb8c0b4004c09400858c094004c09800458c0a0004c8cc004004018894ccc09c00452f5bded8c026464a66604c6464a66605066e1d200200113375e00e605a604c0042940c098004c09c0084cc0a8008cc0100100044cc010010004c0ac008c0a4004c098004c07800458c090004cc0380308cdc39998081bab30243025301d30243025301d0010134881024d530048008dd59811000981100098108009810000980f800980f0011bab301c001301c001301b001301a00130190023758602e002601e012264646464646464646464646464646464a666048604e0022646464a66604e605400426464646464a666052a66605266e3c01407454ccc0a4cdc7801a441024d530013370e00290010a5014a026464a66605c6062004264646464646464646464a66606a66e3c00d220101000013371e00291121ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000014a06eb8c0e4004c0e4008dd7181b800981780119299981899b87480000044c8c8c8c94ccc0e0c0ec00852616375c607200260720046eb8c0dc004c0bc00858c0bc004c94ccc0c0cdc3a40080022606a605c0042a66606066e1d200200113232330010010132253330360011613232323253330373371e00e004200226600c00c00660700066eb8c0d8008c0e8008c0e0004dd7181a98170010b181700098198009819800981900098148008b18178009980c80a119b8733301b3756605e6060605000203c9101024d53004800858dd6981680098168011bae302b001302b002375c60520022c6eb0c0a0004c8cc004004008894ccc09c00452f5c0264666444646600200200644a66605a00220062646605e6e9ccc0bcdd4803198179ba9375c60580026605e6ea0dd69816800a5eb80cc00c00cc0c4008c0bc004dd718130009bab302700133003003302b00230290013013009163301000e23375e604c603e00203c6eacc090004c090004c08c004c088004c084004c080004c07c008dd5980e800980e800980e0011bac301a001301a00130190023758602e002601e01244646600200200644a66602e002297ae0132325333016300500213301a00233004004001133004004001301b002301900122232323253330153370e90010008a400026eb4c068c04c008c04c004c94ccc050cdc3a40040022980103d87a8000132323300100100222533301a00114c103d87a8000132323232533301b3371e014004266e9520003301f375000297ae0133006006003375a60380066eb8c068008c078008c070004dd5980c98090011809000991980080080211299980b8008a6103d87a800013232323253330183371e010004266e9520003301c374c00297ae0133006006003375660320066eb8c05c008c06c008c0640048c8cc004004008894ccc05000452f5bded8c0264646464a66602a66e3d2201000021003133019337606ea4008dd3000998030030019bab3016003375c60280046030004602c00260180126eb8c044004c02400458c03c004c03c008c034004c014008526136563253330073370e90000008a99980518028018a4c2c2a66600e66e1d20020011533300a300500314985858c0140088c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d11", - "hash": "4ad61bf61971298e8aba4e71ce34cac02cddf8030b6fce35c4693a70" + "compiledCode": "590f690100003232323232323232323222253330063370e90001802800899299980399191919299980599b8748000c0280044c8c8c8c8c8c94ccc044cdc3a40040082646464646464646464646464646464a666046604c004264646464a66604e605400426464646464646464646464646464a6660646464646464646464a66607466e3c01c00c4cdc8002800899b90007003375c607c002607c0046eb8c0f0004c0d0034dd7181d000981d0011bae3038001303000b1323375e6e98c094070dd31919199980099998009999800a5eb7bdb1800a5221034d534600480080a52201034d535000480080a400d20feffffffffffffffff01222253330383370e00290000802099191980080080311299981f00089981f99bb0375200c6e9800d2f5bded8c0264646464a66607e66ebccc03002800930103d8798000133043337606ea4028dd30038028a99981f99b8f00a0021323253330413370e900000089982299bb03752018608c607e00400a200a607e00264a666080a66608600229445280a60103d87a800013374a9000198221ba60014bd70191980080080111299982200089982299bb037520166ea00292f5bded8c0264646464a66608a66ebccc04803c00930103d8798000133049337606ea403cdd40070028a99982299b8f00f0021323253330473370e900000089982599bb037520226098608a00400a200a608a00264a66608c66e1c005200014c103d87a800013374a9000198251ba80014bd7019b8000100e133049337606ea4008dd4000998030030019bad3046003375c60880046090004608c00226608666ec0dd48011ba600133006006003375660800066eb8c0f8008c108008c100004c8c8008c8cc004004008894ccc0f8004526132533303f00114984c8c8c8c8c8c8c94ccc10ccdc3a40000022660140146608e00c00a2c60820026601c0040026eb8c10400cdd7182000198220019821001182080118208009981e19bb037520046ea00052f5bded8c044a66606a66e400080045300103d8798000153330353371e0040022980103d87a800014c103d87b80003232300233001300233001009007300233001005003223371400400246e4c00458dd7181b000981b0011bae3034001302c005375c606400260640046eb8c0c0004c0a000cc0b8004c0b8008c0b0004c090008c8c94ccc09ccdc3a4000002264646464a66605c60620042646493180380118030018b18178009817801181680098128018b1812801119299981399b87480000044c8c8c8c94ccc0b8c0c400852616375c605e002605e0046eb8c0b4004c09400858c094004c09800458c0a0004c8cc004004018894ccc09c00452f5bded8c026464a66604c6464a66605066e1d200200113375e00e605a604c0042940c098004c09c0084cc0a8008cc0100100044cc010010004c0ac008c0a4004c098004c07800458c090004cc0380308cdc39998081bab30243025301d30243025301d0010134881034d53460048008dd59811000981100098108009810000980f800980f0011bab301c001301c001301b001301a00130190023758602e002601e0122646464646464646464a66603a6040002264a666036a66603666e1ccc8c004004894ccc08000452000133700900119801001181180099198008008011129998100008a5eb804c8ccc888c8cc00400400c894ccc098004400c4c8cc0a0dd3998141ba90063302837526eb8c094004cc0a0dd41bad30260014bd7019801801981500118140009bae301f00137566040002660060066048004604400290020a99980d99b8733300c00100f4881044d53475300480084cdc3999806000807a441034d534600480085280a501323253330203023002132323232323232323232323232533302d3030002132323232323232323253330333371e01c9101010000153330333371e018910121ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000015333033333033303a0014a09444cdc3999812003813a441044d53475300480085280a5014a06eb0c0dc004c0bc008c8c8c94ccc0cccdc3a40000022646464646464646464646464a666084608a0042646464646464931809803180900398088041808004980780519198008008061129998220008a4c2646600600660900046020608c0022c6086002608600460820026082004607e002607e004607a002607a004607600260760046eb0c0e4004c0c401058c0c400c8c94ccc0cccdc3a4000002264646464a666074607a004264649319299981c99b87480000044c8c94ccc0f8c1040084c92632533303c3370e9000000899192999820982200109924c601c0022c608400260740042a66607866e1d2002001132323232323253330453048002149858dd6982300098230011bad30440013044002375a608400260740042c60740022c607e002606e0062a66607266e1d20020011533303c303700314985858c0dc008c01c00c58c0ec004c0ec008c0e4004c0c400858c0c40048c94ccc0c8cdc3a400000226464a66606e60740042930b1bae30380013030002153330323370e900100089919299981b981d0010a4c2c6eb8c0e0004c0c000858c0c0004c038004c0cc004c0cc008dd59818800981880098140008b18170009980c00991919191919299981719b87480080044cdc79bae3033302c00202214a0605800260620026052002605e002604e0026eb8c0b0004c0b0008dd71815000981100119299981219b87480000044c8c8c8c94ccc0acc0b800852616375c605800260580046eb8c0a8004c08800858c088004c0040088c94ccc08ccdc3a40080022605060420042c6042002604a002604a002604800260360022c60420026601600c466e1cccc034dd598109811180d0008082441034d5346004800858c03000858cc02401c8cdd7980f980c00080b9bab301d001301d001301c00237586034002603400260320046eb0c05c004c03c02488c8cc00400400c894ccc05c00452f5c026464a66602c600a0042660340046600800800226600800800260360046032002444646464a66602a66e1d20020011480004dd6980d1809801180980099299980a19b87480080045300103d87a8000132323300100100222533301a00114c103d87a8000132323232533301b3371e014004266e9520003301f375000297ae0133006006003375a60380066eb8c068008c078008c070004dd5980c98090011809000991980080080211299980b8008a6103d87a800013232323253330183371e010004266e9520003301c374c00297ae0133006006003375660320066eb8c05c008c06c008c0640048c8cc004004008894ccc05000452f5bded8c0264646464a66602a66e3d2201000021003133019337606ea4008dd3000998030030019bab3016003375c60280046030004602c00260180126eb8c044004c02400458c03c004c03c008c034004c014008526136563253330073370e90000008a99980518028018a4c2c2a66600e66e1d20020011533300a300500314985858c0140084c88c8c8c8c94ccc030c8c8c8c94ccc040cdc3a4004601e00226464646464646464646464646464646464a66604266e1d2000302000113232323232323232323232533302c3370e900118158008991919191919191919191919191919191919191919192999821191919299982299b87480000044c8c8cc0040040a0894ccc12c00452809919299982519b8f00200514a2266008008002609e0046eb8c134004dd718251821801099191929998240008a511323300100103622533304d00114a026464a66609866ebcc144c128c144c128c144c148c128008024528899802002000982880118278009919198008008169129998268008a501323232533304d3375e00c00229444cc014014008c134008c144008c13c004cdd2a40006609666e9520023304b375200297ae04bd701bae304b001304300230430013048001304000e13253330433370e66600203402c9101044d534753004800854ccc10ccdc399980080500b245044d534753004800854ccc10ccdd780300c0a99982199baf374c646600200205644a666090002297adef6c6013232323253330493371e91100002100313304d337606ea4008dd3000998030030019bab304a003375c609000460980046094002980101a0001333043304a0024a09445280a5014a02940888c8c8c94ccc120cdc3a40040022900009bad304d304600230460013253330473370e90010008a6103d87a8000132323300100100222533304d00114c103d87a8000132323232533304e3371e014004266e95200033052375000297ae0133006006003375a609e0066eb8c134008c144008c13c004dd598261822801182280099198008008021129998250008a6103d87a8000132323232533304b3371e010004266e9520003304f374c00297ae0133006006003375660980066eb8c128008c138008c1300045281bac3046001303e002303500132533303f3370e900200089822181e8020b181e8019821000981d002982000098200011bab303e001303e002303c0013034001303a01f303900130390013038001303700130360013035001302c02a375c606400260540022c606000260500066eacc0b8004c0b8008c0b0004c090004c0a8004c0a8004c084004c09c004c07c00458c8cc004004038894ccc094004530103d87a80001323253330243375e60526044004026266e952000330280024bd70099802002000981480118138009bac30240013024001302300237566042002604200260400046eacc078004c078004c074008dd6180d800980d800980d0011bac301800130100053016001300e00116301400130140023012001300a00514984d958c00401c8c94ccc030cdc3a40000022646464646464646464646464a666036603c004264646464646493180a0031809803980900418088049808005191980080080611299980e8008a4c2646600600660420046022603e0022c603800260380046034002603400460300026030004602c002602c004602800260280046eb0c048004c02800858c0280048c94ccc02ccdc3a4000002264646464a666024602a004264649319299980899b87480000044c8c94ccc058c0640084c9263253330143370e900000089919299980c980e00109924c601c0022c603400260240042a66602866e1d20020011323232323232533301d3020002149858dd6980f000980f0011bad301c001301c002375a603400260240042c60240022c602e002601e0062a66602266e1d200200115333014300f00314985858c03c008c01c00c58c04c004c04c008c044004c02400858c0240048c94ccc028cdc3a400000226464a66601e60240042930b1bae301000130080021533300a3370e900100089919299980798090010a4c2c6eb8c040004c02000858c020004c02cc0100048c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d12ba301", + "hash": "1c30de5d5350eb8bf1cd10b70c1880f1fd48148278e2d31abb1228c9" + }, + { + "title": "authen_minting_policy.validate_spend_global_setting", + "datum": { + "title": "datum", + "schema": { + "$ref": "#/definitions/amm_dex_v2~1types~1GlobalSetting" + } + }, + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/RedeemerWrapper$Data" + } + }, + "parameters": [ + { + "title": "out_ref", + "schema": { + "$ref": "#/definitions/aiken~1transaction~1OutputReference" + } + } + ], + "compiledCode": "590f690100003232323232323232323222253330063370e90001802800899299980399191919299980599b8748000c0280044c8c8c8c8c8c94ccc044cdc3a40040082646464646464646464646464646464a666046604c004264646464a66604e605400426464646464646464646464646464a6660646464646464646464a66607466e3c01c00c4cdc8002800899b90007003375c607c002607c0046eb8c0f0004c0d0034dd7181d000981d0011bae3038001303000b1323375e6e98c094070dd31919199980099998009999800a5eb7bdb1800a5221034d534600480080a52201034d535000480080a400d20feffffffffffffffff01222253330383370e00290000802099191980080080311299981f00089981f99bb0375200c6e9800d2f5bded8c0264646464a66607e66ebccc03002800930103d8798000133043337606ea4028dd30038028a99981f99b8f00a0021323253330413370e900000089982299bb03752018608c607e00400a200a607e00264a666080a66608600229445280a60103d87a800013374a9000198221ba60014bd70191980080080111299982200089982299bb037520166ea00292f5bded8c0264646464a66608a66ebccc04803c00930103d8798000133049337606ea403cdd40070028a99982299b8f00f0021323253330473370e900000089982599bb037520226098608a00400a200a608a00264a66608c66e1c005200014c103d87a800013374a9000198251ba80014bd7019b8000100e133049337606ea4008dd4000998030030019bad3046003375c60880046090004608c00226608666ec0dd48011ba600133006006003375660800066eb8c0f8008c108008c100004c8c8008c8cc004004008894ccc0f8004526132533303f00114984c8c8c8c8c8c8c94ccc10ccdc3a40000022660140146608e00c00a2c60820026601c0040026eb8c10400cdd7182000198220019821001182080118208009981e19bb037520046ea00052f5bded8c044a66606a66e400080045300103d8798000153330353371e0040022980103d87a800014c103d87b80003232300233001300233001009007300233001005003223371400400246e4c00458dd7181b000981b0011bae3034001302c005375c606400260640046eb8c0c0004c0a000cc0b8004c0b8008c0b0004c090008c8c94ccc09ccdc3a4000002264646464a66605c60620042646493180380118030018b18178009817801181680098128018b1812801119299981399b87480000044c8c8c8c94ccc0b8c0c400852616375c605e002605e0046eb8c0b4004c09400858c094004c09800458c0a0004c8cc004004018894ccc09c00452f5bded8c026464a66604c6464a66605066e1d200200113375e00e605a604c0042940c098004c09c0084cc0a8008cc0100100044cc010010004c0ac008c0a4004c098004c07800458c090004cc0380308cdc39998081bab30243025301d30243025301d0010134881034d53460048008dd59811000981100098108009810000980f800980f0011bab301c001301c001301b001301a00130190023758602e002601e0122646464646464646464a66603a6040002264a666036a66603666e1ccc8c004004894ccc08000452000133700900119801001181180099198008008011129998100008a5eb804c8ccc888c8cc00400400c894ccc098004400c4c8cc0a0dd3998141ba90063302837526eb8c094004cc0a0dd41bad30260014bd7019801801981500118140009bae301f00137566040002660060066048004604400290020a99980d99b8733300c00100f4881044d53475300480084cdc3999806000807a441034d534600480085280a501323253330203023002132323232323232323232323232533302d3030002132323232323232323253330333371e01c9101010000153330333371e018910121ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000015333033333033303a0014a09444cdc3999812003813a441044d53475300480085280a5014a06eb0c0dc004c0bc008c8c8c94ccc0cccdc3a40000022646464646464646464646464a666084608a0042646464646464931809803180900398088041808004980780519198008008061129998220008a4c2646600600660900046020608c0022c6086002608600460820026082004607e002607e004607a002607a004607600260760046eb0c0e4004c0c401058c0c400c8c94ccc0cccdc3a4000002264646464a666074607a004264649319299981c99b87480000044c8c94ccc0f8c1040084c92632533303c3370e9000000899192999820982200109924c601c0022c608400260740042a66607866e1d2002001132323232323253330453048002149858dd6982300098230011bad30440013044002375a608400260740042c60740022c607e002606e0062a66607266e1d20020011533303c303700314985858c0dc008c01c00c58c0ec004c0ec008c0e4004c0c400858c0c40048c94ccc0c8cdc3a400000226464a66606e60740042930b1bae30380013030002153330323370e900100089919299981b981d0010a4c2c6eb8c0e0004c0c000858c0c0004c038004c0cc004c0cc008dd59818800981880098140008b18170009980c00991919191919299981719b87480080044cdc79bae3033302c00202214a0605800260620026052002605e002604e0026eb8c0b0004c0b0008dd71815000981100119299981219b87480000044c8c8c8c94ccc0acc0b800852616375c605800260580046eb8c0a8004c08800858c088004c0040088c94ccc08ccdc3a40080022605060420042c6042002604a002604a002604800260360022c60420026601600c466e1cccc034dd598109811180d0008082441034d5346004800858c03000858cc02401c8cdd7980f980c00080b9bab301d001301d001301c00237586034002603400260320046eb0c05c004c03c02488c8cc00400400c894ccc05c00452f5c026464a66602c600a0042660340046600800800226600800800260360046032002444646464a66602a66e1d20020011480004dd6980d1809801180980099299980a19b87480080045300103d87a8000132323300100100222533301a00114c103d87a8000132323232533301b3371e014004266e9520003301f375000297ae0133006006003375a60380066eb8c068008c078008c070004dd5980c98090011809000991980080080211299980b8008a6103d87a800013232323253330183371e010004266e9520003301c374c00297ae0133006006003375660320066eb8c05c008c06c008c0640048c8cc004004008894ccc05000452f5bded8c0264646464a66602a66e3d2201000021003133019337606ea4008dd3000998030030019bab3016003375c60280046030004602c00260180126eb8c044004c02400458c03c004c03c008c034004c014008526136563253330073370e90000008a99980518028018a4c2c2a66600e66e1d20020011533300a300500314985858c0140084c88c8c8c8c94ccc030c8c8c8c94ccc040cdc3a4004601e00226464646464646464646464646464646464a66604266e1d2000302000113232323232323232323232533302c3370e900118158008991919191919191919191919191919191919191919192999821191919299982299b87480000044c8c8cc0040040a0894ccc12c00452809919299982519b8f00200514a2266008008002609e0046eb8c134004dd718251821801099191929998240008a511323300100103622533304d00114a026464a66609866ebcc144c128c144c128c144c148c128008024528899802002000982880118278009919198008008169129998268008a501323232533304d3375e00c00229444cc014014008c134008c144008c13c004cdd2a40006609666e9520023304b375200297ae04bd701bae304b001304300230430013048001304000e13253330433370e66600203402c9101044d534753004800854ccc10ccdc399980080500b245044d534753004800854ccc10ccdd780300c0a99982199baf374c646600200205644a666090002297adef6c6013232323253330493371e91100002100313304d337606ea4008dd3000998030030019bab304a003375c609000460980046094002980101a0001333043304a0024a09445280a5014a02940888c8c8c94ccc120cdc3a40040022900009bad304d304600230460013253330473370e90010008a6103d87a8000132323300100100222533304d00114c103d87a8000132323232533304e3371e014004266e95200033052375000297ae0133006006003375a609e0066eb8c134008c144008c13c004dd598261822801182280099198008008021129998250008a6103d87a8000132323232533304b3371e010004266e9520003304f374c00297ae0133006006003375660980066eb8c128008c138008c1300045281bac3046001303e002303500132533303f3370e900200089822181e8020b181e8019821000981d002982000098200011bab303e001303e002303c0013034001303a01f303900130390013038001303700130360013035001302c02a375c606400260540022c606000260500066eacc0b8004c0b8008c0b0004c090004c0a8004c0a8004c084004c09c004c07c00458c8cc004004038894ccc094004530103d87a80001323253330243375e60526044004026266e952000330280024bd70099802002000981480118138009bac30240013024001302300237566042002604200260400046eacc078004c078004c074008dd6180d800980d800980d0011bac301800130100053016001300e00116301400130140023012001300a00514984d958c00401c8c94ccc030cdc3a40000022646464646464646464646464a666036603c004264646464646493180a0031809803980900418088049808005191980080080611299980e8008a4c2646600600660420046022603e0022c603800260380046034002603400460300026030004602c002602c004602800260280046eb0c048004c02800858c0280048c94ccc02ccdc3a4000002264646464a666024602a004264649319299980899b87480000044c8c94ccc058c0640084c9263253330143370e900000089919299980c980e00109924c601c0022c603400260240042a66602866e1d20020011323232323232533301d3020002149858dd6980f000980f0011bad301c001301c002375a603400260240042c60240022c602e002601e0062a66602266e1d200200115333014300f00314985858c03c008c01c00c58c04c004c04c008c044004c02400858c0240048c94ccc028cdc3a400000226464a66601e60240042930b1bae301000130080021533300a3370e900100089919299980798090010a4c2c6eb8c040004c02000858c020004c02cc0100048c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d12ba301", + "hash": "1c30de5d5350eb8bf1cd10b70c1880f1fd48148278e2d31abb1228c9" }, { "title": "factory_validator.validate_factory", @@ -56,10 +98,27 @@ "schema": { "$ref": "#/definitions/ByteArray" } + }, + { + "title": "pool_batching_stake_credential", + "schema": { + "$ref": "#/definitions/aiken~1transaction~1credential~1Referenced$aiken~1transaction~1credential~1Credential" + } } ], - "compiledCode": "590e9d01000032323232323232323223223222232323232533300e3232323253330123370e90011808800899191919191919191919191919191919191919191919191919191919191919191919191919299981b9919191919191919299981f99b8f00700313372000a002266e4001c00cdd7182180098218011bae30410013039011375c607e002607e0046eb8c0f4004c0d403c4c8c8c94ccc0e8cdc3a40006072002264646464646464646464646464a666094609a00226464a66609266e1cccc00401c1152201024d5300480084c8c8c8c94ccc140c14c0084c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc1894ccc188cdc80038028a99983119b90003001153330623371e00e06c2a6660c466e3c0040d054ccc188cdc7815802899b8f02b00314a029405280a5014a026464a6660ce60d400426464646464646464646464646464646464646464646464a6660f666e1d2002307a00113232323232323232325333084013375e0300b82a6661080266ebc05816854ccc21004cdc380a0030a9998420099b8701200815333084013370e02000e2a6661080266e21200000815333084013371090000038a9998420099b884800001854ccc2100400454ccc21004cdd79ba632330010010692253330890100114bd6f7b63009919191929998450099b8f48900002100313308e01337606ea4008dd3000998030030019bab308b01003375c611202004611a020046116020026e98cccc00ccccc00ccccc00d2f5bded8c0100029101024d530048008200052201034d535000480082000413520feffffffffffffffff0113375e6e98008dd300f0a5014a029405280a5014a029405280a5014a0a6661060264646600200297adef6c6110105000103192710008101030001031903e800810101000102186400112999844808008a50132325333088013375e6e98cc230040092f5bded8c06e98cc230040152f5bded8c029444cc010010004c23404008c22c04004cdd81ba800d3750016294454ccc20c04c8c8c8c8c94ccc22004cdc3a400000226464646464646464646464a6661260266e1d200000113232330010010722253330990100114a026464a6661300266e3c008014528899802002000984e808011bae309b01001375c61300261220200426464660020020ec44a6661320200229404c8c8c94ccc26404cdd78030008a51133005005002309901002309d01002309b010013374a90001984b8080125eb80c24404004c25804004c23804004c25004004c23004004c24804004c24804004c22404008c8c8c8c8c8c8c8c8c94ccc25804c264040084c8c8c8c8c8c8c8c8c8c8c94ccc27804cdc3a4004613a0200626464a6661400266e1d2002309f010031323253330a20153330a2013370e01c90010a9998510099b8900100d13371201a66e0000d2080c0dbadc30414a029404cdd800a1ba800116375a614c02002613c020062c6eb4c29004004c2700400c58c28804004c2680400cc28004004c2600400cc27804004c27804008c27004004c250041d4c8c8cc00400400888c94ccc264054ccc26404cdc4a40c0002266e24005207214a02a6661320266e1c00920001337020029030099b80337046600600666e04009200248050cdc0800a40c02c66e38014004cdc09b8d00248008dd6984b008011bae309401001163097010013300c0014891cf8c20eb8b2e773e21cf41ab6354cf09bd255ebed0bd8847c655e67b4003756612a02002612a02004612602002611602002612202002612202002611002002611c02002610c020042940c21804004cc1381bc8cdc4240006006660046eacc23004c23404c21404c23004c23404c2140400522011cf8c20eb8b2e773e21cf41ab6354cf09bd255ebed0bd8847c655e67b4002232325333089013370e90010008a5eb7bdb1804dd5984700984380801184380800998200010009800800912999844008008a4000266e01200233002002308b0100115333083013371090000058991929998428080108008a503371266e08031200a3370401c90504e0099b893370401a900a19b8200b480085852819998009999800999980099998009999800a5eb7bdb18122100488100482026fb8081481400181381300141f812c00c1f9221034d5350004800888894ccc21404cdc3800a40002008264646600200200c44a666116020022661180266ec0dd48031ba60034bd6f7b63009919191929998460099baf3300c00a0024c0103d879800013309001337606ea4028dd30038028a9998460099b8f00a00213232533308e013370e90000008998490099bb0375201861260261180200400a200a61180200264a66611a02a6661200200229445280a60103d87a800013374a900019848809ba60014bd701919800800801112999848808008998490099bb037520166ea00292f5bded8c0264646464a6661240266ebccc04803c00930103d879800013309601337606ea403cdd40070028a9998490099b8f00f002132325333094013370e900000089984c0099bb0375202261320261240200400a200a61240200264a6661260266e1c005200014c103d87a800013374a90001984b809ba80014bd7019b8000100e13309601337606ea4008dd4000998030030019bad309301003375c612202004612a020046126020022661200266ec0dd48011ba6001330060060033756611a020066eb8c22c04008c23c04008c23404004c8c8008c8cc004004008894ccc22c04004526132533308c0100114984c8c8c8c8c8c8c94ccc24004cdc3a4000002266014014661280200c00a2c611c020026601c0040026eb8c2380400cdd7184680801984880801984780801184700801184700800998448099bb037520046ea00052f5bded8c044a6661040266e400080045300103d879800015333082013371e0040022980103d87a800014c103d87b800033702907f7fffffffffffffff8099b8100148050c8c94ccc20004cdc419b8200100100213370000290010800a99983f99b88001480005854ccc1fccdc3800a4000290000a99983f99b8700148008520021533307f3370e00290020a400426464666002002006004444a6661060266e200040084ccc00c00c004cdc199b803370600a0020029002080119b803370600290022400466e08008004ccc0d405c12411d4ccc1f14ccc1f0cdc78262450013371e0949110014a0266e0400520809bee02100133303301504b04916307f001307f002375a60fa00260fa0046eb4c1ec004c1ec008dd6983c800983c8011bad30770013077002375a60ea00260ea00460e600260e600460e200260d200464a6660d666e1d2000001132323232323232323232323232323232533307e3081010021323232498c94ccc1f8cdc3a400000226464a66610602610c0200426493191bad308301002375a6102020022c6466ec0c21404004c21404c21804004dd6184200800983e0020a99983f19b874800800454ccc20404c1f00105261616307c003307000e306f00f16307f001307f002375a60fa00260fa0046eb4c1ec004c1ec008dd6983c800983c8011bad30770013077002375a60ea00260ea00460e600260e600460e200260d20042c60d20026602808600260da00260da0046eacc1ac004c1ac004c18800458c1a0004cc0741248c8c8c8c8c8c8c94ccc1a8cdc3a400400226464a6660d866e3c1980044cdc3999812003034245034d535000480085281bae3070001306800214a060d000260da00260ca0066eacc1ac004c1ac008c1a4004c18400458dd7183300098330011bae3064001305c006375c60c400260c40046eb8c180004c160010c13c004cc00c0c8010c134004cc0040c001888c94ccc160cdc3a4008002260ba60ac0042a6660b066e1d2002001132323300100100522533305e00116132323232533305f3371e00e004200226600c00c00660c00066eb8c178008c188008c180004dd7182e982b0010b182b000982c800982c800982c0009827802982a800982a800982a00098258018b182880098288011827800998020181191919191919299982819baf00c00113370e666010006098911024d530048008528182a00098260019bab305200130520023050001304800116222323232533304e3370e90010008a400026eb4c14cc130008c130004c94ccc134cdc3a4004002298103d87a8000132323300100100222533305300114c103d87a800013232323253330543371e014004266e95200033058375000297ae0133006006003375a60aa0066eb8c14c008c15c008c154004dd5982918258011825800998020018011119198008008019129998270008a60103d87a8000132323232533304f3371e00e004266e95200033053374c00297ae0133006006003375660a00066eb8c138008c148008c14000458cc0040c48cdd780198261822982618229826182698228009119198008008019129998260008a5eb804c8c94ccc12cc0140084cc13c008cc0100100044cc010010004c140008c138004c124004c10400cdd5982380098238011822800981e80098218009821800981d0009820000981c0008b19800812119baf303f303800102722323300100100322533303f00114c0103d87a800013232533303e300500213374a90001982100125eb804cc010010004c10c008c104004c8c8c008cc004c008cc00402401cc008cc00401400c88cdc500100091b9300116375c607600260760046eb8c0e4004c0c4024dd7181b800981b8011bae3035001302d007375c606600260660046eb8c0c4004c0a4090c0bc004c0bc008c0b4004c09407cdd59815800981580098150011bac302800130280023026001302600237566048002604800260460046eacc084004c084004c080008dd6180f000980f0011bac301c001301c00237586034002602400a603000260200022c602c002602c0046028002601800a29309b2b19299980719b87480000044c8c8c8c94ccc054c0600084c8c9263007002300600316301600130160023014001300c00616300c005232533300e3370e9000000899191919299980a980c0010a4c2c6eb8c058004c058008dd7180a00098060010b18060009800802119299980619b87480000044c8c8c8c94ccc04cc05800852616375c602800260280046eb8c048004c02800858c028004dd70009bae001230053754002460066ea80055cd2ab9d5573caae7d5d02ba157441", - "hash": "2bed7ac783643262193dec2113260424d2e837cc38b4444f56783e8d" + "compiledCode": "590b7f010000323232323232323232232232222232323232533300f3232323253330133370e900118088008991919191919191919191919191919191919191919191919191929998169919191919191919299981a99b8f00700313372000a002266e4001c00cdd7181c800981c8011bae30370013030011375c606a002606a0046eb8c0cc004c0b003c4c8c94ccc0bccdc3a4000605a002264646464646464646464646464a66607e6084002264a66607a66e1cccc0040180e5221034d534600480084c8c8c8c94ccc110c11c0084c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc1594ccc158cdc80038028a99982b19b90003001153330563371e00e0682a6660ac66e3c0040c854ccc158cdc7814802899b8f02900314a029405280a5014a026464a6660b660bc00426464646464646464646464646464646464646464646464646464646464646464646464a6660f666ebc06c1d054ccc1eccdd780c82e8a99983d99baf01705b1533307b3370e02a00a2a6660f666e1c04c01c54ccc1eccdc38088030a99983d99b884800001c54ccc1eccdc42400000c2a6660f666e2120140051533307b3370e01e01a2a6660f6a6660f666e2403d20a01f13371290050078a501533307b533307b00914a026660f6941282511533307b3375e01698103d87a80001533307b3375e6e98c8cc004004180894ccc2000400452f5bded8c0264646464a6661020266e3d220100002100313308501337606ea4008dd3000998030030019bab308201003375c6100020046108020046104020026e98cccc008cccc008cccc0092f5bded8c00ee9101034d534600480081dd2201034d535000480081dc13920feffffffffffffffff0113375e6e98004dd30108a5014a029405280a5014a029405280a5014a029405280a5014a06666002666600266660026666002666600297adef6c6048810048810048302a294101501480181401380141d813400c1d9221034d5350004800888894ccc1f4cdc3800a40002008264646600200200c44a666106020022661080266ec0dd48031ba60034bd6f7b63009919191929998420099baf3300c00a0024c0103d879800013308801337606ea4028dd30038028a9998420099b8f00a002132325333086013370e90000008998450099bb03752018611602610a0200400a200a61060200264a66610a02a6661100200229445280a60103d87a800013374a900019844809ba60014bd701919800800801112999844808008998450099bb037520166ea00292f5bded8c0264646464a6661140266ebccc04803c00930103d879800013308e01337606ea403cdd40070028a9998450099b8f00f00213232533308c013370e90000008998480099bb0375202261220261160200400a200a61120200264a6661160266e1c005200014c103d87a800013374a900019847809ba80014bd7019b8000100e13308e01337606ea4008dd4000998030030019bad308b01003375c611202004611a020046116020022661100266ec0dd48011ba6001330060060033756610a020066eb8c20c04008c21c04008c21404004c8c8008c8cc004004008894ccc20c0400452613253330840100114984c8c8c8c8c8c8c94ccc22004cdc3a4000002266014014661180200c00a2c610a020026601c0040026eb8c2180400cdd7184280801984480801984380801184300801184300800998408099bb037520046ea00052f5bded8c044a6660f466e400080045300103d87980001533307a3371e0040022980103d87a800014c103d87b800033702907f7fffffffffffffff8099b8100148050c8c94ccc1e0cdc419b8200100100213370000290010800a99983b99b88001480005854ccc1dccdc3800a4000290000a99983b99b870014800852002153330773370e00290020a400426464666002002006004444a6660f666e200040084ccc00c00c004cdc199b803370600a0020029002080119b803370600290022400466e08008004ccc0e406c12c1254ccc1d14ccc1d0cdc78272450013371e0989110014a0266e0400520c0a8a504100133303701904d04b3370e900118399baa3077001307700230750013075002375a60e600260e60046eb4c1c4004c1c4008dd6983780098378011bad306d001306d002375a60d600260d600460d200260d200460ce00260ce00460ca00260bc00464a6660be66e1d20000011323232323232323232323232323232323232323253330763079002132323232498c94ccc1dccdc3a400000226464a6660f860fe0042930b1bad307d0013076007153330773370e90010008a99983d183b0038a4c2c2c60e800c60d002260ce02464a6660e866e1d2000001132325333079307c002132498c94ccc1dccdc3a400000226464a6660f860fe0042930b1bae307d0013076002153330773370e900100089919299983e183f8010a4c2c6eb8c1f4004c1d800858c1d000458c1e8004c1cc05054ccc1d0cdc3a40040022646464646464a6660fa6100020042930b1bad307e001307e002375a60f800260f80046eb4c1e8004c1cc05058c1c404c58cdc3a400460e66ea8c1dc004c1dc008c1d4004c1d4008dd6983980098398011bad30710013071002375a60de00260de0046eb4c1b4004c1b4008dd69835800983580118348009834801183380098338011832800982f0010b182e000980a000983080098308011bab305f001305f001305700116305c0013301c03d232323232323232533305e3370e900100089919299983019b8f05a00113370e66604800c0b8911034d535000480085281bae3064001305d00214a060b600260c200260b40066eacc17c004c17c008c174004c15800458dd7182d000982d0011bae30580013051006375c60ac00260ac0046eb8c150004c134010c108004c00c010c100004c0040188c94ccc12ccdc3a4008002260a060940042c6090002609a002609a0026098002608800a60920026092002609000260800062c608a002608a0046086002660060484646464646464a66608866ebc02c0044cdc39998040018202441034d53460048008528182400098208019bab304600130460023044001303d0011622232323253330423370e90010008a400026eb4c11cc104008c0fc004c94ccc104cdc3a4004002298103d87a8000132323300100100222533304700114c103d87a800013232323253330483371e014004266e9520003304c375000297ae0133006006003375a60920066eb8c11c008c12c008c124004dd598231820001181f00099198008008021129998220008a6103d87a800013232323253330453371e010004266e95200033049374c00297ae01330060060033756608c0066eb8c110008c120008c11800458cc0040948cdd78019820981d9820981d98209821181d8009119198008008019129998208008a5eb804c8c94ccc100c0140084cc110008cc0100100044cc010010004c114008c10c004c0f8004c0dc00cdd5981e000981e001181d0009819800981c000981c0009818000981a80098170008b191980080080c9129998198008a60103d87a80001323253330323375e606e606200403c266e952000330360024bd70099802002000981b801181a80099191801198009801198008048039801198008028019119b8a002001237260022c6eb8c0c4004c0c4008dd7181780098140049bae302d001302d002375c6056002604800e6eb8c0a4004c0a4008dd71813800981000c981280098128011811800980e00a1bab3021001302100130200023758603c002603c002603a0046eb0c06c004c050014c064004c04800458c05c004c05c008c054004c0380145261365632533300f3370e9000000899191919299980b180c8010991924c600e004600c0062c602e002602e004602a002601c00c2c601800a464a66601e66e1d200000113232323253330163019002149858dd7180b800980b8011bae3015001300e00216300c0013001004232533300d3370e9000000899191919299980a180b8010a4c2c6eb8c054004c054008dd7180980098060010b18050009bae001375c002460086ea80048c010dd5000ab9a5573aaae7955cfaba05742ae881", + "hash": "9049adb969fecb912e9ae30c567821c53d4747be84a98c9188514733" + }, + { + "title": "order_validator.validate_expired_order_cancel", + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "590b230100003232323232323232322253330053232323253330093370e900218040008991919191919191919191919191919191919191919191919191919980080080580b1111919191919191919191919191919191919191919191919191919191919191919299982299b8748000c1100044c8c8c8c94ccc1254ccc124cdc40010180a99982499baf00e017153330493371266e04c0a406c004c0a405454ccc124cdd79ba63028015374c6050036266ebc030c94ccc128cdc3a4000002298103d87980001533304a3370e9001000899ba548008cc138c13cc1200512f5c0266e9520043304e37526e50dd99827982400a25eb80c12004c5280a5014a0294054ccc124cdd79ba70234c0101800014a2266604e04e0460422c6eb4c128008dd698240009919bb0304c001304c304d0013758609600260860022c609200260920026090002608e002608c002608a00260880046084002608400460800026080002606e00464a66607266e1d20000011323232323232323232323232323232323232533304e305100213232323232323232498c94ccc14ccdc3a400000226464a6660b060b600426493191bad3058002375a60ac0022c6466ec0c168004c168c16c004dd6182c80098288048a99982999b874800800454ccc158c144024526161630510083253330523370e900000089919191919191919299982e983000109924c607a00a2c66e1d2002305a375460bc00260bc0046eb4c170004c170008c168004c168008cdc3a400460a86ea8c160004c14003054ccc148cdc3a40040022646464646464a6660b660bc00426493181d8018b1bad305c001305c002305a001305a0023370e9001182a1baa3058001305000c153330523370e900200089919191919191919299982e983000109924c607a00a2c6eb4c178004c178008dd6982e000982e001182d000982d00119b8748008c150dd5182c00098280060a99982919b87480180044c8c8c8c8c8c8c8c94ccc174c1800084c926303d005163370e9001182d1baa305e001305e002375a60b800260b800460b400260b400466e1d20023054375460b000260a00182a6660a466e1d20080011323232323232533305b305e002132498c94ccc164cdc3a4000002264646464a6660c060c60042930b1bad30610013061002375a60be00260ae00c2a6660b266e1d200200113232323253330603063002149858dd6983080098308011bad305f0013057006163057005163370e9001182c1baa305c001305c002375a60b400260b400460b000260a00182a6660a466e1d200a00113232323232323232533305d3060002132498c0f801c58cdc3a400460b46ea8c178004c178008dd6982e000982e0011bad305a001305a0023058001305000c153330523370e900600089919191919191919299982e983000109924c607c00a2c66e1d2002305a375460bc00260bc0046eb4c170004c170008c168004c168008cdc3a400460a86ea8c160004c14003054ccc148cdc3a401c00226464646464646464646464646464a6660c660cc0042930b1bad30640013064002375a60c400260c40046eb4c180004c180008dd6982f000982f0011bad305c001305c002375a60b400260b400466e1d20023054375460b000260a00182a6660a466e1d2010001132323232323232323232533305f3062002132498c10002458cdc3a400460b86ea8c180004c180008dd6982f000982f0011bad305c001305c002375a60b400260b400460b000260a00182a6660a466e1d20120011323232323232533305b305e00213232498c0f0010c8cc004004018894ccc1740045261323300300330610023232533305c3370e90000008991919192999831983300109924c608a0062c66e1d20023060375460c800260c800460c400260b40042c60b400260be0022c6eb4c170004c170008c168004c168008dd6182c00098280060a99982919b874805000454ccc154c1400305261616305000b303500c303100d302f00e302f00f302d01032533304c3370e9000000899192999828982a0010a4c2c6eb8c148004c12804854ccc130cdc3a400400226464a6660a260a80042930b1bae3052001304a0121533304c3370e9002000899192999828982a0010a4c2c6eb8c148004c12804854ccc130cdc3a400c00226464a6660a260a80042930b1bae3052001304a01216304a01116304f001304f002375a609a002609a0046096002609600460920026092004608e002608e004608a002608a0046086002608600460820026082004607e002606e0042c606e00264a66607066e1d20040011303d3036008153330383370e9001000899191980080081191299981f0008b099191919299981f99b8f00700210011330060060033040003375c607c004608400460800026eb8c0f4c0d802058c0d801cc0ec004c0ec008dd5981c800981c801181b8009817805181a800981a8011bab30330013033001302a001303000130300013027004302e004302c003302c003302a0022323300100100222533302700114bd6f7b630099191919299981419b8f488100002100313302c337606ea4008dd3000998030030019bab3029003375c604e004605600460520024646464a66604866e1d20020011480004dd698149811001181100099299981199b8748008004530103d87a8000132323300100100222533302900114c103d87a8000132323232533302a3371e9110000213374a9000198171ba80014bd700998030030019bad302b003375c6052004605a00460560026eacc0a0c084008c084004c8cc004004008894ccc0980045300103d87a800013232323253330273371e9110000213374a9000198159ba60014bd700998030030019bab3028003375c604c00460540046050002464a66604266e1d20000011323232325333028302b00213232498c94ccc09ccdc3a400000226464a666058605e0042649319299981519b87480000044c8c94ccc0bcc0c80084c926301200116303000130280021533302a3370e900100089919191919192999819981b0010a4c2c6eb4c0d0004c0d0008dd6981900098190011bad3030001302800216302800116302d0013025003153330273370e90010008a99981518128018a4c2c2c604a00460160062c60520026052004604e002603e0042c603e002464a66604066e1d200000115333023301e00214985854ccc080cdc3a400400226464a66604a60500042930b1bae3026001301e002153330203370e900200089919299981298140010a4c2c6eb8c098004c07800858c0780048c94ccc07ccdc3a400000226464a666048604e0042930b1bad3025001301d0021533301f3370e900100089919299981218138010a4c2c6eb4c094004c07400858c0740048c94ccc078cdc3a400000226464a666046604c0042930b1bad3024001301c0021533301e3370e900100089919299981198130010a4c2c6eb4c090004c07000858c0700048c94ccc074cdc3a4000002264646464a666048604e0042930b1bae30250013025002375c604600260360042c6036002464a66603866e1d20000011323253330213024002149858dd71811000980d0010a99980e19b87480080044c8c94ccc084c09000852616375c604400260340042c603400264646464a66603a66e1d2002301c0011375a604460360022c60420026032002603e002602e00c646600200201e44a66603a002297ae013232533301c323232323232323253330243370e90010008a5114a06044002604e002603e002604a002603a002604600260460026034004266040004660080080022660080080026042004603e0026eacc070004c070004c06c004c068008c060004c060004c05c004c058004c054004c050008dd61809000980900098088011bac300f001300700316300d001300d002300b001300300114984d9588c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d101", + "hash": "c8b0cc61374d409ff9c8512317003e7196a3e4d48553398c656cc124" }, { "title": "order_validator.validate_order", @@ -77,46 +136,52 @@ }, "parameters": [ { - "title": "stake_credential", + "title": "pool_batching_credential", + "schema": { + "$ref": "#/definitions/aiken~1transaction~1credential~1Referenced$aiken~1transaction~1credential~1Credential" + } + }, + { + "title": "expired_order_cancel_credential", "schema": { "$ref": "#/definitions/aiken~1transaction~1credential~1Referenced$aiken~1transaction~1credential~1Credential" } } ], - "compiledCode": "59079f0100003232323232323232322222533300732323232533300b3370e90011805000899191919299980799b87480000084cc004dd5980a180a980a980a980a980a980a98068038060a99980799b87480080084c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc080cdc3a400000226464646600200201444a66604e00229404c8c94ccc098cdc78010028a51133004004001302b002375c60520026eb8c098004c0780084cdc424000664600200244a66604a00229000099b8048008cc008008c0a0004c8cc004004044894ccc09400452f5c026464a66604866ebcc0a4c088c0a4c088c0a4c0a8c0880080184cc0a0008cc0100100044cc010010004c0a4008c09c004c078004c08c004c06c004c084004c06405cc8c8c8c8c94ccc07ccdc3a4000002264646464646464646464646464646464a666064606a0042646464646464649319299981b19b87480000044c8c94ccc0ecc0f80084c92632375a60760046eb4c0e400458c8cdd8181e800981e981f0009bac303c0013034008153330363370e90010008a99981c981a0040a4c2c2c606800e64a66606a66e1d20000011323232323232323253330403043002149858cdc3a4004607a6ea8c104004c104008dd6981f800981f8011bad303d001303d0023370e9001181b9baa303b001303300b153330353370e900100089919191919191919299982018218010a4c2c66e1d2002303d3754608200260820046eb4c0fc004c0fc008dd6981e800981e80119b8748008c0dcdd5181d80098198058a99981a99b87480100044c8c8c8c8c8c8c8c8c8c94ccc108c114008526163370e9001181f9baa30430013043002375a608200260820046eb4c0fc004c0fc008dd6981e800981e80119b8748008c0dcdd5181d80098198058a99981a99b87480180044c8c8c8c8c8c8c8c94ccc100c10c008526163370e9001181e9baa30410013041002375a607e002607e0046eb4c0f4004c0f4008cdc3a4004606e6ea8c0ec004c0cc02c54ccc0d4cdc3a401000226464646464646464a66608060860042930b19b8748008c0f4dd5182080098208011bad303f001303f002375a607a002607a0046eb4c0ec004c0cc02c54ccc0d4cdc3a401400226464646464646464a66608060860042930b19b8748008c0f4dd5182080098208011bad303f001303f002375a607a002607a0046eb4c0ec004c0cc02c54ccc0d4cdc3a401800226464646464646464a66608060860042930b19b8748008c0f4dd5182080098208011bad303f001303f002375a607a002607a00466e1d200230373754607600260660162a66606a66e1d200e0011323232323232323232323232323253330463049002149858dd6982380098238011bad30450013045002375a608600260860046eb4c104004c104008dd6981f800981f8011bad303d001303d0023370e9001181b9baa303b001303300b153330353370e9008000899191919191919191919299982118228010a4c2c66e1d2002303f3754608600260860046eb4c104004c104008dd6981f800981f8011bad303d001303d002375a607600260660162a66606a66e1d20120011323232323232533303e3041002132498c8cc004004018894ccc1000045261323300300330440023232533303f3370e90000008991919192999823182480109924c60500062c66e1d200230433754608e002608e004608a002607a0042c607a00260840022c6eb4c0fc004c0fc008dd6981e800981e8011bac303b001303300b16303300a301800b301500c301500d301300e301300f1630330013033002375a60620026062004605e002605e004605a002605a0046056002605600460520026052004604e002604e004604a002603a0362c603a034464a66603e66e1d20000011323253330243027002149858dd71812800980e8010a99980f99b874800800454ccc088c0740085261616301d001232533301e3370e9000000899191919299981298140010991924c64a66604866e1d2000001132325333029302c002132498c94ccc09ccdc3a400000226464a666058605e0042649318078008b181680098128010a99981399b87480080044c8c8c8c8c8c94ccc0c0c0cc00852616375a606200260620046eb4c0bc004c0bc008dd6981680098128010b18128008b181500098110018a99981219b874800800454ccc09cc08800c52616163022002300800316302600130260023024001301c00216301c001232533301d3370e9000000899191919299981218138010a4c2c6eb8c094004c094008dd71811800980d8010b180d800919299980e19b87480000044c8c94ccc084c09000852616375c604400260340042a66603866e1d20020011323253330213024002149858dd71811000980d0010b180d0009bac301e001301e001301d001301c001301b001301a0013019001301800130170023758602a002601a00e2660026eacc050c054c054c054c054c054c054c03401c03088c8cc00400400c894ccc0540045280991919299980a99baf00600114a226600a00a004602a0046032004602e002601801064a66601a66e1d200000115333010300b00814985854ccc034cdc3a40040022a66602060160102930b0a99980699b874801000454ccc040c02c0205261616300b007300900116300f001300f002300d001300500114984d9588c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d11", - "hash": "2109ade2f74be47e1d94617a37967dd924098ce763826935e4bd248d" + "compiledCode": "590a240100003232323232323232323222222533300832323232533300c3370e900118058008991919299980799b87480000084cc004dd5980a180a980a980a980a980a980a98068030060a99980799b87480080084c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc080cdc3a400000226464646600200201044a66604e00229404c8c94ccc098cdc78010028a51133004004001302b002375c60520026eb8c098004c07800854ccc080cdc3a400400226464646660466054646600200202844a666050002297ae01323253330273375e6058604a6058604a6058605a604a00400a26605600466008008002266008008002605800460540029412899ba548008cc098dd4800a5eb80dd71813000980f0010a99981019b87480100044cc048020cdd2a40006604866e952002330243025301e0024bd7025eb804c8c8ccc088cdc3991bad30253028323253330253370e90010008a5eb7bdb1804dd598151811801181180099198008008011129998140008a60103d87a800013232323253330293371e010004266e9520003302d374c00297ae0133006006003375660540066eb8c0a0008c0b0008c0a8004c8cc004004038894ccc09c00452f5bded8c0264646464a66605066e3d22100002100313302c337606ea4008dd3000998030030019bab3029003375c604e0046056004605200290002504a26eb8c098004c078008c078004c08c004c06c060c8c8c8c8c8c8c94ccc08ccdc3a40000022646464646464646464646464646464646464a6660706076004264646464646464649319299981e99b87480000044c8c94ccc108c1140084c92632375a60840046eb4c10000458c8cdd81822000982218228009bac3043001303b0091533303d3370e90010008a999820181d8048a4c2c2c607601064a66607866e1d2000001132323232323232325333047304a002132498c09401458cdc3a400460886ea8c120004c120008dd6982300098230011822000982200119b8748008c0f8dd51821000981d0060a99981e19b87480080044c8c8c8c8c8c94ccc114c1200084c926302300316375a608c002608c0046088002608800466e1d2002303e3754608400260740182a66607866e1d2004001132323232323232325333047304a002132498c09401458dd6982400098240011bad30460013046002304400130440023370e9001181f1baa3042001303a00c1533303c3370e9003000899191919191919192999823982500109924c604a00a2c66e1d200230443754609000260900046eb4c118004c118008c110004c110008cdc3a4004607c6ea8c108004c0e803054ccc0f0cdc3a40100022646464646464a66608a60900042649319299982199b87480000044c8c8c8c94ccc128c13400852616375a609600260960046eb4c124004c10401854ccc10ccdc3a4004002264646464a666094609a0042930b1bad304b001304b002375a6092002608200c2c608200a2c66e1d200230423754608c002608c0046eb4c110004c110008c108004c0e803054ccc0f0cdc3a401400226464646464646464a66608e60940042649318130038b19b8748008c110dd5182400098240011bad30460013046002375a60880026088004608400260740182a66607866e1d200c001132323232323232325333047304a002132498c09801458cdc3a400460886ea8c120004c120008dd6982300098230011822000982200119b8748008c0f8dd51821000981d0060a99981e19b87480380044c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc134c14000852616375a609c002609c0046eb4c130004c130008dd6982500098250011bad30480013048002375a608c002608c0046eb4c110004c110008cdc3a4004607c6ea8c108004c0e803054ccc0f0cdc3a4020002264646464646464646464a66609260980042649318140048b19b8748008c118dd5182500098250011bad30480013048002375a608c002608c0046eb4c110004c110008c108004c0e803054ccc0f0cdc3a40240022646464646464a66608a60900042646493181200219198008008031129998238008a4c2646600600660960046464a66608c66e1d2000001132323232533304d3050002132498c0b400c58cdc3a400460946ea8c138004c138008c130004c11000858c110004c12400458dd698230009823001182200098220011bac3042001303a00c1533303c3370e900a0008a99981f981d0060a4c2c2c6074016603a018603001a603001c602c01e602c02064a66606c66e1d200000113232533303b303e002149858dd7181e000981a0090a99981b19b87480080044c8c94ccc0ecc0f800852616375c607800260680242a66606c66e1d200400113232533303b303e002149858dd7181e000981a0090a99981b19b87480180044c8c94ccc0ecc0f800852616375c607800260680242c60680222c607200260720046eb4c0dc004c0dc008c0d4004c0d4008c0cc004c0cc008c0c4004c0c4008c0bc004c0bc008c0b4004c0b4008c0ac004c0ac008c0a4004c08407858c0840748c94ccc08ccdc3a40000022a66604c60420042930b0a99981199b87480080044c8c94ccc0a0c0ac00852616375c605200260420042a66604666e1d2004001132325333028302b002149858dd7181480098108010b1810800919299981119b87480000044c8c8c8c94ccc0a4c0b00084c8c9263253330283370e9000000899192999816981800109924c64a66605666e1d20000011323253330303033002132498c04400458c0c4004c0a400854ccc0accdc3a40040022646464646464a666068606e0042930b1bad30350013035002375a606600260660046eb4c0c4004c0a400858c0a400458c0b8004c09800c54ccc0a0cdc3a40040022a666056604c0062930b0b181300118050018b18150009815001181400098100010b1810000919299981099b87480000044c8c94ccc098c0a400852616375a604e002603e0042a66604266e1d20020011323253330263029002149858dd69813800980f8010b180f800919299981019b87480000044c8c94ccc094c0a000852616375a604c002603c0042a66604066e1d20020011323253330253028002149858dd69813000980f0010b180f000919299980f99b87480000044c8c8c8c94ccc098c0a400852616375c604e002604e0046eb8c094004c07400858c0740048c94ccc078cdc3a400000226464a666046604c0042930b1bae3024001301c0021533301e3370e900100089919299981198130010a4c2c6eb8c090004c07000858c070004dd618100009810000980f8011bab301d001301d001301c00237566034002603400260320026030002602e0046eb0c054004c0340184cc004dd5980a180a980a980a980a980a980a980680300591191980080080191299980a8008a50132323253330153375e00c00229444cc014014008c054008c064008c05c004c03001cc94ccc034cdc3a40000022a666020601600e2930b0a99980699b874800800454ccc040c02c01c526161533300d3370e90020008a99980818058038a4c2c2c601600c2c60200026020004601c002600c00229309b2b118029baa001230033754002ae6955ceaab9e5573eae815d0aba25747", + "hash": "40f85724e4211d5504b4356455ca7b3b18b4ee83c11c9f606f183e0e" }, { - "title": "order_validator.validate_order_spending", + "title": "pool_validator.validate_pool", + "datum": { + "title": "datum", + "schema": { + "$ref": "#/definitions/amm_dex_v2~1types~1PoolDatum" + } + }, "redeemer": { "title": "redeemer", "schema": { - "$ref": "#/definitions/amm_dex_v2~1types~1OrderSpendingRedeemer" + "$ref": "#/definitions/amm_dex_v2~1types~1PoolRedeemer" } }, "parameters": [ { - "title": "pool_hash", + "title": "authen_policy_id", "schema": { "$ref": "#/definitions/ByteArray" } } ], - "compiledCode": "590a670100003232323232323232322322232533300832323232533300c3370e900218058008991919191919191919191919299980c19baf3374a90011980e1ba90144bd700008a51132323232323232323232323232323232323232533302b3370e90011815000899191919191919191919980080080700c91119191919191919191919191919191919191919191919191919191919191919299982a99b8748000c1500044c8c8c8c94ccc1654ccc164cdc40010168a99982c99baf00e016153330593371266e04c0a0068004c0a005054ccc164cdd79ba63027014374c604e034266ebcc94ccc168cdc3a4000002298103d87a80001533305a3370e9001000899ba548000cc178c17cc16004d2f5c0266e9520003305e37526e50dd9982f982c009a5eb80c1600480305280a5014a0294054ccc164cdd79ba70224c101800014a2266604c04c0440402c6eb4c168008dd6982c0009919bb0305c001305c305d001375860b600260a60022c60b200260b200260b000260ae00260ac00260aa00260a800460a400260a400460a0002609000464a66609466e1d2000001132323232323232323232323232323232533305d3060002132323232323232498c94ccc184cdc3a400000226464a6660cc60d200426493191bad3066002375a60c80022c6466ec0c1a0004c1a0c1a4004dd61833800982f8040a99983099b874800800454ccc190c17c0205261616305f0073253330603370e900000089919191919191919299983598370010a4c2c66e1d20023068375460d800260d80046eb4c1a8004c1a8008dd69834000983400119b8748008c188dd51833000982f0058a99983019b87480080044c8c8c8c8c8c8c8c94ccc1acc1b8008526163370e900118341baa306c001306c002375a60d400260d40046eb4c1a0004c1a0008cdc3a400460c46ea8c198004c17802c54ccc180cdc3a4008002264646464646464646464a6660da60e00042930b19b8748008c1a8dd5183700098370011bad306c001306c002375a60d400260d40046eb4c1a0004c1a0008cdc3a400460c46ea8c198004c17802c54ccc180cdc3a400c00226464646464646464a6660d660dc0042930b19b8748008c1a0dd5183600098360011bad306a001306a002375a60d000260d000466e1d20023062375460cc00260bc0162a6660c066e1d200800113232323232323232533306b306e002149858cdc3a400460d06ea8c1b0004c1b0008dd6983500098350011bad30680013068002375a60cc00260bc0162a6660c066e1d200a00113232323232323232533306b306e002149858cdc3a400460d06ea8c1b0004c1b0008dd6983500098350011bad30680013068002375a60cc00260bc0162a6660c066e1d200c00113232323232323232533306b306e002149858cdc3a400460d06ea8c1b0004c1b0008dd6983500098350011bad306800130680023370e900118311baa3066001305e00b153330603370e9007000899191919191919191919191919192999838983a0010a4c2c6eb4c1c8004c1c8008dd6983800098380011bad306e001306e002375a60d800260d80046eb4c1a8004c1a8008dd69834000983400119b8748008c188dd51833000982f0058a99983019b87480400044c8c8c8c8c8c8c8c8c8c94ccc1b4c1c0008526163370e900118351baa306e001306e002375a60d800260d80046eb4c1a8004c1a8008dd6983400098340011bad3066001305e00b153330603370e900900089919191919192999834983600109924c646600200200c44a6660d60022930991980180198378011919299983519b87480000044c8c8c8c94ccc1c4c1d00084c9263040003163370e900118371baa3072001307200230700013068002163068001306d00116375a60d400260d40046eb4c1a0004c1a0008dd61833000982f0058b182f005181800598170061816006981600718150078b182f000982f0011bad305c001305c002305a001305a00230580013058002305600130560023054001305400230520013052002305000130480021630480013253330493370e90020008982718238040a99982499b87480080044c8c8cc004004098894ccc13c004584c8c8c8c94ccc140cdc7803801080089980300300198288019bae304f00230530023051001375c609c608e0102c608e00e609800260980046eacc128004c128008c120004c100028c118004c118008dd598220009822000981d80098208009820800981c002181f802181e801981e801981d8011191980080080111299981c0008a5eb7bdb1804c8c8c8c94ccc0e4cdc7a4500002100313303d337606ea4008dd3000998030030019bab303a003375c6070004607800460740024646464a66606a66e1d20020011480004dd6981d1819801181980099299981a19b8748008004530103d87a8000132323300100100222533303a00114c103d87a8000132323232533303b3371e9110000213374a90001981f9ba80014bd700998030030019bad303c003375c6074004607c00460780026eacc0e4c0c8008c0c8004c8cc004004008894ccc0dc0045300103d87a800013232323253330383371e9110000213374a90001981e1ba60014bd700998030030019bab3039003375c606e00460760046072002464a66606466e1d20000011323232325333039303c00213232498c94ccc0e0cdc3a400000226464a66607a60800042649319299981d99b87480000044c8c94ccc100c10c0084c926301000116304100130390021533303b3370e90010008991919191919299982218238010a4c2c6eb4c114004c114008dd6982180098218011bad3041001303900216303900116303e0013036003153330383370e90010008a99981d981b0018a4c2c2c606c00460120062c60740026074004607000260600042c6060002464a66606266e1d20000011323253330363039002149858dd7181b80098178010a99981899b874800800454ccc0d0c0bc0085261616302f00123253330303370e9000000899191919299981b981d0010a4c2c6eb8c0e0004c0e0008dd7181b00098170010b1817000919299981799b87480000044c8c94ccc0d0c0dc00852616375c606a002605a0042a66605e66e1d20020011323253330343037002149858dd7181a80098168010b18168009bad3031001302900116302f0013027001302d0013025006323300100101722533302b00114bd700991929998151919191919191919299981919b87480080045288a5030300013035001302d0013033001302b00130310013031001302800213302e00233004004001133004004001302f002302d00137566054002605400260520026050004604c002604c002604a0026048002604600260440046eb0c080004c080004c07c004c05803cc070004c050004c068004c048004c060004c060004c03cccc8c8c8c0040048894ccc058cdc4a40280022666006006603860386038603860386038603860386038603800466e040052014133004002001300100122253330143371200290000980c8010999801801980d00119b810014800800400cdd6180a80098068031bad3013001300b008300a0011630100013010002300e001300600214984d958c94ccc020cdc3a400000226464a66601a60200042930b1bad300e0013006003163006002375c0024600a6ea80048c00cdd5000ab9a5573aaae7955cfaba05742ae881", - "hash": "911029a455371a40b9b7c9d2723a08da58c7bf27f0d74b60ae688681" + "compiledCode": "590f45010000323232323232323232232222323232323232533300e3232323253330123370e90011808800899191919299980b19b87480000084cc004dd5980d980e180e180e180e180e180e180a003980d980a0088991919191919191919191919299981119b87480080384c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0d0cdc3a4000606600226464646464646464646464646464646464a66608a666605600204002c0262a66608a6660580400160022a66608a605c605e032264646464646464646464646464646464a6660aaa6660aa66e1cccc0e00241452201034d535000480084cdd79ba6009374c00629404c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc20004cdc3a4000002264a6661020266ebc0a405454ccc20404cdd78138098a9998408099baf02501115333081013370e04601e2a6661020266e1c08403454ccc20404cdc380f8058a99984080a9998408080b8801899984080801a504a22a6661020266ebc0dc0c454ccc20404ccc0f002520a01f4802854ccc20404ccc0f001d20a01f4802840045280a5014a029405280a5014a029405280a50325333081013370e90010008a51133303c375a610c0260fe00a904827241083460fe0082a6661000266e1d200200115333080013375e0500282a6661000266ebc09804854ccc20004cdd78120080a9998400099b8702200e15333080013370e0400182a6661000266e1c07802854ccc20004cdc380e0040a9998400099b8701a00615333080013375e030008266ebc0d80c05280a5014a029405280a5014a02940528099baf07b02b307e05c3370e9001183f9baa308301001308301002308101001308101002375a60fe00260fe0046eb4c1f4004c1f4008dd6983d800983d8011bad30790013079002375a60ee00260ee00460ea00260ea00460e600260e600460e200260d202c66e1d2002306b375460de00260de00460da00260da0046eb4c1ac004c1ac008dd6983480098348011bad30670013067002375a60ca00260ca0046eb4c18c004c18c008c184004c184008c17c004c17c008c174004c154148c12c004c0dc00458c164004c164008dd5982b800982b801182a800982699817013000982980098258019bab30510013051002304f0013047001304d001304d0013044011222533304833712006004266e2400400c5280a5014a02940c94ccc114cdc3a4000002200e2a66608a66e1d20020011002100430430213048001304800230460013046001304500230430013043001303a0013301c014037303f0013037001303d001303d0013034001303a0013032001163301300e0203758606e002606e002606c0046eacc0d0004c0d0004c0cc008dd59818800981880098180011bac302e001302e0023758605800260580046eb0c0a8004c088054c0a0004c0800704c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0c8cdc3a400060620022646464646464646464646464a66607c666604800203602201c2a66607c66604a03600c0022a66607c604e6050028264646464646464646464646464646464646464a6660a2a6660a266ebc03401c54ccc144cdd7826001099b8733303400b04d4881034d535000480085280a501323232323232323232323232323232323232323375e6e98060dd31999812999981280f00400319b8100c533306453330643371e0109110013371e00c9110014a0266e0400520c0a8a50410010040023370201466608e03c00800466608c03a00e00a6eb8c19c004c19c008dd71832800982e8051bae30630013063002375c60c200260b20106eb4c17c004c17c008dd6982e800982e800982e001182d000982d001182c000982c00098278260b18228009818800982980098298011bab30510013051002304f001304733028022001304d001304500337566096002609600460920026082002608e002608e002607c01a4444a66608666e1c00520001004132323300100100622533304900113304a337606ea4018dd3001a5eb7bdb1804c8c8c8c94ccc128cdd79980600500126103d879800013304e337606ea4028dd30038028a99982519b8f00a00213232533304c3370e900000089982819bb0375201860a2609400400a200a609400264a666096a66609c00229445280a60103d87a800013374a9000198279ba60014bd70191980080080111299982780089982819bb037520166ea00292f5bded8c0264646464a6660a066ebccc04803c00930103d8798000133054337606ea403cdd40070028a99982819b8f00f0021323253330523370e900000089982b19bb0375202260ae60a000400a200a60a000264a6660a266e1c005200014c103d87a800013374a90001982a9ba80014bd7019b8000100e133054337606ea4008dd4000998030030019bad3051003375c609e00460a600460a200226609c66ec0dd48011ba600133006006003375660960066eb8c124008c134008c12c004c8c8008c8cc004004008894ccc124004526132533304a00114984c8c8c8c8c8c8c94ccc138cdc3a4000002266014014660a400c00a2c60980026601c0040026eb8c13000cdd7182580198278019826801182600118260009982399bb037520046ea00052f5bded8c044a66608066e400080045300103d8798000153330403371e0040022980103d87a800014c103d87b800014a02940528182100098210009820800981c0009980d00a01a981e800981a800981d800981d8009819000981c00098180008b1980880700f1bac30350013035001303400237566064002606400260620046eacc0bc004c0bc004c0b8008dd6181600098160011bac302a001302a002375860500026040026446464a666050605600420022c605200266016004466ebcc0a4c088c0a4c08800400888cc0180088cdd7981418108008011119299981119b8748000c0840044c8c8c8c8c8c8c8c8c8c94ccc0b0cdc39998078018062441044d53475300480084c8c8008c94ccc0b8cdc3a40000022646464646464646464646464a66607a608000426464646464649318120031811803981100418108049810005191980080080611299981f8008a4c264660060066086004604260820022c607c002607c004607800260780046074002607400460700026070004606c002606c0046eb0c0d0004c0b000858c0b0004c03800458c0c0004c0c0008dd5981700098170009812800981580098158009811000981400098100008b1980280111919191919191919299981519b87480080044cdc79bae302f302800200a14a06050002605a002604a00260560026046002605200260520026040002464a66604066e1d200400113025301e00216301e00122232323253330233370e90010008a400026eb4c0a0c084008c084004c94ccc088cdc3a40040022980103d87a8000132323300100100222533302800114c103d87a800013232323253330293371e014004266e9520003302d375000297ae0133006006003375a60540066eb8c0a0008c0b0008c0a8004dd598139810001181000099198008008021129998128008a6103d87a800013232323253330263371e010004266e9520003302a374c00297ae01330060060033756604e0066eb8c094008c0a4008c09c00488c8cc00400400c894ccc08c0045300103d87a8000132325333022300500213374a90001981300125eb804cc010010004c09c008c0940048c94ccc074cdc3a4000002264646464a666048604e004264649319299981199b87480000044c8c94ccc0a0c0ac0084c926301c0011630290013021003153330233370e90010008a99981318108018a4c2c2c604200460320062c604a002604a004604600260360042c60360024444646464a66604266e1d2000001132323300100100622533302700114a026464a66604c66e3c00801452889980200200098158011bae3029001375c604c603e0042646464a66604800229444c8cc004004028894ccc0a400452809919299981419baf302d3026302d3026302d302e302600200914a2266008008002605a00460560026601c00e66e952000330273374a9001198139ba90014bd7025eb80dd71813800980f801180f8009812000980e00211119191929998111812800899198008008039129998120008a511323253330233232323232323232533302b3370e90010008a99981599baf00200e14a2266ebc010040528981480098170009813000981600098120009815000981500098108010998020020008a5030280023026001163300600523375e0046048603a6048603a6048604a603a0026044002603400444646600200200644a66603e002297ae013232533301e3005002133022002330040040011330040040013023002302100123375e6e98005300101a0002323300100100222533301c00114bd6f7b630099191919299980e99b8f4881000021003133021337606ea4008dd3000998030030019bab301e003375c60380046040004603c00244646600200200644a66603800229404c8c8c94ccc070cdd78030008a51133005005002301c0023020002301e001301300e3018001301000116301600130160023014001300c00714984d958c94ccc038cdc3a40000022a66602260180102930b0a99980719b87480080044c8c94ccc04cc0580084c9263253330113370e90000008a99980a18078010a4c2c2a66602266e1d200200115333014300f00214985854ccc044cdc3a40080022a666028601e0042930b0b18078008b180a00098060040a99980719b874801000454ccc044c0300205261616300c0073001007232533300d3370e9000000899191919191919191919191919191919191919192999812181380109919191924c64a66604a66e1d200000113232533302a302d002149858dd6981580098118038a99981299b874800800454ccc0a0c08c01c52616163023006301901130180123018013163370e900118109baa3025001302500230230013023002375a604200260420046eb4c07c004c07c008dd6980e800980e8011bad301b001301b002375a60320026032004602e002602e004602a002602a004602600260160042c6016002464a66601866e1d200000113232323253330133016002149858dd7180a000980a0011bae3012001300a00216300a001232533300b3370e9000000899192999808180980109924c600a0022c602200260120042a66601666e1d2002001132323232323253330143017002149858dd6980a800980a8011bad30130013013002375a602200260120042c6012002464a66601466e1d200000113232533300f3012002149858dd7180800098040010a99980519b87480080044c8c94ccc03cc04800852616375c602000260100042c60100026eb80048c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d101", + "hash": "42b2ebb649207c5a79b43eeec999427439b90b36a312f2ebb1a93580" }, { - "title": "pool_validator.validate_pool", - "datum": { - "title": "raw_datum", - "schema": { - "$ref": "#/definitions/Data" - } - }, + "title": "pool_validator.validate_pool_batching", "redeemer": { "title": "redeemer", "schema": { - "$ref": "#/definitions/amm_dex_v2~1types~1PoolRedeemer" + "$ref": "#/definitions/amm_dex_v2~1types~1PoolBatchingRedeemer" } }, "parameters": [ @@ -125,10 +190,16 @@ "schema": { "$ref": "#/definitions/ByteArray" } + }, + { + "title": "pool_payment_cred", + "schema": { + "$ref": "#/definitions/aiken~1transaction~1credential~1Credential" + } } ], - "compiledCode": "593a8b010000323232323232323232322322223232533300a32323232533300e3370e9001180680089919191919191919191919191919191919191919191919191919191919191919191919191919299981a19b87480000904c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc13cccc13cc158069282511533304f303b01a1533304f33323001001222533305500213375e6e9c0053010180001533305500114a0266600600660b000460b00020340302a66609e607a607c01a2646464646464646464646464646464646464646464646464646464646464646464646464a6660e6a6660e66603207c0062660b400400229404cdd79ba7004374e646666600200200600407a00e44444646464646464646464646464646464646464646464646464646464646464646464646464a66613802a6661380266e2120000031533309c013371090000100a99984e0099b890200031533309c013375e07200e264a66613a0266e1d200200114a226466e24140dd6984f809919bb030a40100130a40130a501001375861460200261360200461360200229405280a5014a0264a66614002048200226666605405404804404000264a66613a0266e1d20000011323232323232323253330a50153330a501337109000002899b884800000c52809999999999999999982681081580c00b00a00900380282302201482001f01e017000919b89004001163370e90011852809baa30a90100130a901002375a614e02002614e020046eb4c29404004c29404008cdc3a4004613e026ea8c28c04004c26c0401854ccc27404cdc3a400400226464646464646464a66614a02a66614a0266e21200000513371090000018a5013333333333333333304d02102b01801601401200700504604402904003e03c02e0012337120020082c66e1d200230a50137546152020026152020046eb4c29c04004c29c04008dd698528080098528080119b8748008c27c04dd5185180800984d808030a99984e8099b87480100044c8c8c8c8c8c8c8c8c8c94ccc29c054ccc29c04cdc42400000e2a66614e0266e21200000513371090000018a5014a026666666666666666609e04605a03403002c02801200e09008c05608408007c0600024a6661500266e24018004528899b89001004163370e90011853809baa30ab0100130ab01002375a6152020026152020046eb4c29c04004c29c04008dd698528080098528080119b8748008c27c04dd5185180800984d808030a99984e8099b87480180044c8c8c8c8c8c8c8c94ccc294054ccc29404cdc42400000a266e21200000314a0264646464646464646464646464646464646464646464646464646464a66618202002264a6661840266660d606205e0020902a6661840204826618c026ea0cdc099b8001d004003330c601375066e0406c080cc31804dd419b80019004330c601375066e0405c080cc31804dd400aa5eb804cc31804dd419b8101d020330c601375066e04cdc000d80200199863009ba8337020320406618c026ea0cdc000b80219863009ba80154bd700b199984f00999984f00999984f0081ea4410048810033702900002280500419b814800000c01801007c54ccc304054ccc304040744cccc1a80d00c8cc1ac0f411411c52808250b19b89002020333308c0100105a05805653330be0133710038012266e00cdc199b82337040160380ae66e08cdc080480e19b810570594800858dd71861008009861008011bae30c00100130b801009375c617c02002617c020046eb8c2f004004c2d00401cdd6985d00800985d008011bad30b80100130b80100230b60100130b60100230b40100153330ae010101330b20104f330b20104d330b201375001266164026ea001d2f5c02661640209a661640209e66164026ea001ccc2c804dd4004a5eb80dd69859008009859008011bad30b00100130b001002375a615c02002615c020046eb4c2b004004c2b0040bcdd69855008170b19b8748008c29404dd51854808009854808011bad30a70100130a701002375a614a02002614a0200466e1d2002309f01375461460200261360200c2a66613a0266e1d20080011323232323232323253330a50153330a5013371290000038a9998528099b894800001454ccc29404cdc42400066e0001c0144cdc42400000629405280a5013232323232323232323232323232323232323232323232323232323253330c10100113253330c201333306b03102f0010481330c601375066e04cdc000e81200399863009ba83370266e0006c088014cc31804dd419b80019024330c601375066e0005c088cc31804dd419b800150034bd700b199984f00999984f00999984f00999984f0081ea450048810033702900002280900819b814800008c038030cdc0a40000420140100042a66618202a6661820203a266660d4068064660d607a08a08e2940412858cdc480f0009bad30c40100130c401002375a6184020026184020046eb4c30004004c8c94ccc2f004cdc4000801099191919191919863009ba83333306f00500405d05b059330c6014c01010000330c601375066e0ccdc119b803370404400200402a66e04cdc100d80080125eb80dd69861808011bad30c10100133333306b01a01800200105a058375a6180020046eb4c2f804004cccccc19c07807005c05415c15454ccc2f004cdc400100089919191919191986300a61010000330c6013750666660de00a0080ba0b60b26618c026ea0cdc199b823370066e08090004008054cdc099b8201d0010024bd701bad30c301002375a6182020026666660d60300340040020b40b06eb4c30004008dd6985f0080099999983380e00f00a80b82b82a89986000a601010000330c0014c1010000330c001375000497ae03370666e0806c038050cdc199b8201c00d015375c617c02002617c020046eb8c2f004004c2d00414cdd7185d00800985d008011bae30b80100130b001051375c616c02002616c020046eb8c2d004004c2b00413cdd69859008009859008011bad30b00100130b001002375a615c02002615c020046eb4c2b004004c2b0040bcdd69855008170b19b8748008c29404dd51854808009854808011bad30a70100130a701002375a614a02002614a020046eb4c28c04004c26c0401854ccc27404cdc3a401400226464646464646464a66614a02a66614a0266e212000007153330a501337109000002899b884800000c5280a5013232323232323232323232323232323232323232323232323253330be0100113253330bf01333306802e02c0010451330c301375066e04068010cc30c04dd419b81018003330c301375066e04058010cc30c04dd419b81014003330c301375066e040480852f5c02c66661360266661360266661360266661360207491010048810033702900002100380299b814800008003c03400c02c02400854ccc2f8054ccc2f8040684cccc19c0c40bccc1a00e810811052808238b299985e8099b8901d0021337120360022940dd6985f008011bad30bc01001333306801501301c00d375c617c02002617c020046eb8c2f004004c2d00414cdd7185d00800985d008011bae30b80100130b001051375c616c02002616c020046eb8c2d004004c2b00413cdd69859008009859008011bad30b00100130b001002375a615c02002615c020046eb4c2b004004c2b0040bcdd69855008170b19b8748008c29404dd51854808009854808011bad30a70100130a701002375a614a02002614a020046eb4c28c04004c26c0401854ccc27404cdc3a401800226464646464646464a66614a02a66614a0266e21200000513371090000018a5013232323232323232323232323232323232323232323232323253330be0100113253330bf01333306802e02c001045153330bf010211330c301375066e0406801ccc30c04dd419b813370203000a00666186026ea0058cc30c04dd419b81014003330c301375066e0404807d2f5c0266186026ea0cdc099b8101a003007330c301375066e04060014cc30c04dd419b81016003330c301375002866186026ea0cdc080900fa5eb8058cccc26c04cccc26c04cccc26c040e922010048810033702900002100500419b814800007803803000854ccc2f8054ccc2f8040684cccc19c0c40bccc1a00e810811052808238b19b8901b001375a6182020026182020046eb4c2fc04004c2fc04008dd6985e808009919191919299985e0080f099860009ba8333308901004057055053330c0014c01010000330c001375066e0000cccccc2280400800401015c1552f5c026618002981010000330c00137506666112020060ae0aa0a666180026ea0cdc0002199998450080080100182b82aa5eb80cdc080a00119b81015002375a6176020046eb4c2e404004cccc19404804005c028dd7185d80800985d808011bae30b90100130b101050375c616e02002616e020046eb8c2d404004c2b4040054ccc2b8040404134413cdd69859008009859008011bad30b00100130b001002375a615c02002615c020046eb4c2b004004c2b0040bcdd69855008170b19b8748008c29404dd51854808009854808011bad30a70100130a701002375a614a02002614a0200466e1d2002309f01375461460200261360200c2a66613a0266e1d200e0011323232323232323232323232323253330ab0153330ab013371090000048a9998558099b884800001c54ccc2ac04cdc42400000a2a6661560266e212000003153330ab0133712006016266e240bc0045280a5014a0294052809919191919191919191919191919299985c80a99985c808008991919191919191929998608099baf00100313375e07e00e2940cdd2a400066188020666618802062661880205e661880205a6618802056661880266e95200e330c4013330c0010224c0103d87a80004c0103d8798000330c401375001466188026ea0078cc31004dd400e19862009ba833702034900119862009ba8018330c401375002c97ae0330c401375066e0409c110cc310040952f5c06120020026613e020e8002618402002618402002618202004617e02002616e0207e26661100205004c07e26617a026ea0034cc2f404dd40059985e809ba8009330bd01375000e6617a026ea00152f5c02c66e1d200230b9013754617a02002617a020046eb4c2ec04004c2ec04008dd6985c80800985c808011bad30b70100130b701002375a616a02002616a020046eb4c2cc04004c2cc04008dd698588080099191919191919191919191919191919191919191919191919191919191919299986500a9998650099b884800001454ccc32804cdc4811002899baf374c0026e981045280a5013253330cb0102d1330cf01375066e04cdc001000300199867809ba83370203c0086619e026ea0cdc000e00319867809ba8337020340086619e026ea0060cc33c04dd4002998678099986580800a6103d87a80004c0103d87980004bd70099867809ba8337020400086619e026ea0cdc099b8001e006003330cf01375066e04070010cc33c04dd419b8001a006330cf0137500306619e026ea0014cc33c04ccc32c04005300103d87a80004c0103d87980004bd7029998650099b88480080904cdc48110020a501633330a60133330a60133330a60104548810048810033702900002680600519b8148000010020018008cccc2540400c18c18417cccccc25404038030008188180cdc0813000a9998628099b89025001102510013232323253330c80133710900000088008b19b830020013370404400466e04cdc119b8202300100a3370466e08084178030cdc082e82f9bae30c80100130c801002375c618c02002617c020126eb8c31004004c31004008dd7186100800985d008039bad30c00100130c001002375a617c02002617c02004617802002617802004617402002a6661680202c266170020aa66170020a666170026ea0024cc2e004dd4003a5eb804cc2e00414ccc2e004154cc2e004dd40039985c009ba80094bd701bad30b80100130b801002375a616c02002616c020046eb4c2d004004c2d004008dd698590080098590081a9bad30b00103416375a615e02002615e020046eb4c2b404004c2b404008dd69855808009855808011bad30a90100130a901002375a614e02002614e020046eb4c29404004c29404008cdc3a4004613e026ea8c28c04004c26c0401854ccc27404cdc3a4020002264646464646464646464a66614e02a66614e0266e212000009153330a7013371090000038a9998538099b88480000144cdc42400000629405280a50132323232323232323232323232323232323232323232323232323232323253330c50100113253330c601333306f03503300104c1330ca01375066e04cdc080f80280499865009ba83370266e0407400c01ccc32804dd419b8101b005330ca01375066e0406400ccc32804dd419b810170284bd700b199985100999985100999985100999985100820a4410048810033702900002480600519b814800009c05004801004003800854ccc314054ccc3140407c4cccc1b80e00d8cc1bc10412412c52808270b19b89020003375a6190020026190020046eb4c31804004c31804008dd69862008009862008011bad30c2010013232323232323253330c3013371000200426466190026ea0cccc2440400417c17416ccc32005301010000330c801375066e0401c004cc32004dd419b80006333330920100500400105f05d4bd701999999983900300280200181181082f02e0a9998618099b88002001132330c8014c01010000330c80137506666122020020be0ba0b666190026ea0cdc0003999998490080200280082f82e99864009ba83370200c00297ae03333333307200500600300402102305e05c1330c7014c1010000330c7014c1010000330c701375000c6618e026ea00152f5c066e08010088cdc100200f99b81017002337020300046eb4c30004008dd6985f00800999983500a80980f0069bae30c00100130c001002375c617c02002616c020aa6eb8c2f004004c2f004008dd7185d008009859008299bae30b80100130b801002375c616c02002615c020a26eb4c2d004004c2d004008dd69859008009859008011bad30b00100130b001002375a615c02002615c020626eb4c2b0040c058cdc3a4004614e026ea8c2ac04004c2ac04008dd69854808009854808011bad30a70100130a701002375a614a02002614a020046eb4c28c04004c26c0401858c26c0401458c28004004c28004008dd6984f00800984f00801184e00800984e00801184d00800984d00801184c00800984c00801184b00800984b00801184a00800984a00801184900800984500801182e000998358200021bab308e01001308e0100130850100d308b01001308b010023756611202002611202004610e0200260fe002610a02002610a0200260f800c61060200e6eb4c20404018c20404018c1fc014c1fc014c1f401058cc1200cc8c8c94ccc1d4ccc1d4cdd78008052504a226660ea66ebc0040a12825114a060f200260e20026466600200207a97ae0222533307700210011333003003307a002330783304c004375a60f20040026608c06846464646464a6660ec6660ec66ebc00402d2825113330763375e002052941288a50307a001307200130780013078001306f001375860e800260e80046eb0c1c8004c1c8008c1c0004c1c0008c1b8004c1b8008dd6983600098360011bad306a001306a00230680013068002306600130660023064001305c33333303a00200105a0590144a060be00460ba00264a6660b866e1d2000305b001132323232323232323232323253330683375e00200c264a6660d860de002266ec002401058cc0f80b08cdd798371833983718339837183798338008028b183600098320009981d013000983480098308009833800982f80098328009832800982e0009831000982d0008b1981900f919baf04d3061305a0013001001222533305f00213375e6e9c00530010180001533305f00114a0266600600660c400460c40024444444444444444464646464646464646464646464646464646464646464646464646464a66610a02002264a66610c02666605e05405200205a2a66610c02050266114026ea0cdc099b8001d0270033308a01375066e0406c010cc22804dd419b800190273308a01375066e0405c010cc22804dd400aa5eb804cc22804dd419b8101d0043308a01375066e04cdc000d81380199845009ba83370203200866114026ea0cdc000b81399845009ba80154bd700b199983119998311999831016a450048810033702900001180500419b814800009801801000c54ccc214054ccc214040784cccc0b80ac0a8cc0bc0b408c0b0528080f8b180e001199982801201000f80f1999982800580481180f80f1bae308601001308601002375c61080200260f80126eb8c20804004c20804008dd7184000800983c0039bad307e001307e002375a60f800260f800460f400260f400460f0002a6660e40282660ec024660ec022660ec6ea0024cc1d8dd4003a5eb804cc1d8044cc1d8048cc1d8dd40039983b1ba80094bd701bad30760013076002375a60e800260e80046eb4c1c8004c1c8008dd6983800098380021bad306e00322223232323232323232323253330653370e900000088020a99983280209981a8028068a5030630013068001306000b53330613375e01400a266ebcdd30041ba600314a060ca00260ca0046eacc18c004c18c008c184004c16400488cccc0d4009221004881003370400290009111111919191919bb0375066e04c040cdc0980780099b823370400600a66e04014018004dd419b820023370200a00c66e08cdc099b824801001001400ccdc12400866e0001c014cdc119b8248020cdc000300219b813370400c601800a66e08cdc100380280219b823370000a0060084444446466ec0dd419b823370400a00200c6ea0cdc019b823370400400800e66e08014004cdc08008011111119299982c99b874800800452000132323370666e08cdc10040031bad305c0013370466e0801c014dd6982e8009919bb0306000130603061001375860be00260ae00460ae002444466ec0dd419b83337040040080026ea0cdc199b82002003001222222223232323370666e04c034cdc099b820010013370466e0920080023370466e08010024cdc099b8200700a3370400c01600266e0920040023370066e08cdc100300119b800070093370400a66e04cdc100400199b8200200a3370400800266e040040088cdc10008009299982819b88001480005854ccc140cdc3800a4000290000a99982819b870014800852002153330503370e00290020a400426464666002002006004444a6660a866e200040084ccc00c00c004cdc199b803370600a0020029002080119b803370600290022400429405280a5014a06eb4c140008c138004ccc0d52211c229013ad3a22d2d051a28e7f9214a32444ecf19998f7bdf0c2849862000010063302300f0123756609e002609e002609c002609a00460960026096002609400260920046eacc11c004c11c004c118008dd61822000982200098218011bac30410013039030301a035375a607c002607c0046eb0c0f0004c0f0008dd6181d00098190170a99981a19b87480080904c8c8c8c8c8c8c8c8c8c8c8c94ccc1014ccc100cdc38010008a99982019b894801000454ccc100c0b00244c0b001c5280a5014a026464646464646464646464646464646464646464a6660a86084608601a264646464646464646464646464646464646464a6660d460da00426464a6660d860de0042646464646464646464646464646464646464646464646464646464a66610802a6661080266e21200000315333084013371090000248a9998420099b89049003153330840133305300b00901c15333084013375e04e00e264a66610a0266e1d200200114a226466e240ccdd69843809919bb0308c01001308c01308d01001375861160200261060200461060200229405280a5014a029404c94ccc21404cdc3a40240022646464646464a66611602a6661160266e2120000031533308b013371090000008998390190028a5014a02646464646464646464646464646464646464646464646464646464646464a6661520266e2407c0084cdd79ba6001374c06c2940cccc21404cccc21404cccc214040e922010048810033702900003680400319b8148000080010008004ccc14407c138084dd71855808009855808011bae30a90100130a101005375c614e02002614e020046eb8c29404004c274040094ccc27804028400840114ccc27404030401c4014c28404004c28404008c27c04004c25c0402cc27404004c27404008c26c04004c24c04020cdc3a4004612a026ea8c26404004c26404004c24004018cdc3a40046124026ea8c25804004c25804004c23404010cc1980d4cdc0981b01aa4004612402068660c800c66e04c0d0019200230900100516375a611e02002611e020046eb4c23404004c23404008dd61845808009841808030a5030830100516308801001308801002375a610c02002610c0200461080200261080200461040200261040200461000200261000200460fc00260fc00260fa00260e8004608c002660aa04a0086eacc1e0004c1e0004c1bc024c1d4004c1d4008dd59839800983980098350009838000983800098338018b18368009981e811919191919299983619983619baf00301a4a09444ccc1b0cdd78008042504a22940c1c0004c1a0004c1b8004c19800458c1ac004cc0ec0908c8c8c8c8c8c8c94ccc1b4ccc1b4cdd780180da504a226660da66ebc0040252825114a060e200260d200260de00260ce00260da00260da00260c800260d200260c200260ce00260ce00260cc00260ca00260c800460c400260c400260c200260b060be0026464646464a6660c260c8004264646464646464a6660ca66e1cc034cc0ec0908cdd798359832183598321835983618320008010050a99983299b87300d3303b02123375e60d660c860d660c80020040142646466600200201c01a44464646464a6660da66ebcdd3801a6101800015333070001133071330080040024bd700b09983899804002001199803803801800983900218380019838001983700111191919191919191919191919299983999baf008003133333304f00a00d06f0020244a22c60a4002660a404400660ea00260da01260e600260e600260e400460e000260d000260dc00260dc00260ca0042c2c60d200260c200260ce00260be00260ca00260ca00260b80022c60c400266064036466ebc138c188c16c004c00c008cc0180848cc0cc05c004cc0140888cc0c8064004c004004894ccc17000452000133700900119801001182f8009800800911119191919192999830802080089999804804800802001191919191919191919191919191919191919191919191919191919191919191919299983f19baf01e00313232325333081013371090000158991929998418099b884800000854ccc20c054ccc20c0401854ccc20c04cdc399b813370002e05a0020202a6661060266e1ccdc080a8010070a9998418099b873370002605a018266e1ccdc08088010050a5014a0294054ccc20c04cdc399b8101700201015333083013370e66e04cdc000a8168008070a9998418099b8733702026004018266e1ccdc00088168050a5014a0294040085858cccc13c0b0080078070ccccc13c0080040ac07c07458dd69841008011bad308001001533307e0011337606ea0048dd4008099bb037500206ea004858cdc3a400460fc6ea8c20804004c20804008c20004004c1e007cdd6983f000983f0011bad307c001307c002375a60f400260f40126eb4c1e0020dd6983b800983b8011bad30750013075002375a60e600260e60086eb4c1c400cdd6183800098380011bac306e001306e001306d002306b001306b002375a60d200260d20046eb4c19c004c19c008c194004c194004c190004c16c010c188010c18000cc18000cc17800888c8cc00400400c894ccc16c00452f5c02660b860066eb4c174004cc008008c1780045281bad3055002305300133303a48811c229013ad3a22d2d051a28e7f9214a32444ecf19998f7bdf0c2849862000010063302800f01b375660a800260a800260a600260a400460a000260a0002609e002609c0046eacc130004c130004c12c008dd61824800982480098240011bac3046001303e035163002006300100730010012253330410011480004cdc0240046600400460880026eb4c100004c100008dd6181f000981f0011bac303c001303c002375a6074002606405c26464646464a66607266e1d2004029132323232323232323232323232323232323232323232323253330513370e900018280008991929998299999980e2451cf8c20eb8b2e773e21cf41ab6354cf09bd255ebed0bd8847c655e67b40001400c00800a15333053301f006153330533041304200f1323232323232323232323232323232533306253330623370e6660820120bc9101034d535000480084cdd79ba6009374c00629404c8c8c94ccc194cdc3a40000022646464646464646464646464646464646464646464646464646464a6661000266ebc06804054ccc20004cdd780c0070a9998400099b8701600c15333080013370e0280142a6661000266e1c04802054ccc20004cdd78148118a99984000a9998400099b88480000104c8c94ccc20804008400452819b893370400a900519b82007482827004cdc499b8200648050cdc1002240042c200229405280a5014a029405280a50325333080013370e90010008a511323233225333084013371090000008991929998430080108008a503371266e08009200233704006900619b8933704004900219b820014800858dd69841808009bad3084010013233760610e02002610e026110020026eb0c21804004c1f8008c1f8004c20c04004c20c04008dd69840808009840808011bad307f001307f002375a60fa00260fa0046eb4c1ec004c1ec008dd6983c800983c801183b800983b801183a80098368069bad30730013073002375a60e200260e20046eb4c1bc004c1bc008c1b4004c1b4008c1ac004c18c1804cdd783000198318151821800998218098008b183300098330011bab306400130640023062001305a3303101b00130600013058003375660bc00260bc00460b800260a800260b400260b400260a200229405280a503057001304f0011633018013041375660a800260a80046eacc148004c148008dd618280009828001182700098270011bab304c001304c001304b00237566092002609200260900046eb0c118004c118008dd6182200098220011bac3042001303a031301b036303f0013037033132323232323232323232323232323232323232323232533304f3370e900018270008991929998289999980d2451cf8c20eb8b2e773e21cf41ab6354cf09bd255ebed0bd8847c655e67b40001400c00800a15333051301d00615333051303f304000f13232323232323232323232323232323232533306253330623375e01a00e2a6660c466ebc1740084cdc399982080582f2441034d535000480085280a5013232323232323232323232323232323232323375e6e9805cdd31999828999982880e80400319b8100c53330743305200800613370200290404df701080080200119b8100a33305301d00400233305201c007005375c60ee00260ee0046eb8c1d4004c1b4028dd7183980098398011bae30710013069008375a60de00260de0046eb4c1b4004c1b4004c1b0008c1a8004c1a8008c1a0004c18017458c104004cc10404c004c190004c190008dd5983100098310011830000982c1981780d800982f000982b0019bab305c001305c002305a001305200130580013058001304f00114a02940528182a80098268008b1980b00981f9bab30520013052002375660a000260a00046eb0c138004c138008c130004c130008dd59825000982500098248011bab3047001304700130460023758608800260880046eb0c108004c108008dd61820000981c017980c81a1119808801119baf30403039001002222223232533303e3370e900000089919191919191919191919299982499b87480000044c8c8cc004004044894ccc13c00452809919299982719b8f00200514a226600800800260a60046eb8c144004dd71827182380109919198008008091129998278008a501323232533304f3375e00c00229444cc014014008c13c008c14c008c144004cdd2a40006609a00497ae03047001304c0013044001304a001304200130480013048001303f0023330290090010053044001303c00214a0607800266026008466e212000300733027375660846086607660846086607600200c600200244a66607400229000099b8048008cc008008c0f40048c94ccc0e4c0f00045288b191980080080111299981d0008a5eb7bdb1804c8c94ccc0e4c8c94ccc0eccdc3a40040022944528181c800981d00109981e80119802002000899802002000981f001181e000911119299981c19b874800800452000132323370666e08cdc10038031bad303b0013370400a6eb4c0f0004c8cdd8181f800981f98200009bac303e001303600230360012222232323370666e08004018cdc019b820030070013370400200866e04004008888c8c8c8c8c8c8c8c8c94ccc0f4cdc3a400000220042a66607a00426601a00a0162940c0ec008cdd7805003181f800981b804181e800981e800981e001181d00098190009119baf3253330333370e90000008a60103d87a8000153330333370e9001000899ba548000cc0dcc0e0c0c400d2f5c0266e9520003303737526e50dd9981c1818801a5eb80c0c40080048c94ccc0c4cdc3a4000002264646464646464646464646464646464a666088608e00426464646464646493181680399299982399b87480000044c8c8c8c8c8c8c8c94ccc148c154008526163370e900118279baa30530013053002375a60a200260a20046eb4c13c004c13c008cdc3a400460926ea8c134004c11402c54ccc11ccdc3a400400226464646464646464a6660a460aa0042930b19b8748008c13cdd5182980098298011bad30510013051002375a609e002609e00466e1d200230493754609a002608a0162a66608e66e1d200400113232323232323232323253330543057002149858cdc3a400460a26ea8c154004c154008dd6982980098298011bad30510013051002375a609e002609e00466e1d200230493754609a002608a0162a66608e66e1d20060011323232323232323253330523055002149858cdc3a4004609e6ea8c14c004c14c008dd6982880098288011bad304f001304f0023370e900118249baa304d001304500b153330473370e9004000899191919191919192999829182a8010a4c2c66e1d2002304f375460a600260a60046eb4c144004c144008dd6982780098278011bad304d001304500b153330473370e9005000899191919191919192999829182a8010a4c2c66e1d2002304f375460a600260a60046eb4c144004c144008dd6982780098278011bad304d001304500b153330473370e9006000899191919191919192999829182a8010a4c2c66e1d2002304f375460a600260a60046eb4c144004c144008dd69827800982780119b8748008c124dd5182680098228058a99982399b87480380044c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc160c16c00852616375a60b200260b20046eb4c15c004c15c008dd6982a800982a8011bad30530013053002375a60a200260a20046eb4c13c004c13c008cdc3a400460926ea8c134004c11402c54ccc11ccdc3a4020002264646464646464646464a6660a860ae0042930b19b8748008c144dd5182a800982a8011bad30530013053002375a60a200260a20046eb4c13c004c13c008dd6982680098228058a99982399b87480480044c8c8c8c8c8c94ccc140c14c0084c92633045005232533304f3370e9000000899191919299982b182c80109924c60700062c66e1d20023053375460ae00260ae00460aa002609a0042c609a0022c6eb4c144004c144008dd6982780098278011bac304d001304500b16304500a302a00b301600c301600d301400e301400f1630450013045002375a6086002608600460820026082004607e002607e004607a002607a0046076002607600460720026072004606e002605e0042c605e002464a66606066e1d20000011323253330353038002149858dd7181b00098170010a99981819b874800800454ccc0ccc0b80085261616302e001232533302f3370e9000000899191919299981b181c8010991924c64a66606a66e1d200000113232533303a303d002132498c94ccc0e0cdc3a400000226464a66607a60800042649318070008b181f000981b0010a99981c19b87480080044c8c8c8c8c8c94ccc104c11000852616375a608400260840046eb4c100004c100008dd6981f000981b0010b181b0008b181d80098198018a99981a99b874800800454ccc0e0c0cc00c52616163033002300700316303700130370023035001302d00216302d001232533302e3370e9000000899192999819981b0010a4c2c6eb8c0d0004c0b000854ccc0b8cdc3a400400226464a666066606c0042930b1bae3034001302c00216302c0012232325333032303500210011630330013300300223375e606660586066605800200444646600200200644a666062002297ae01323253330303005002133034002330040040011330040040013035002303300122323300100100322533303000114c103d87a800013232533302f300500213374a90001981980125eb804cc010010004c0d0008c0c8004c0040048894ccc0a8cdc4a40280022666006006606060606060606060606060606060606060606000466e04005201413300400200130010012225333028337120029000098168010999801801981700119b8100148008888888c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc1554ccc1540b04cdc380e8058a511533305553330553375e04201e2a6660aa66ebc07c03454ccc154cdc380b8028a99982a99b8701500313375e02600229405280a5014a02646464646464646464646464646464646464646464a6660d4a6660d466ebcdd30011ba603d1533306a3375e6e98004dd301d099b873370200600866e040c80805280a5013374a90001983701b1983701a19837006198371ba802c3306e3750054660dc050660dc07e660dc6e9ccc1b8dd4018198371ba802e3306e3750010660dc6ea0018cc1b8dd401925eb80cc1b8dd3998371ba801e3306e3750038660dc6ea001ccc1b8dd4002998371ba80204bd7025eb8058cccc118cccc118cccc118cccc118cccc1192f5bded8c091100488100482026fb80810d2201034d5350004800804c04401803c03401010c030008cccc114cccc114cccc114cccc114cccc1152f5bded8c091100488100482026fb8081092201034d5350004800804804001803803001010802c008ccc1180dc104028ccc1140e4100024ccc1100d402c024ccc10c0dc028020dd698328011bad306300153330613303f00b0091337606ea0cdc08012410137dc046ea0cdc0800a410137dc04266ec0dd40011ba800133303f03000a00833303e0320090073374a9000198311ba903833062375200297ae0304033041304033041007005304033041003001375c60c200260c20046eb8c17c004c15c08cdd7182e800982e8011bae305b0013053021161630590013059002375a60ae00260ae0046eb4c154004c154008dd6982980098298011bad30510013051002375a609e002609e004609a002609a00460960026086004604800266048036022608e002608e0046eb4c114004c114008dd6982180098218011bad30410013041002375a607e002607e0046eb4c0f4004c0f4008c0ec004c0ec008c0e4004c0c4030c0dc004c0dc008dd5981a800981a80098160049bab3032001303200230300013028006222253330273370e00290000802099191980080080311299981680089981719bb0375200c6e9800d2f5bded8c0264646464a66605c66ebccc040028009300103d8798000133032337606ea4028dd30038028a99981719b8f00a0021323253330303370e900000089981a19bb03752018606a605c00400a200a605c00264a66605ea66606400229445280a60103d87a800013374a9000198199ba60014bd70191980080080111299981980089981a19bb037520166ea00292f5bded8c0264646464a66606866ebccc05803c00930103d8798000133038337606ea403cdd40070028a99981a19b8f00f0021323253330363370e900000089981d19bb037520226076606800400a200a606800264a66606a66e1c005200014c103d87a800013374a90001981c9ba80014bd7019b8000100e133038337606ea4008dd4000998030030019bad3035003375c6066004606e004606a00226606466ec0dd48011ba6001330060060033756605e0066eb8c0b4008c0c4008c0bc004c8c8008c8cc004004008894ccc0b4004526132533302e00114984c8c8c8c8c8c8c94ccc0c8cdc3a40000022660140146606c00c00a2c6060002660240040026eb8c0c000cdd7181780198198019818801181800118180009981599bb037520046ea00052f5bded8c044a66604866e3c00922010013371e0029110014a0444646464a66604e66e1d20020011480004dd698161812801181280099299981319b8748008004530103d87a8000132323300100100222533302c00114c103d87a8000132323232533302d3371e014004266e95200033031375000297ae0133006006003375a605c0066eb8c0b0008c0c0008c0b8004dd598159812001181200099807801801119299981119b87480000044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0d4c0e00084c8c8c926301a003301800e301700f1630360013036002375a606800260680046eb4c0c8004c0c8008dd6981800098180011bad302e001302e002375a6058002605800460540026054004605000260400042c60400024464a66604466e1d2004001130273020002153330223370e900100089919198008008029129998140008b099191919299981499b8f0070021001133006006003302a003375c6050004605800460540026eb8c09cc08000858c080004894ccc080cdc80010008a60103d8798000153330203371e0040022980103d87a800014c103d87b8000237260024466e280080048c94ccc074cdc3a4000002264646464a666048604e0042930b1bae30250013025002375c604600260360042c6036002464a66603866e1d20000011323253330213024002132498c8dd698108011bad301f0011632337606046002604660480026eb0c088004c06800854ccc070cdc3a40040022a66603e60340042930b0b180d0009800800911299980f001099baf374e0029810180001533301e00114a0266600600660420046042002444646464646464646464a66604c605200426464646464646464646464a66605c66e1d2002302d0031323253330303370e90011817801899192999819299981919b8700e4800854ccc0c8cdc4800806899b8900d337000069040606dd6e1820a5014a0266ec0050dd40008b1bad3036001302e00316375a606800260580062c6064002605400660600026050006605c002605c0046058002604801a6464660020020044464a666052a66605266e25206000113371200290390a50153330293370e0049000099b81001481804cdc019b82330030033370200490012402866e040052060163371c00a00266e04dc6801240046eb4c098008dd718120008b1813800998058008051bab302500130250023023001301b001302100130210013018002223232533301a3370e90010008a5eb7bdb1804dd5980f980c001180c0009980180100091191980080080191299980e0008a60103d87a8000132323232533301d3371e00e004266e95200033021374c00297ae01330060060033756603c0066eb8c070008c080008c078004c004004894ccc060004528899299980c8008a51132325333018333018323300100100222533301d00114a026464a66603866e1c01800852889980200200098108011bad301f0014a09444cc014014004528180e8019bad301b002301b00123375e6e9800530101a0002323300100100222533301700114bd6f7b630099191919299980c19b8f488100002100313301c337606ea4008dd3000998030030019bab3019003375c602e00460360046032002601e014602800260180022c602400260240046020002601000629309b2b19299980519b87480000044c8c8c8c8c8c94ccc04cc0580084c8c926330090042375a0026601000a46eb400458dd6980a000980a0011bac301200130120023758602000260100082a66601466e1d2002001132323232323232325333015301800213232498cc02c0108dd68009980500291bad00116375a602c002602c0046eb0c050004c050008dd6180900098090011bad301000130080041533300a3370e9002000899192999807980900109924c64a66601a66e1d200000115333010300b00214985854ccc034cdc3a40040022a66602060160042930b0b18058008b180800098040020a99980519b874801800454ccc034c0200105261616300800322323300100100322533300f00114984c8cc00c00cc04c008c00cc044004dd7000918029baa001230033754002ae6955ceaab9e5573eae815d0aba25747", - "hash": "124dc5f4428af77b4c891f023e9a149597122f401ef020ba521867a0" + "compiledCode": "593bf9010000323232323232323232232222323232533300b32323232533300f3370e90021807000899191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919299981ea99981e991919299982019b87480000044c8c8cc004004088894ccc11800452809919299982299b8f00200514a226600800800260940046eb8c120004dd71822981f001099191929998218008a511323300100103222533304800114a026464a66608e66ebcc130c114c130c114c130c134c114008024528899802002000982600118250009919198008008141129998240008a50132323253330483375e00c00229444cc014014008c120008c130008c128004cdd2a40006608c66e95200233046375200297ae04bd701bae3046001303e002303e0013043001303b0021533303d300101413375e6e98c8cc004004094894ccc10800452f5bded8c0264646464a66608666e3d221000021003133047337606ea4008dd3000998030030019bab3044003375c6084004608c0046088002980101a00014a029404c8c8c8c8c8c8c8c8c8c8c94ccc1214ccc120cdc39b8d01f300100813300300a00914a02a66609601429404c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc17c0504c8c8c94ccc188c1940c84c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8cdd79ba7001374e64646464646464646464646464646666600200207a0d40b202244444646464646464646464646464646464646464646464646464646464646464646464a66614a02a66614a0266e212000003153330a50133710900000f8a9998528099b8901f003153330a5013375e07c00e264a66614c0266e1d200200114a226466e241c4dd69854009919bb030ad0100130ad0130ae01001375861580200261480200461480200229405280a5014a02646464a6661560204620042666660520520460020420046eb0c2a404008dd61853808009929998530099b87480000044c8c8c8c8c8c8c8c8c8c94ccc2c004cdc42400000a266ec0dd39999999999999999981901100100d00c00b00a004803826825815023822821816801919b89006001374e0022c616a0205c61660205a66e1d200230ae0137546164020026164020046eb4c2c004004c2c004008c2b804004c2b804008cdc3a40046150026ea8c2b004004c2900401854ccc29804cdc3a400400226464646464646464a66615c0266e2120000031337606e9cccccccccccccccccc0c008000806005805004801c01412c1240a011410c1040ad28119b89001004374e0022c6166020586162020566eb4c2c004004c2c004008c2b804004c2b804008cdc3a40046150026ea8c2b004004c2900401854ccc29804cdc3a4008002264646464646464646464a66616002a6661600266e21200000513371090000018a501337606e9cccccccccccccccccc0c808800806806005805002401c13412c0a811c11410c0b528129998588099b8900600114a2266e24004010dd38008b185a808171859808169bad30b20100130b201002375a616002002616002004615c02002615c0200466e1d200230a801375461580200261480200c2a66614c0266e1d200600113232323232323232323253330b001337109000002899bb0374e646464646464646464646464646464646464646464646464646464646464a66619c0266e21200000113253330cf0100113253330d0013333053036034001022153330d0010291330d401375066e04cdc00100028021986a009ba83370203c04a661a8026ea0cdc000e0029986a009ba83370203404a661a8026ea00612f5c02661a8026ea0cdc08100129986a009ba83370266e00078014010cc35004dd419b8101c025330d401375066e00068014cc35004dd400c25eb8058cccccccc15410412402c02401c01401009054ccc33c054ccc33c040884cccc1480e40dccc14c10412408452808260b19b89003001163253330ce013370e900000089bad30d30130cc010251323253330d001337129000000899b813330a10104200c00a00116375a61a80200261980204a6198020486660e20020140bea6661960266e2008002c4cdc019b833370466e0803408120a09c013370466e0402c080cdc0a4141380201290010b1bae30cf0100130cf01002375c619a02002618a020166eb8c32c04004c32c04008dd71864808009860808049bad30c70100130c701002375a618a02002618a020046eb4c30c04004c30c04008c30404004c30404008c2fc040054ccc2e4040484cc2f404158cc2f404150cc2f404dd40049985e809ba8007330bd0137500a097ae01330bd01054330bd01056330bd01375000e6617a026ea0024cc2f404dd402725eb80dd6985e80800985e808011bad30bb0100130bb01002375a6172020026172020046eb4c2dc04004c2dc040b8dd6985a808169ba70011630b50102e30b30102d3370e90011857009baa30b20100130b201002375a616002002616002004615c02002615c0200466e1d200230a801375461580200261480200c2a66614c0266e1d20080011323232323232323253330ae01337109000002899bb0374e646464646464646464646464646464646464646464646464a66618c02a66618c0266e252000002153330c601337129000000899b8848000cdc00010008a5014a0264646464646464a66619a02002264a66619c0266660a20680640020442661a4026ea0cdc099b8002000a007330d201375066e04cdc000f00480299869009ba833700038014661a4026ea0cdc000d00499869009ba83370003000697ae016333307d333307d333307d333307d03f4890048810033702900002380a80999b814800002404403ccdc0a400001001a0160042a66619a02a66619a02044266660a006e06a660a207e08e0422940412858cdc48118009bad30d00100130d001002375a619c02002619c020046eb4c33004004c8c94ccc32004cdc4000801099191919867809ba8333305500200106205e330cf014c01010000330cf01375066e0ccdc119b813370400e00200402a66e00cdc100e80080125eb80dd69866008011bad30ca010013333305100400301a01805f153330c8013371000400226464646619e02981010000330cf01375066660aa0040020c00bc6619e026ea0cdc199b823370266e08018004008054cdc019b8201b0010024bd701bad30cc01002375a619402002666660a20060080300340ba266198029801010000330cc014c1010000330cc01375000497ae03370666e0800804405ccdc199b8200201001816375a618e020046eb4c31404004c94ccc31004cdc3a400000226466ec0c32804004c32804c32c04004c308040744c8c8c8c94ccc320054ccc32004cdc4a4000006266e25200000114a0266ec0dd419b813330990103a01000e003375066e04ccc264040e803002800458dd69866008009866008011bad30ca0100130c20101d30c20101c375c618e02002618e020046eb8c31404004c2f404160dd71861808009861808011bae30c10100130b901056375c617e02002617e020046eb8c2f404004c2d404150dd6985d80800985d808011bad30b90100130b901002375a616e02002616e020046eb4c2d404004c2d4040b0dd69859808159ba70011630b30102c30b10102b3370e90011856009baa30b00100130b001002375a615c02002615c0200461580200261480200c2a66614c0266e1d200a00113232323232323232323253330b00153330b001337109000003899b8848000014528099bb0374e64646464646464646464646464646464646464646464a66618c0266e21200000113232323253330ca0100113253330cb01333304e03102f00101d1330cf01375066e0406c010cc33c04dd419b81019003330cf01375066e0405c010cc33c04dd419b81015003330cf01375066e0404c0192f5c02c66660f466660f466660f466660f40789110048810033702900002200400319b814800001404003800c03002800854ccc328054ccc328040744cccc1340d00c8cc1380f011007052808238b29998648099b8902000213371203c0022940dd69865008011bad30c801001333304d01601400100e163253330c6013370e900000089bad30cb0130c40101f1323253330c801337129000000899b813330990103a00600400116375a61980200261880203e61880203c6eb8c32404004c32404008dd7186380800985f8082d1bae30c50100130c501002375c6186020026176020b06eb8c30404004c30404008dd7185f80800985b8082b1bad30bd0100130bd01002375a6176020026176020046eb4c2e404004c2e404008dd6985b80800985b808171bad30b50102d374e0022c616a0205c61660205a66e1d200230ae0137546164020026164020046eb4c2c004004c2c004008dd69857008009857008011856008009852008030a9998530099b87480300044c8c8c8c8c8c8c8c8c8c94ccc2c004cdc42400000a266ec0dd39919191919191919191919191919191919191929998618099b88480000044c8c8c8c8c8c8c94ccc328040044c94ccc32c04cccc1380c40bc00407454ccc32c040904cc33c04dd419b8101b007330cf01375066e04cdc080c80280199867809ba8017330cf01375066e0405400ccc33c04dd419b810130094bd70099867809ba83370266e0406c00c01ccc33c04dd419b81019005330cf01375066e0405c00ccc33c04dd400a99867809ba83370202601297ae016333307a333307a333307a03c4890048810033702900002200580499b814800002003c03400854ccc328054ccc328040744cccc1340d00c8cc1380f011007052808238b19b8901e001375a619a02002619a020046eb4c32c04004c32c04008dd69864808009919191919299986400810899866009ba833306d00405f05b330cc014c01010000330cc01375066e0000ccccc1b800800401017d2f5c026619802981010000330cc0137506660da0060ba0b666198026ea0cdc0002199983700080100182ea5eb80cdc080a80119b81016002375a618e020046eb4c31404004cccc12804c04400402c58c94ccc30c04cdc3a400000226eb4c32004c304040684c8c94ccc31404cdc4a4000002266e04ccc258040dc01801000458dd698648080098608080d18608080c9bae30c60100130c601002375c6188020026178020ae6eb8c30804004c30804008dd7186000800985c00800a99985c80809082a082b1bad30bd0100130bd01002375a6176020026176020046eb4c2e404004c2e404008dd6985b80800985b808171bad30b50102d374e0022c616a0205c61660205a66e1d200230ae0137546164020026164020046eb4c2c004004c2c004008c2b804004c2b804008cdc3a40046150026ea8c2b004004c2900401854ccc29804cdc3a401c002264646464646464646464646464646464646464a66617202a6661720266e21200000e153330b9013371090000060a99985c8099b884800002854ccc2e404cdc4240000102a6661720266e240200404cdc48198030a5014a029405280a501323232323232323232323232323253330c70153330c7010011323232323232323253330cf013375e002006266ebc10c01c52819ba548000cc348040e8cc348040e0cc348040d8cc348040d0cc348040c8cc348040c0cc34804cdd2a401c661a40266619c0204e98103d87a80004c0103d8798000330d2013750014661a4026ea008ccc34804dd401099869009ba83370203e900119869009ba801d330d201375003697ae0330d201375066e040b0120cc348040a92f5c060ec002660f21520200261a00200261a002002619e02004619a02002618a0202626660dc05a056026266ec0dd399865809ba800d330cb01375001666196026ea0024cc32c04dd400399865809ba80054bd701ba7012163370e90011863809baa30cb0100130cb01002375a6192020026192020046eb4c31c04004c31c04008dd69862808009862808011bad30c30100130c301002375a6182020026182020046eb4c2fc04004c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc368054ccc36804cdc42400000a2a6661b40266e240a40144cdd79ba6001374c0442940528099299986d8081a09986f809ba83370266e0008801800ccc37c04dd419b81020004330df01375066e00078018cc37c04dd419b8101c004330df013750034661be026ea0014cc37c04ccc36c0400530103d87a80004c0103d87980004bd7009986f809ba833702044008661be026ea0cdc099b80020006003330df01375066e04078010cc37c04dd419b8001c006330df013750034661be026ea0014cc37c04ccc36c04005300103d87a80004c0103d87980004bd70299986d0099b88480080ac4cdc48148020a50163333333305f04b05300c00a00800600400233307d00300d06b333307d01000e00200c3370205a002a6661aa0266e240b000440b04004c8c8c8c94ccc36004cdc42400000220022c66e0c008004cdc101480119b813370466e080a8004030cdc119b82028482827004038cdc0a414138020126eb8c36004004c36004008dd7186b008009867008059bae30d40100130d401002375c61a4020026194020126eb4c34004004c34004008dd69867008009867008011bad30cc0100130cc0100230ca0100130ca0100230c80100153330c20101b1330c60105f330c60105d330c60137500126618c026ea001ccc31804dd402ca5eb804cc31804174cc3180417ccc31804dd400399863009ba8009330c60137500ae97ae0375a618c02002618c020046eb4c31004004c31004008dd69861008009861008011bad30c00100130c001037375a617c0206c2c6eacc2f404004c2f404004c2d004008c2ec040d0c2e4040ccdd6985c00800985c008011bad30b60100130b601002375a6168020026168020046eb4c2c804004c2c804008dd69858008009858008011bad30ae0100130ae010023370e90011854009baa30ac0100130a401006153330a6013370e90080008991919191919191919191919299985900a9998590099b884800002454ccc2c804cdc42400000e266e21200000514a029404cdd81ba73232323232323232323232323232323232323232323253330c8013371090000008991919191919191919299986880800899299986900999982a81c01b00081109986b009ba83370266e04080014024cc35804dd419b813370203c00600e661ac026ea0cdc080e0029986b009ba833702034006661ac026ea0cdc080c005a5eb8058cccc20404cccc20404cccc20404cccc2040410d22010048810033702900002580680599b814800002805404c01004403c00854ccc344054ccc344040884cccc1500ec0e4cc15410c12c08452808270b19b89023003375a61a80200261a8020046eb4c34804004c34804008dd69868008009868008011bad30ce010013232323232323253330cf0133710002004264661a8026ea0ccc1d400419c18ccc35005301010000330d401375066e0401c004cc35004dd419b8000633330760050040010674bd70199999982b8030028020018130120330a9998678099b88002001132330d4014c01010000330d40137506660ea0020ca0c6661a8026ea0cdc0003999983b0020028008329986a009ba83370200c00297ae033333330570050060030040240260641330d3014c1010000330d3014c1010000330d301375000c661a6026ea00152f5c066e08010094cdc100201119b81018002337020320046eb4c33004008dd6986500800999982780b00a0008070b1929998640099b87480000044dd69866809863008108991929998650099b89480000044cdc099984d8081e0030020008b1bad30ce0100130c60102130c601020375c6196020026196020046eb8c32404004c30404170dd71863808009863808011bae30c50100130bd0105a375c6186020026186020046eb8c30404004c2e404160dd6985f80800985f808011bad30bd0100130bd01002375a6176020026176020046eb4c2e404004c2e4040c0dd6985b808179ba70011630b70103030b50102f3370e90011858009baa30b40100130b401002375a6164020026164020046eb4c2c004004c2c004008dd69857008009857008011856008009852008030a9998530099b87480500044cdd81ba7323232323232323232323232323232323232323253330ba0153330ba013371290000010a99985d0099b89480000044cdc42400066e000080045280a501330be01375066e00050008cc2f804dd419b80012001330be01375066e00040008cc2f804dd419b8000e001330be01375001897ae01633308a0102b00500353330b8013306900800613370200206420026661100205200e00a6eb8c2ec04004c2ec04008dd7185c808009858808271bae30b70100130b701002375c616a02002615a020986eb4c2cc04004c2cc04008dd69858808009858808011bad30af0100130af01002375a615a02002615a020486eb4c2ac0408cdd38128b1852008028b1854808009854808011bad30a70100130a70100230a50100130a50100230a30100130a30100230a10100130a101002309f01001309f01002309d01001309d01002309b01001309b01002309901001309101002303b0013303e06e0013095010013095010023756612602002612602004612202002611202002611e02002611e02002610c02008611a0200a6eb4c22c04010c22c04014c2240401088888888888888888c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc29404cdc4240000022646464a666150020022a66615002a666150026464646464646464a6661600266e1d200000113375e05c00e2a6661600266ebc0b801c4cc1600100b4528185700800985980800985580815985880800985880800985800801185700800985300814899191929998558099b87480000044cdd79858009854808011ba63037003132323232323232323375e6e9802cdd31999999981c81a8158020011bae30b801001375c61700261720200201e01c61600200a6eb8c2d804004c2d804008dd7185a00800985600801185780801185680800a99985580813899bb002502413376004804a61520200266664444a66615a02a66615a0266e3c01122010013371e0069110014a0264646464a666168020042a6661620205a266e952000330b501374c6616a0266ec1301014000374c6616a0266ec13001014000375066e04004cdc0014806a5eb7bdb180cc2d404cdd81ba9006374c6616a0266ec0dd48029ba800c4bd6f7b63025eb7bdb1812f5c02c26464a66616c020042646464a66617202004008264a666174020022646464a66617402a66617402a666174026661740206c94128899b8f00500f14a0266e3c0040385280a99985d0099b8801600213374a90001985f009ba6330be0133760981014000374c6617c0266ec13001014000375066e00cdc080501900aa5eb7bdb180cc2f804cdd81ba9005374c6617c0266ec0dd48009ba83370200402c97adef6c604bd6f7b63025eb8054ccc2e804cdc380100b099ba548000cc2f804dd31985f0099bb04c1014000374c6617c0266ec13001014000375066e00cdc080501900aa5eb7bdb1812f5bded8c097ae01614c103d87a8000375c6174020046eb4c2e804004c2f00400c014c2f004008dd7185b008011bab30b60100130b80100400114c103d87a800030b701002375a616402616a026eacc2c804008c2d404008c2cc04004c0e40bc5300103d87a8000375c6068614e020466eb8c0b8c29c0408cdd7181a1853808111bae302e30a7010223756605a614c02052294054ccc2a0040904cc2b004dd419b813370003200800466158026ea0cdc080b80199856009ba83370002a00866158026ea0cdc080980199856009ba80114bd70099856009ba83370203200666158026ea0cdc099b80017004002330ac01375066e0405400ccc2b004dd419b80013004330ac01375002297ae016153330a80153330a80101b1333302b0280273302c02a02002914a020382c603200466609600400e036666609601401000200c2c64a66614a0266e1d20000011375a61540261460204026464a66614e0266e2520000011337026660f005200c0080022c6eb4c2ac04004c28c04080c28c0407cdd71854008009854008011bae30a601001309e01007375a6148020026148020046eb4c28804004c28804008dd6985000800985000801184f00800a99984c0080a09984e008091984e009ba80093309c01375000e66138026ea003d2f5c02661380202266138026ea001ccc27004dd40049984e009ba800e4bd701bad309c01001309c01002375a6134020026134020046eb4c26004004c26004008dd6984b00800984b008021bad309401003222232323232323232323232533308b013370e900000088020a999845808020998198028068a50308901001308e0100130860100b5333087013375e01400a266ebcdd30041ba600314a06116020026116020046eacc22404004c22404008c21c04004c1fc00488cccc0b8009221004881003370400290009184080984100800911111112999841009981980300289999819199981900424410048810033702900019b800070020040030011533308201330330040031333303233330320084881004881003370200200e00c00a66e052000002133330323333032333303200848810048810033702900000380300299b814800000801000c0048888cdd81ba83370666e08008010004dd419b8333704004006002444444464646466e0ccdc0980799b813370400200266e08cdc12401000466e08cdc124141380201066e04cdc100300499b8200500a00133704900200119b803370466e08014008cdc000300419b820043370266e0801d20a09c013370400401266e0800c004cdc0a41413802002444446464646466ec0dd419b81300d33702601c00266e08cdc1001a4141380266e0520a09c01005001375066e08008cdc0a4141380200a66e08cdc099b824801120a09c0100400333704900219b800060043370466e0920083370000a00666e04cdc1002980580219b823370400c00800666e08cdc0002001001911119299983d99b87480080045200013370666e08cdc10028019bad30800130790023370466e0801120a09c01482827004c1e40048c1ec0048c8cc004004008894ccc1e800452f5bded8c02660f66466ec0c1e4004c1e8004c1f0004cc008008c1f400494ccc1d0cdc4000a40002c2a6660e866e1c005200014800054ccc1d0cdc3800a4004290010a99983a19b87001480105200213232333001001003002222533307833710002004266600600600266e0ccdc019b83005001001480104008cdc019b830014801120022337040020026eb0c1d8004c1d8008dd6183a000983a001183900098390011bad30700013070002375a60dc00260dc00460d800260d800460d400260d400460d000260c06666660200a400200a0bc940010c198004c198004c17400c58c18c0c4c188078c1840784c94ccc180c18c0684c8c94ccc188c1940e04c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc1eccdc3a402460f400a26464646464646464a6661060266e1d2000308201058132325333085015333085013371090000068a9998428099b884800009c54ccc21404cdc48138068a9998428099981600a8098140a999842809929998430099b874800800452889919b89051375a6110026466ec0c23404004c23404c23804004dd61846008009842008061842008058a9998428099baf01100315333085013371090000028a99984280998200238048a999842809824800899b89371a00290030a5014a029405280a5014a029405280a50132323232323232323232323232323232323232323232323232323232323232323253330a6013371090000008991929998540099b8902800213375e6e98004dd301f8a503333057333305733330570434890048810033702900002480480399b814800000801400c004ccc0780040800a858c94ccc29804cdc3a400000226eb4c2ac04c290040a04c8c94ccc2a004cdc4a4000002266e04ccc1e411002802000458dd69856008009852008141852008139bae30a90100130a901002375c614e02002613e0200a6eb8c29404004c29404008dd7185180800984d80801299984e0080508010802299984d8080608038802984f80800984f80801184e80800984a80805984d80800984d80801184c8080098488080419b8748008c24c04dd5184b80800984b8080098470080319b8748008c24004dd5184a00800984a008009845808021982900319b81304500648008c24004014cc140038cdc0982180724004611c0201a600200244446464646464a666126020082002266660120120020080046464646464646464646464646464646464646464646464646464646464646464a66615e0266ebc07400c4c8c8c8c8c8c94ccc2d404cdc42400005a26464a66616e0266e212000002153330b70153330b701009153330b7013370e66e04cdc000d0178008098a99985b8099b87337020300040222a66616e0266e1ccdc000b017807899b873370202800401a29405280a50153330b7013370e66e0406800804c54ccc2dc04cdc399b813370003005e0020222a66616e0266e1ccdc080b001007899b873370002805e01a29405280a501002161633305b02e00201e333305b00500302d00116375a6172020026172020046eb4c2dc04004c2dc04008dd6985a80800a99985780800899859809ba8012330b301375002066166026ea006d2f5c0266166026ea0040cc2cc04dd400919859809ba80194bd700b19b8748008c2bc04dd518598080098598080118588080098548080f1bad30af0100130af01002375a615a02002615a020046eb4c2ac04004c2ac04024dd69854808041bad30a80100130a801002375a614c02002614c020046eb4c29004004c29004010dd69851008019bac30a10100130a1010023758613e02002613e02004613a02002613a020046eb4c26c04004c26c04008dd6984c80800984c80801184b80800984b80800984b00800984680802184a008021849008019849008019848008011919199980080080182482d911119191919191929998488099baf374e00a980101800015333091015333091013375e9801018000374e006266ebd301018000374e00229404cc25404ccc02c0180100092f5c02c26612a0266601600c008004666601401400a006002612c0200c61280200a61280200a61240200861240200861200200644466666606e0f2611c02611e02610e0200600410a02944004ccc10c0052f5c0446608c0026609a0920042c6eb8c22404004c2040416058c21c04004c1fcc21804014dd69842808009842808011841808009841808011bac308101001307900516307f001307f002375a60fa00260fa00460f600260f600460f200260f200460ee00260ee00460ea00260ea00260e800260e600260d400460280026602e08e0086eacc1b8004c1b8004c194028c1ac004c1ac008dd598348009834800983000098330009833000982e8018b1bad3063037306204716306101922232533305f3370e90010008a4000266e0ccdc119b82004003375a60c860ba00466e0920a09c01482827004c1740048888c8c8cdc199b820010053370066e0920a09c010060013370400200666e0520a09c0100122232323232323232323253330653370e900000088010a9998328010998068028058a5030630023375e01400c60ce00260be01060ca00260ca00260c800460c400260b40024466ebc004c94ccc16ccdc3a40000022980103d87980001533305b3370e9001000899ba548008cc17cc180c16400d2f5c0266e9520043305f37526e50dd99830182c801a5eb80c1640088c94ccc164cdc3a40000022646464646464646464646464646464646464a6660dc60e2004264646464646464649319299983999b87480000044c8c94ccc1e0c1ec0084c92632375a60f00046eb4c1d800458c8cdd8183d000983d183d8009bac30790013071009153330733370e90010008a99983b18388048a4c2c2c60e201064a6660e466e1d200000113232323232323232533307d308001002132498c09401458cdc3a400460f46ea8c1f8004c1f8008dd6983e000983e001183d000983d00119b8748008c1d0dd5183c00098380060a99983919b87480080044c8c8c8c8c8c94ccc1ecc1f80084c926302300316375a60f800260f800460f400260f400466e1d20023074375460f000260e00182a6660e466e1d200400113232323232323232533307d308001002132498c09401458dd6983f000983f0011bad307c001307c002307a001307a0023370e9001183a1baa3078001307000c153330723370e900300089919191919191919299983e98400080109924c604a00a2c66e1d2002307a375460fc00260fc0046eb4c1f0004c1f0008c1e8004c1e8008cdc3a400460e86ea8c1e0004c1c003054ccc1c8cdc3a40100022646464646464a6660f660fc0042649319299983c99b87480000044c8c8c8c94ccc20004c20c0400852616375a6102020026102020046eb4c1fc004c1dc01854ccc1e4cdc3a4004002264646464a666100026106020042930b1bad308101001308101002375a60fe00260ee00c2c60ee00a2c66e1d20023078375460f800260f80046eb4c1e8004c1e8008c1e0004c1c003054ccc1c8cdc3a401400226464646464646464a6660fa6100020042649318130038b19b8748008c1e8dd5183f000983f0011bad307c001307c002375a60f400260f400460f000260e00182a6660e466e1d200c00113232323232323232533307d308001002132498c09801458cdc3a400460f46ea8c1f8004c1f8008dd6983e000983e001183d000983d00119b8748008c1d0dd5183c00098380060a99983919b87480380044c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc20c04c2180400852616375a6108020026108020046eb4c20804004c20804008dd69840008009840008011bad307e001307e002375a60f800260f80046eb4c1e8004c1e8008cdc3a400460e86ea8c1e0004c1c003054ccc1c8cdc3a4020002264646464646464646464a6660fe6104020042649318140048b19b8748008c1f0dd51840008009840008011bad307e001307e002375a60f800260f80046eb4c1e8004c1e8008c1e0004c1c003054ccc1c8cdc3a40240022646464646464a6660f660fc0042646493181200219837802919299983d19b87480000044c8c8c8c94ccc20404c210040084c9263035003163370e9001183f1baa308201001308201002308001001307800216307800116375a60f800260f800460f400260f40046eb0c1e0004c1c003054ccc1c8cdc3a40280022a6660ea60e00182930b0b18380059813806180c806981e007180b807981d00819299983619b87480000044c8c94ccc1c4c1d000852616375c60e400260d40242a6660d866e1d20020011323253330713074002149858dd7183900098350090a99983619b87480100044c8c94ccc1c4c1d000852616375c60e400260d40242a6660d866e1d20060011323253330713074002149858dd7183900098350090b18350088b183780098378011bad306d001306d002306b001306b0023069001306900230670013067002306500130650023063001306300230610013061002305f001305700216305700123253330583370e90000008a99982d982b0010a4c2c2a6660b066e1d200200113232533305d3060002149858dd7182f000982b0010a99982c19b87480100044c8c94ccc174c18000852616375c60bc00260ac0042c60ac002464a6660ae66e1d200000113232533305c305f002149858dd6982e800982a8010a99982b99b87480080044c8c94ccc170c17c00852616375a60ba00260aa0042c60aa002464a6660ac66e1d200000113232533305b305e002149858dd6982e000982a0010a99982b19b87480080044c8c94ccc16cc17800852616375a60b800260a80042c60a80024464a6660ac66e1d20040011305b3054002153330563370e9001000899191980080080291299982e0008b099191919299982e99b8f0070021001133006006003305e003375c60b800460c000460bc0026eb8c16cc15000858c150004888888c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc240054ccc240040e84cdc38118068a5115333090015333090013375e0520262a6661200266ebc0a40f854ccc24004cdd781b8188a9998480099baf02701115333090013375e04a01e2a6661200266e1c07401c54ccc24004cdc380d8028a9998480099baf019003153330900101710011333090010014a09445280a5014a029405280a5014a029404c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc294054ccc29404cdd79ba6002374c0942a66614a0266ebcdd30009ba604413370e66e0400c010cdc081c0110a5014a0266e952000330a90103c330a90103a330a90100c330a90137506660a806409c05866152026ea0ccc1500c01380b0cc2a4040b8cc2a404dd399854809ba8036330a901375006866152026ea0020cc2a404dd400319854809ba80384bd7019854809ba7330a901375004066152026ea0078cc2a404dd400399854809ba8005330a901375004497ae04bd700b199982a199982a199982a199982a199982a25eb7bdb18122010048810048302a2941013d2201034d5350004800804c04401803c03401013c030008cccc14ccccc14ccccc14ccccc14ccccc14d2f5bded8c09110048810048302a294101392201034d5350004800804804001803803001013802c008ccc1cc104134028ccc1c8118130024ccc1c40fc02c024ccc1c0110028020dd69850008011bad309e01001533309c013304d00b0091337606ea0cdc080124181514a086ea0cdc0800a4181514a08266ec0dd40011ba800133306c03a00a00833306b03f0090073374a90001984e809ba90443309d01375200297ae0304d3304e304d3304e007005304d3304e003001375c6138020026138020046eb8c26804004c248040a4dd7184c00800984c008011bae309601001308e0102716163370e90011848009baa309401001309401002309201001309201002375a6120020026120020046eb4c23804004c23804008dd69846008009846008011bad308a01001308a01002375a611002002611002004610c02002610c0200461080200261080200461040200260f4004605a002609802e66e1d2002307a375460fc00260fc00460f800260f80046eb4c1e8004c1e8008dd6983c000983c0011bad30760013076002375a60e800260e80046eb4c1c8004c1c8008c1c0004c1c0008c1b8004c1b8008c1b0004c190008c05c004c0d801cc1a0004c1a0008dd5983300098330011832000982e005183100098310011bab30600013060002305e0013056005222325333055333008001482807d200a100116533305400113253330553370e9001000880209919299982b999805000a4120069000099b8000100616375a60b600260a600660a600420064444a6660a866e1c00520001004132323300100100622533305a00113305b337606ea4018dd3001a5eb7bdb1804c8c8c8c94ccc16ccdd79980780500126103d879800013305f337606ea4028dd30038028a99982d99b8f00a00213232533305d3370e900000089983099bb0375201860c460b600400a200a60b600264a6660b8a6660be00229445280a60103d87a800013374a9000198301ba60014bd70191980080080111299983000089983099bb037520166ea00292f5bded8c0264646464a6660c266ebccc05403c00930103d8798000133065337606ea403cdd40070028a99983099b8f00f0021323253330633370e900000089983399bb0375202260d060c200400a200a60c200264a6660c466e1c005200014c103d87a800013374a9000198331ba80014bd7019b8000100e133065337606ea4008dd4000998030030019bad3062003375c60c000460c800460c40022660be66ec0dd48011ba600133006006003375660b80066eb8c168008c178008c170004c8c8008c8cc004004008894ccc168004526132533305b00114984c8c8c8c8c8c8c94ccc17ccdc3a4000002266014014660c600c00a2c60ba002660220040026eb8c17400cdd7182e0019830001982f001182e801182e8009982c19bb037520046ea00052f5bded8c044a6660a266e3c00922010013371e0029110014a0464a6660a066e1d2000001132323232323232323232323232323232323232325333067306a002132323232498c17c018c074044c070048c0cc04c58cdc3a400460c86ea8c1a0004c1a0008c198004c198008dd6983200098320011bad30620013062002375a60c000260c00046eb4c178004c178008dd6982e000982e001182d000982d001182c000982c001182b00098270010b1827000911299982819b890030021337120020062940894ccc138cdc80010008a60103d87980001533304e3371e0040022980103d87a800014c103d87b8000237260024466e280080048c94ccc12ccdc3a4000002264646464a6660a460aa0042930b1bae30530013053002375c60a200260920042c6092002609c0142c600200244a66609600229000099b8048008cc008008c138004c0040048894ccc1280084cdd79ba70014c10180001533304a00114a02666006006609a004609a00266600203497ae022330040013300b00500222232323330010010040022225333049337100029000080109998018019980299b8e00700100233702002900119b81371a0069001111982380080119801817119191919191919299982419982419baf00300d4a09444ccc120cdd7800821a504a22940c130004c110004c128004c108004c120004c120004c0fc004cc0080a48cdd79822981f1822981f00081d99800816119baf3044303d3044303d30443045303d00103a22323300100100322533304400114bd70099192999821980280109982380119802002000899802002000982400118230008b119299981f19b88480000044c8ccc004005221400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000480008894ccc104cdc48020008a511323253330433370e00290010a50133300500533714666e312000002004337169001199b8c337000049001241000200866e0000d20023371c00600266e380140045281b8d001330010060163001001222533303c33712900a0008999801801982118211821182118211821182118211821182100119b81001480504cc010008004c0040048894ccc0e8cdc4800a40002607e0042666006006608000466e0400520023232323232323232533303e3370e9001181e80189919299982019b8748008c0fc00c4c8c94ccc108cdc499b810010033370466e092014481e120d00f13370066e0ccdc0800801a40080062c6eb4c118004c0f800c58dd69822000981e0018b1821000981d0019820000981c001981f000981f001181e000981a00c1bac303a00130320013253330343370e90001819800899191919191919191919299981f19b8733300f00303a489044d53475300480084c8c8008c94ccc100cdc3a40000022646464646464646464646464a66609e60a4004264646464646493180f803180f003980e804180e004980d805198218059180d8008b18280009828001182700098270011826000982600118250009825001182400098240011bac3046001303e00216303e00130100011630420013042002375660800026080002606e002607a002607a0026068002607400260640022c646600200204044a666070002298103d87a80001323253330373232323232323232533303f3370e9001000899b8f375c6088607a0040762940c0f4004c108004c0e8004c100004c0e0004c0f8004c0f8004c0d40084cdd2a40006607600497ae0133004004001303c002303a00123253330343370e9000000899191919299981d981f0010991924c64a66607466e1d200000113232533303f3042002132498c02c00458c100004c0e000c54ccc0e8cdc3a40040022a66607a60700062930b0b181c00118040018b181e000981e001181d00098190010b1819000919299981999b87480000044c8c94ccc0e0c0ec0084c92630050011630390013031002153330333370e90010008991919191919299981e181f8010a4c2c6eb4c0f4004c0f4008dd6981d800981d8011bad3039001303100216303100123253330323370e900000089919299981b981d0010a4c2c6eb8c0e0004c0c000854ccc0c8cdc3a400400226464a66606e60740042930b1bae3038001303000216303000122232323253330353370e90010008a400026eb4c0e8c0cc008c0cc004c94ccc0d0cdc3a4004002298103d87a8000132323300100100222533303a00114c103d87a8000132323232533303b3371e014004266e9520003303f375000297ae0133006006003375a60780066eb8c0e8008c0f8008c0f0004dd5981c98190011819000991980080080211299981b8008a6103d87a800013232323253330383371e010004266e9520003303c374c00297ae0133006006003375660720066eb8c0dc008c0ec008c0e40048c94ccc0c0cdc3a40080022606a605c0042c605c0026eb0c0c8004c0c8008c0c0004c0c0008dd7181700098170011bac302c001302c002375a6054002604403c6eacc0a0004c0a0004c09c008dd618128009812801181180098118011bab3021001302100130200023756603c002603c002603a0046eb0c06c004c06c008dd6180c800980c8011bac3017001300f0053015001300d00116301300130130023011001300900414984d958c94ccc02ccdc3a4000002264646464646464646464a6660306036004264646493198070019180800099299980b99b87480000044c8c94ccc070c07c00852616375c603a002602a00a2a66602e66e1d20020011533301a301500514985858c054010cc03001c8dd68008b1bac3019001301900230170013017002375c602a002602a0046eb0c04c004c04c008dd6980880098048028b18048021119198008008019129998080008a4c26466006006602800460066024002464a66601466e1d200000113232533300f3012002149858dd6980800098040010a99980519b874800800454ccc034c02000852616163008001375c0024600a6ea80048c00cdd5000ab9a5573aaae7955cfaba05742ae89", + "hash": "0dd823e4426270dfc30d2a3db68a81f2278744427bf6b80189444ce3" }, { "title": "sample_multi_sign.withdraw", @@ -138,16 +209,8 @@ "$ref": "#/definitions/Data" } }, - "parameters": [ - { - "title": "admin_pid", - "schema": { - "$ref": "#/definitions/ByteArray" - } - } - ], - "compiledCode": "5904a60100003232323232323232322322253330073370e900018030008a99980399191919191919191919191919191919299980b99b8748010c0580344c8c8c8c94ccc06ccdc3a40006034002264646464646464646464646464a66605066e1d2004302700313232533302a3375e02466e9520003302e0034bd700991919198008008011129998188008a51132325333030323300100101b22533303500114a026464a66606866e3c008018528899802002000981c8011bae303700113300400400114a0606a0046eb8c0cc004dd61818181480119299981599b87480000044c8c94ccc0c0c0cc0084c926323300100100222533303200114984c8cc00c00cc0d8008dd7181a0008b1bac3031001302900216302900116302e001302600316302c0013024004302a001302a00130290023027001301f00130250013025001301c0023232323232323232325333029302c0021323232323232323232323253330313370e9001181800189919299981999b8748008c0c800c4c8c94ccc0d54ccc0d4cdc3807240042a66606a66e240040344cdc480699b8000348203036eb70c105280a501337600286ea000458dd6981c80098188018b1bad3037001302f003163035001302d0033033001302b00330310013031002302f00130270153232330010010022232533302c533302c337129030000899b89001481c85280a99981619b87002480004cdc0800a40c0266e00cdc11980180199b810024800920143370200290300b19b8e005001337026e340092002375a60520046eb8c09c00458c0a8004cc02c004080dd5981400098140011813000980f00098120009812000980d8009810800980c8008b191980080080711299980f8008a6103d87a800013232533301e3232323232323371090001919198008008011129998150008a4000266e01200233002002302d0013300b001020375660500026050002603e002604a002604a0026038004266e952000330220024bd7009980200200098118011810800911919299980e99b874800800452f5bded8c026eacc088c06c008c06c004c8cc00400400c894ccc080004530103d87a800013232323253330213371e00e004266e95200033025374c00297ae0133006006003375660440066eb8c080008c090008c088004c074004c05403458dd6180d800980d801180c800980c800980c000980b800980b000980a800980a0011bac301200130120013009003300f001300f002300d001300500114984d9584c88c94ccc028c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc060cdc3a4004602e0162646464646600200200444a66604000229444c8c94ccc07cc8cc004004024894ccc09000452809919299981199b8f00200614a226600800800260500046eb8c0980044cc01001000452818120011bae30220013758603e002602e028602c0162c6eb0c070004c070004c06c004c068004c064004c060004c05c004c058004c054004c03000cc048004c048008c040004c0200085261365632533300a3370e9000000899192999807980900109924c646600200200444a66602200229309919801801980a8011bae30130011637586020002601000a2c60100086018600a0026eb80048c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d11", - "hash": "32d6df8e23b7325cc95b4f4a928f623cb37cdc998802b1f30dc5ae39" + "compiledCode": "5903170100003232323232323232322253330053370e900018020008a999802991919191919191919191919191919299980a19b8748010c04c0304c8c94ccc058cdc3a4000602a00226464a66603066e1d200230170011323232533301b3370e9000180d0008991919191919191919299981219b8748010c08c0044c8c8c8c8c8cc004004008894ccc0b4004528899192999816191980080080d1129998188008a501323253330303371e00400c29444cc010010004c0d4008dd718198008998020020008a503031002375c605e0026eb0c0b0c094008c94ccc09ccdc3a400000226464a666058605e0042649319198008008011129998170008a4c2646600600660640046eb8c0c000458dd6181680098128010b1812800981500098110008b181400098140009813800980f00098120009812000980d8009810800980c8008b191980080080811299980f8008a6103d87a800013232533301e323232323232323253330263370e9001000899b8f375c6056604800401a2940c090004c0a4004c084004c09c004c07c004c094004c094004c0700084cdd2a40006604400497ae013300400400130230023021001375c603c002602c0022c603800260280022c603400260240182c6eb0c060004c060004c05c004c058004c054004c050004c04c004c048008dd618080009808000980380198068009806801180580098018008a4c26cac264464a6660106464646464646464646464646464a66602c66e1d2002301500b13232323300100100222533301d00114a226464a666038646600200201044a66604200229404c8c94ccc080cdc78010030a511330040040013025002375c60460022660080080022940c084008dd7180f8009bac301c00130140131637586034002603400260320026030002602e002602c002602a00260280026026002601400660200026020004601c002600c00429309b2b19299980419b87480000044c8c94ccc034c0400084c926323300100100222533300f00114984c8cc00c00cc04c008dd718088008b1bac300e0013006005163006004300a3003001230053754002460066ea80055cd2ab9d5573caae7d5d02ba157441", + "hash": "128cacae8708a0f45d04b6b15e7b72b7ee76013704bbfaf4b91503c2" }, { "title": "sample_multi_sign.spend", @@ -163,19 +226,28 @@ "$ref": "#/definitions/RedeemerWrapper$Data" } }, - "parameters": [ - { - "title": "admin_pid", - "schema": { - "$ref": "#/definitions/ByteArray" - } - } - ], - "compiledCode": "5904a60100003232323232323232322322253330073370e900018030008a99980399191919191919191919191919191919299980b99b8748010c0580344c8c8c8c94ccc06ccdc3a40006034002264646464646464646464646464a66605066e1d2004302700313232533302a3375e02466e9520003302e0034bd700991919198008008011129998188008a51132325333030323300100101b22533303500114a026464a66606866e3c008018528899802002000981c8011bae303700113300400400114a0606a0046eb8c0cc004dd61818181480119299981599b87480000044c8c94ccc0c0c0cc0084c926323300100100222533303200114984c8cc00c00cc0d8008dd7181a0008b1bac3031001302900216302900116302e001302600316302c0013024004302a001302a00130290023027001301f00130250013025001301c0023232323232323232325333029302c0021323232323232323232323253330313370e9001181800189919299981999b8748008c0c800c4c8c94ccc0d54ccc0d4cdc3807240042a66606a66e240040344cdc480699b8000348203036eb70c105280a501337600286ea000458dd6981c80098188018b1bad3037001302f003163035001302d0033033001302b00330310013031002302f00130270153232330010010022232533302c533302c337129030000899b89001481c85280a99981619b87002480004cdc0800a40c0266e00cdc11980180199b810024800920143370200290300b19b8e005001337026e340092002375a60520046eb8c09c00458c0a8004cc02c004080dd5981400098140011813000980f00098120009812000980d8009810800980c8008b191980080080711299980f8008a6103d87a800013232533301e3232323232323371090001919198008008011129998150008a4000266e01200233002002302d0013300b001020375660500026050002603e002604a002604a0026038004266e952000330220024bd7009980200200098118011810800911919299980e99b874800800452f5bded8c026eacc088c06c008c06c004c8cc00400400c894ccc080004530103d87a800013232323253330213371e00e004266e95200033025374c00297ae0133006006003375660440066eb8c080008c090008c088004c074004c05403458dd6180d800980d801180c800980c800980c000980b800980b000980a800980a0011bac301200130120013009003300f001300f002300d001300500114984d9584c88c94ccc028c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc060cdc3a4004602e0162646464646600200200444a66604000229444c8c94ccc07cc8cc004004024894ccc09000452809919299981199b8f00200614a226600800800260500046eb8c0980044cc01001000452818120011bae30220013758603e002602e028602c0162c6eb0c070004c070004c06c004c068004c064004c060004c05c004c058004c054004c03000cc048004c048008c040004c0200085261365632533300a3370e9000000899192999807980900109924c646600200200444a66602200229309919801801980a8011bae30130011637586020002601000a2c60100086018600a0026eb80048c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d11", - "hash": "32d6df8e23b7325cc95b4f4a928f623cb37cdc998802b1f30dc5ae39" + "compiledCode": "5903170100003232323232323232322253330053370e900018020008a999802991919191919191919191919191919299980a19b8748010c04c0304c8c94ccc058cdc3a4000602a00226464a66603066e1d200230170011323232533301b3370e9000180d0008991919191919191919299981219b8748010c08c0044c8c8c8c8c8cc004004008894ccc0b4004528899192999816191980080080d1129998188008a501323253330303371e00400c29444cc010010004c0d4008dd718198008998020020008a503031002375c605e0026eb0c0b0c094008c94ccc09ccdc3a400000226464a666058605e0042649319198008008011129998170008a4c2646600600660640046eb8c0c000458dd6181680098128010b1812800981500098110008b181400098140009813800980f00098120009812000980d8009810800980c8008b191980080080811299980f8008a6103d87a800013232533301e323232323232323253330263370e9001000899b8f375c6056604800401a2940c090004c0a4004c084004c09c004c07c004c094004c094004c0700084cdd2a40006604400497ae013300400400130230023021001375c603c002602c0022c603800260280022c603400260240182c6eb0c060004c060004c05c004c058004c054004c050004c04c004c048008dd618080009808000980380198068009806801180580098018008a4c26cac264464a6660106464646464646464646464646464a66602c66e1d2002301500b13232323300100100222533301d00114a226464a666038646600200201044a66604200229404c8c94ccc080cdc78010030a511330040040013025002375c60460022660080080022940c084008dd7180f8009bac301c00130140131637586034002603400260320026030002602e002602c002602a00260280026026002601400660200026020004601c002600c00429309b2b19299980419b87480000044c8c94ccc034c0400084c926323300100100222533300f00114984c8cc00c00cc04c008dd718088008b1bac300e0013006005163006004300a3003001230053754002460066ea80055cd2ab9d5573caae7d5d02ba157441", + "hash": "128cacae8708a0f45d04b6b15e7b72b7ee76013704bbfaf4b91503c2" } ], "definitions": { + "Bool": { + "title": "Bool", + "anyOf": [ + { + "title": "False", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "True", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, "ByteArray": { "dataType": "bytes" }, @@ -198,6 +270,87 @@ "$ref": "#/definitions/Int" } }, + "List$Option$Int": { + "dataType": "list", + "items": { + "$ref": "#/definitions/Option$Int" + } + }, + "List$aiken/transaction/credential/Address": { + "dataType": "list", + "items": { + "$ref": "#/definitions/aiken~1transaction~1credential~1Address" + } + }, + "Option$ByteArray": { + "title": "Optional", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/ByteArray" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Option$Int": { + "title": "Optional", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Option$aiken/transaction/credential/Referenced$aiken/transaction/credential/Credential": { + "title": "Optional", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/aiken~1transaction~1credential~1Referenced$aiken~1transaction~1credential~1Credential" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, "RedeemerWrapper$Data": { "title": "Wrapped Redeemer", "description": "A redeemer wrapped in an extra constructor to make multi-validator detection possible on-chain.", @@ -251,6 +404,27 @@ } ] }, + "aiken/transaction/credential/Address": { + "title": "Address", + "description": "A Cardano `Address` typically holding one or two credential references.\n\n Note that legacy bootstrap addresses (a.k.a. 'Byron addresses') are\n completely excluded from Plutus contexts. Thus, from an on-chain\n perspective only exists addresses of type 00, 01, ..., 07 as detailed\n in [CIP-0019 :: Shelley Addresses](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0019/#shelley-addresses).", + "anyOf": [ + { + "title": "Address", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "payment_credential", + "$ref": "#/definitions/aiken~1transaction~1credential~1Credential" + }, + { + "title": "stake_credential", + "$ref": "#/definitions/Option$aiken~1transaction~1credential~1Referenced$aiken~1transaction~1credential~1Credential" + } + ] + } + ] + }, "aiken/transaction/credential/Credential": { "title": "Credential", "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", @@ -336,7 +510,7 @@ "title": "AuthenRedeemer", "anyOf": [ { - "title": "MintFactoryAuthen", + "title": "DexInitialization", "dataType": "constructor", "index": 0, "fields": [] @@ -389,88 +563,156 @@ } ] }, - "amm_dex_v2/types/OrderSpendingRedeemer": { - "title": "OrderSpendingRedeemer", + "amm_dex_v2/types/GlobalSetting": { + "title": "GlobalSetting", "anyOf": [ { - "title": "OrderSpendingRedeemer", + "title": "GlobalSetting", "dataType": "constructor", "index": 0, "fields": [ { - "title": "pool_input_index", - "$ref": "#/definitions/Int" + "title": "batchers", + "$ref": "#/definitions/List$aiken~1transaction~1credential~1Address" + }, + { + "title": "pool_fee_updater", + "$ref": "#/definitions/aiken~1transaction~1credential~1Address" + }, + { + "title": "fee_sharing_taker", + "$ref": "#/definitions/aiken~1transaction~1credential~1Address" + }, + { + "title": "pool_stake_key_updater", + "$ref": "#/definitions/aiken~1transaction~1credential~1Address" + }, + { + "title": "pool_dynamic_fee_updater", + "$ref": "#/definitions/aiken~1transaction~1credential~1Address" + }, + { + "title": "admin", + "$ref": "#/definitions/aiken~1transaction~1credential~1Address" } ] } ] }, - "amm_dex_v2/types/PoolRedeemer": { - "title": "PoolRedeemer", + "amm_dex_v2/types/PoolBatchingRedeemer": { + "title": "PoolBatchingRedeemer", "anyOf": [ { - "title": "Batching", + "title": "PoolBatchingRedeemer", "dataType": "constructor", "index": 0, "fields": [ { - "title": "input_indexes", - "$ref": "#/definitions/List$Int" + "title": "batcher_index", + "$ref": "#/definitions/Int" }, { "title": "orders_fee", "$ref": "#/definitions/List$Int" }, { - "title": "license_index", - "$ref": "#/definitions/Int" + "title": "input_indexes", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "pool_input_indexes_opt", + "$ref": "#/definitions/Option$ByteArray" + }, + { + "title": "vol_fees", + "$ref": "#/definitions/List$Option$Int" } ] - }, + } + ] + }, + "amm_dex_v2/types/PoolDatum": { + "title": "PoolDatum", + "anyOf": [ { - "title": "MultiRouting", + "title": "PoolDatum", "dataType": "constructor", - "index": 1, + "index": 0, "fields": [ { - "title": "license_index", + "title": "pool_batching_stake_credential", + "$ref": "#/definitions/aiken~1transaction~1credential~1Referenced$aiken~1transaction~1credential~1Credential" + }, + { + "title": "asset_a", + "$ref": "#/definitions/amm_dex_v2~1types~1Asset" + }, + { + "title": "asset_b", + "$ref": "#/definitions/amm_dex_v2~1types~1Asset" + }, + { + "title": "total_liquidity", "$ref": "#/definitions/Int" }, { - "title": "routing_in_indexes", - "$ref": "#/definitions/List$Int" + "title": "reserve_a", + "$ref": "#/definitions/Int" }, { - "title": "routing_out_indexes", - "$ref": "#/definitions/List$Int" + "title": "reserve_b", + "$ref": "#/definitions/Int" + }, + { + "title": "base_fee_a_numerator", + "$ref": "#/definitions/Int" }, { - "title": "order_fee", + "title": "base_fee_b_numerator", "$ref": "#/definitions/Int" + }, + { + "title": "fee_sharing_numerator_opt", + "$ref": "#/definitions/Option$Int" + }, + { + "title": "allow_dynamic_fee", + "$ref": "#/definitions/Bool" } ] + } + ] + }, + "amm_dex_v2/types/PoolRedeemer": { + "title": "PoolRedeemer", + "anyOf": [ + { + "title": "Batching", + "dataType": "constructor", + "index": 0, + "fields": [] }, { - "title": "UpdatePoolFeeOrStakeCredential", + "title": "UpdatePoolParameters", "dataType": "constructor", - "index": 2, + "index": 1, "fields": [ { "title": "action", - "$ref": "#/definitions/amm_dex_v2~1types~1UpdatePoolFeeOrStakeCredentialAction" + "$ref": "#/definitions/amm_dex_v2~1types~1UpdatePoolParametersAction" } ] }, { - "title": "WithdrawLiquidityShare", + "title": "WithdrawFeeSharing", "dataType": "constructor", - "index": 3, + "index": 2, "fields": [] } ] }, - "amm_dex_v2/types/UpdatePoolFeeOrStakeCredentialAction": { - "title": "UpdatePoolFeeOrStakeCredentialAction", + "amm_dex_v2/types/UpdatePoolParametersAction": { + "title": "UpdatePoolParametersAction", "anyOf": [ { "title": "UpdatePoolFee", @@ -479,10 +721,16 @@ "fields": [] }, { - "title": "UpdatePoolStakeCredential", + "title": "UpdateDynamicFee", "dataType": "constructor", "index": 1, "fields": [] + }, + { + "title": "UpdatePoolStakeCredential", + "dataType": "constructor", + "index": 2, + "fields": [] } ] }, diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..20ca9b5 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,28 @@ +import dts from "rollup-plugin-dts"; +import esbuild from "rollup-plugin-esbuild"; + +const bundle = (config) => ({ + ...config, + input: "src/index.ts", + external: (id) => !/^[./]/.test(id), +}); + +export default [ + bundle({ + plugins: [esbuild()], + output: [ + { + file: `build/index.es.js`, + format: "es", + sourcemap: true, + }, + ], + }), + bundle({ + plugins: [dts()], + output: { + file: `build/index.d.ts`, + format: "es", + }, + }), +]; diff --git a/src/batcher-sample.ts b/src/batcher-sample.ts new file mode 100644 index 0000000..c1518fe --- /dev/null +++ b/src/batcher-sample.ts @@ -0,0 +1,619 @@ +import { + Assets, + Constr, + Data, + Lucid, + Script, + toHex, + UTxO, +} from "lucid-cardano"; + +import { sha3 } from "./hash"; +import { EmulatorProvider } from "./provider"; +import { getContractScripts } from "./script"; +import { ADA, Asset } from "./types/asset"; +import { GlobalSetting } from "./types/global-setting"; +import { + AuthorizationMethodType, + OrderAmountType, + OrderDatum, + OrderDirection, + OrderExtraDatumType, + OrderKillable, +} from "./types/order"; +import { PoolBaseFee, PoolDatum } from "./types/pool"; +import { TxIn } from "./types/tx"; + +const DEFAULT_BATCHER_FEE = 2_000000n; +const DEFAULT_DEPOSIT_ADA = 2_000000n; +const DEFAULT_INIT_POOL_ADA = 3_000000n; + +const DEFAULT_FEE_DENOMINATOR = 10000n; + +function computeLPAssetName(assetA: Asset, assetB: Asset): string { + const k1 = sha3(assetA.policyId + assetA.tokenName); + const k2 = sha3(assetB.policyId + assetB.tokenName); + return sha3(k1 + k2); +} + +function calculateAmountOut({ + reserveIn, + reserveOut, + amountIn, + tradingFee, +}: { + reserveIn: bigint; + reserveOut: bigint; + amountIn: bigint; + tradingFee: bigint; +}): bigint { + const diff = DEFAULT_FEE_DENOMINATOR - tradingFee; + const inWithFee = diff * amountIn; + const numerator = inWithFee * reserveOut; + const denominator = DEFAULT_FEE_DENOMINATOR * reserveIn + inWithFee; + return numerator / denominator; +} + +function calculateEarnedFeeIn({ + amountIn, + tradingFee, + feeSharing, +}: { + amountIn: bigint; + tradingFee: bigint; + feeSharing?: bigint; +}): { + lpFee: bigint; + feeShare: bigint; +} { + const lpFee = (amountIn * tradingFee) / DEFAULT_FEE_DENOMINATOR; + let feeShare = 0n; + if (feeSharing) { + feeShare = + (amountIn * tradingFee * feeSharing) / + (DEFAULT_FEE_DENOMINATOR * DEFAULT_FEE_DENOMINATOR); + } + + return { + lpFee: lpFee, + feeShare: feeShare, + }; +} + +function calculateSwapExactIn({ + datumReserves, + valueReserves, + tradingFee, + amountIn, + direction, + feeSharing, +}: { + datumReserves: [bigint, bigint]; + valueReserves: [bigint, bigint]; + tradingFee: PoolBaseFee; + amountIn: bigint; + direction: OrderDirection; + feeSharing?: bigint; +}): { + newDatumReserves: [bigint, bigint]; + newValueReserves: [bigint, bigint]; + amountOut: bigint; +} { + const [datumReserveA, datumReserveB] = [...datumReserves]; + const [valueReserveA, valueReserveB] = [...valueReserves]; + const [reserveIn, reserveOut, tradingFeeIn] = + direction === OrderDirection.A_TO_B + ? [datumReserveA, datumReserveB, tradingFee.feeANumerator] + : [datumReserveB, datumReserveA, tradingFee.feeBNumerator]; + const amountOut = calculateAmountOut({ + amountIn: amountIn, + reserveIn: reserveIn, + reserveOut: reserveOut, + tradingFee: tradingFeeIn, + }); + const { feeShare: feeShareIn } = calculateEarnedFeeIn({ + amountIn: amountIn, + tradingFee: tradingFeeIn, + feeSharing: feeSharing, + }); + let newDatumReserveA: bigint; + let newDatumReserveB: bigint; + let newValueReserveA: bigint; + let newValueReserveB: bigint; + switch (direction) { + case OrderDirection.A_TO_B: { + newDatumReserveA = datumReserveA + amountIn - feeShareIn; + newDatumReserveB = datumReserveB - amountOut; + newValueReserveA = valueReserveA + amountIn; + newValueReserveB = valueReserveB - amountOut; + break; + } + case OrderDirection.B_TO_A: { + newDatumReserveA = datumReserveA - amountOut; + newDatumReserveB = datumReserveB + amountIn - feeShareIn; + newValueReserveA = valueReserveA - amountOut; + newValueReserveB = valueReserveB + amountIn; + break; + } + } + return { + newDatumReserves: [newDatumReserveA, newDatumReserveB], + newValueReserves: [newValueReserveA, newValueReserveB], + amountOut: amountOut, + }; +} + +function calculateOrderIndexes(txIns: TxIn[]): Uint8Array { + // first, we need to sort order by TxID and TxIndex + const tempTxIns = [...txIns]; + tempTxIns.sort((a, b) => TxIn.compare(a, b)); + // then, we loop the original orders backwards and add the indexes to resulting array + const ret: number[] = []; + for (let i = txIns.length - 1; i >= 0; i--) { + for (let j = 0; j < tempTxIns.length; j++) { + if (TxIn.compare(txIns[i], tempTxIns[j]) === 0) { + ret.push(j); + break; + } + } + } + return new Uint8Array(ret.reverse()); +} + +function getGlobalSetting(lucid: Lucid): { + globalSetting: GlobalSetting; + globalSettingUtxo: UTxO; +} { + const script = getContractScripts(lucid); + const pubkeyBatcher = getPubKeyBatcher(); + const scriptBatcher = getScriptBatcher(lucid); + const globalSetting: GlobalSetting = { + batchers: [pubkeyBatcher.batcherAddr, scriptBatcher.batcherAddr], + admin: "addr_test1vqe2eyupqj8e0jr8uumakm2zuhh2ucrcevy7hw8vztjaragvljjnc", + feeSharingTaker: + "addr_test1vqe2eyupqj8e0jr8uumakm2zuhh2ucrcevy7hw8vztjaragvljjnc", + poolDynamicFeeUpdater: + "addr_test1vqe2eyupqj8e0jr8uumakm2zuhh2ucrcevy7hw8vztjaragvljjnc", + poolFeeUpdater: + "addr_test1vqe2eyupqj8e0jr8uumakm2zuhh2ucrcevy7hw8vztjaragvljjnc", + poolStakeKeyUpdater: + "addr_test1vqe2eyupqj8e0jr8uumakm2zuhh2ucrcevy7hw8vztjaragvljjnc", + }; + return { + globalSetting: globalSetting, + globalSettingUtxo: { + txHash: + "eb5d5d3cf842b171b09a1878fc8c16cf7a5ad6a0d18e3122feb31078e224680a", + outputIndex: 20, + assets: { + [Asset.toString(ADA)]: 1_000_000_000n, + [Asset.toString(script.globalSettingAsset)]: 1n, + }, + address: script.authenAddress, + datum: Data.to(GlobalSetting.toPlutus(globalSetting)), + }, + }; +} + +function getPubKeyBatcher(): { + batcherAddr: string; + licenseUtxo: UTxO; + skey: string; +} { + const batcherAddr = + "addr_test1vq6wk0m30zgvzdpcut0th2flaj0xv2quwjajjthr8r6t9dcpt0dt5"; + return { + batcherAddr: batcherAddr, + licenseUtxo: { + txHash: + "37f875a17eee36e6ea4026de97c8b063ae649dd39fd07bce419e6b6e3c993477", + outputIndex: 0, + assets: { + [Asset.toString(ADA)]: 1_000_000_000n, + }, + address: batcherAddr, + }, + skey: "ed25519_sk1lpsssf9u5qpwraf230jua6d7703ze2ekwl734xqykqu3seszl7aslqde8x", + }; +} + +function getScriptBatcher(lucid: Lucid): { + batcherAddr: string; + batcherRef: UTxO; + licenseUtxo: UTxO; + collateral: UTxO; + collateralSkey: string; +} { + const batcherScript: Script = { + type: "PlutusV2", + script: + "583c0100003232323232222533300432323253330073370e900118041baa00114a22c60120026012002600c6ea8004526136565734aae7555cf2ba157441", + }; + const batcherAddr = lucid.utils.validatorToAddress(batcherScript); + const batcherRef: UTxO = { + txHash: "eb5d5d3cf842b171b09a1878fc8c16cf7a5ad6a0d18e3122feb31078e224680a", + outputIndex: 10, + address: "addr_test1vzztre5epvtj5p72sh28nvrs3e6s4xxn95f66cvg0sqsk7qd3mah0", + scriptRef: batcherScript, + assets: {}, + }; + return { + batcherAddr: batcherAddr, + batcherRef: batcherRef, + licenseUtxo: { + txHash: + "37f875a17eee36e6ea4026de97c8b063ae649dd39fd07bce419e6b6e3c993477", + outputIndex: 0, + assets: { + [Asset.toString(ADA)]: 1_000_000_000n, + }, + address: batcherAddr, + datum: Data.to(new Constr(0, [])), + }, + collateral: { + txHash: + "eb5d5d3cf842b171b09a1878fc8c16cf7a5ad6a0d18e3122feb31078e224680a", + outputIndex: 99, + assets: { + [Asset.toString(ADA)]: 5_000000n, + }, + address: + "addr_test1qqanmx3m8uchn2649eccsu2y3ztgkkr5rqtuznahyc2v5cwqe09wdp3al4rg9psrd43vptvavmaavsv5feldkgmyzjjq87yath", + }, + collateralSkey: + "ed25519_sk1cx0k7z6axzggg08d2e870cgpklawa9ppw39s7dny84allq8fltyqmfsvpw", + }; +} + +async function buildTxByPubKeyBatcher({ + lucid, + pool, + orders, +}: { + lucid: Lucid; + pool: { + poolIn: UTxO; + poolOut: { + value: Assets; + datum: string; + }; + }; + orders: { + orderIn: UTxO; + orderOut: { + address: string; + value: Assets; + }; + }[]; +}): Promise { + const scripts = getContractScripts(lucid); + const globalSetting = getGlobalSetting(lucid); + const { batcherAddr, licenseUtxo, skey } = getPubKeyBatcher(); + + lucid.selectWalletFrom({ + address: batcherAddr, + utxos: [licenseUtxo], + }); + + const inputIndexes = calculateOrderIndexes( + orders.map(({ orderIn }) => ({ + txId: orderIn.txHash, + index: orderIn.outputIndex, + })) + ); + + const poolBatchingRedeemer = new Constr(0, [ + 0n, + orders.map((_) => DEFAULT_BATCHER_FEE), + toHex(inputIndexes), + new Constr(1, []), + [new Constr(1, [])], + ]); + + const validFrom = new Date(); + const validTo = new Date(validFrom.getTime() + 10 * 60 * 1000); + const tx = lucid + .newTx() + .readFrom([ + globalSetting.globalSettingUtxo, + scripts.references.poolRef, + scripts.references.orderRef, + scripts.references.poolBatchingRef, + ]) + .collectFrom([pool.poolIn], Data.to(new Constr(0, []))) + .collectFrom( + orders.map((o) => o.orderIn), + Data.to(new Constr(0, [])) + ) + .withdraw(scripts.poolBatchingAddress, 0n, Data.to(poolBatchingRedeemer)) + .validFrom(validFrom.getTime()) + .validTo(validTo.getTime()) + .addSigner(batcherAddr); + + for (const { orderOut } of orders) { + tx.payToAddress(orderOut.address, orderOut.value); + } + tx.payToContract( + pool.poolIn.address, + { + inline: pool.poolOut.datum, + }, + pool.poolOut.value + ); + + const txComplete = await tx.complete({ + change: { + address: batcherAddr, + }, + }); + + const txSigned = await txComplete.signWithPrivateKey(skey).complete(); + const txId = await txSigned.submit(); + console.log(`Submit success by pub key batcher: ${txId}`); +} + +async function buildTxByScriptBatcher({ + lucid, + pool, + orders, +}: { + lucid: Lucid; + pool: { + poolIn: UTxO; + poolOut: { + value: Assets; + datum: string; + }; + }; + orders: { + orderIn: UTxO; + orderOut: { + address: string; + value: Assets; + }; + }[]; +}): Promise { + const scripts = getContractScripts(lucid); + const globalSetting = getGlobalSetting(lucid); + const { batcherAddr, licenseUtxo, batcherRef, collateral, collateralSkey } = + getScriptBatcher(lucid); + + lucid.selectWalletFrom({ + address: collateral.address, + utxos: [collateral], + }); + + const inputIndexes = calculateOrderIndexes( + orders.map(({ orderIn }) => ({ + txId: orderIn.txHash, + index: orderIn.outputIndex, + })) + ); + + const poolBatchingRedeemer = new Constr(0, [ + 1n, + orders.map((_) => DEFAULT_BATCHER_FEE), + toHex(inputIndexes), + new Constr(1, []), + [new Constr(1, [])], + ]); + + const validFrom = new Date(); + const validTo = new Date(validFrom.getTime() + 10 * 60 * 1000); + const tx = lucid + .newTx() + .readFrom([ + globalSetting.globalSettingUtxo, + batcherRef, + scripts.references.poolRef, + scripts.references.orderRef, + scripts.references.poolBatchingRef, + ]) + .collectFrom([pool.poolIn], Data.to(new Constr(0, []))) + .collectFrom( + orders.map((o) => o.orderIn), + Data.to(new Constr(0, [])) + ) + .collectFrom([licenseUtxo], Data.to(new Constr(0, []))) + .withdraw(scripts.poolBatchingAddress, 0n, Data.to(poolBatchingRedeemer)) + .validFrom(validFrom.getTime()) + .validTo(validTo.getTime()); + + for (const { orderOut } of orders) { + tx.payToAddress(orderOut.address, orderOut.value); + } + tx.payToContract( + pool.poolIn.address, + { + inline: pool.poolOut.datum, + }, + pool.poolOut.value + ); + + const txComplete = await tx.complete({ + change: { + address: batcherAddr, + outputData: { + inline: Data.to(new Constr(0, [])), + }, + }, + coinSelection: false, + }); + + const txSigned = await txComplete + .signWithPrivateKey(collateralSkey) + .complete(); + const txId = await txSigned.submit(); + console.log(`Submit success by script batcher: ${txId}`); +} + +async function main(): Promise { + const lucid = await Lucid.new(new EmulatorProvider(), "Preprod"); + const scripts = getContractScripts(lucid); + const assetA: Asset = ADA; + const assetB: Asset = { + policyId: "e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72", + tokenName: "4d494e", + }; + const amountA = 27_877_961_987941n; + const amountB = 414_804_973_691450n; + const lpAssetName = computeLPAssetName(assetA, assetB); + const lpAsset: Asset = { + policyId: scripts.authenPolicyId, + tokenName: lpAssetName, + }; + const totalLiquidity = 106241703280080n; + const maxLiquidity = 9223372036854775807n; + + const poolDatum: PoolDatum = { + poolBatchingStakeCredential: scripts.poolBatchingCredential, + assetA: assetA, + assetB: assetB, + totalLiquidity: totalLiquidity, + reserveA: 27_877_961_987941n, + reserveB: 414_804_973_691450n, + feeSharingNumerator: undefined, + baseFee: { + feeANumerator: 30n, + feeBNumerator: 100n, + }, + allowDynamicFee: false, + }; + + const poolValue: Assets = { + [Asset.toString(assetA)]: amountA + DEFAULT_INIT_POOL_ADA, + [Asset.toString(assetB)]: amountB, + [Asset.toString(lpAsset)]: maxLiquidity - totalLiquidity, + [Asset.toString(scripts.poolAuthAsset)]: 1n, + }; + + const poolInUtxo: UTxO = { + txHash: "dcb8585da6a8b47d014e2fc8718d3b6a44bd5f899d02654f611dfc525e74b154", + outputIndex: 0, + assets: poolValue, + address: scripts.poolAddress, + datum: Data.to(PoolDatum.toPlutus(poolDatum)), + }; + + const testUserAddr = + "addr_test1vrxhzzazrwa988jumcrtt7kt6gf7rwd4jxzr0kfvxjaqvwqavxh3s"; + const cancellerPubKeyHash = + "cd710ba21bba539e5cde06b5facbd213e1b9b5918437d92c34ba0638"; + const totalOrderAmount = 2_000_000000n; + const swapAmount = 1_000_000000n; + const swapDirection = OrderDirection.A_TO_B; + const orderDatum: OrderDatum = { + canceller: { + type: AuthorizationMethodType.SIGNATURE, + hash: cancellerPubKeyHash, + }, + refundReceiver: testUserAddr, + refundReceiverDatum: { + type: OrderExtraDatumType.NO_DATUM, + }, + successReceiver: testUserAddr, + successReceiverDatum: { + type: OrderExtraDatumType.NO_DATUM, + }, + lpAsset: lpAsset, + maxBatcherFee: DEFAULT_BATCHER_FEE, + expiredOptions: undefined, + step: { + direction: swapDirection, + swapAmountOption: { + type: OrderAmountType.SPECIFIC_AMOUNT, + swapAmount: swapAmount, + }, + minimumReceived: 1n, + killable: OrderKillable.PENDING_ON_FAILED, + }, + }; + const orderValue: Assets = { + [Asset.toString(ADA)]: + DEFAULT_BATCHER_FEE + DEFAULT_DEPOSIT_ADA + totalOrderAmount, + }; + + const orders: { + orderIn: UTxO; + orderOut: { + address: string; + value: Assets; + }; + }[] = []; + + let tempDatumReserves: [bigint, bigint] = [amountA, amountB]; + let tempValueReserves: [bigint, bigint] = [amountA, amountB]; + for (let i = 0; i < 38; i++) { + const orderIn: UTxO = { + txHash: + "5573777bedba6bb5f56541681256158dcf8ebfbc9e7251277d25b118517dce10", + outputIndex: i, + assets: orderValue, + address: scripts.orderAddress, + datum: Data.to(OrderDatum.toPlutus(orderDatum)), + }; + const { amountOut, newDatumReserves, newValueReserves } = + calculateSwapExactIn({ + datumReserves: tempDatumReserves, + valueReserves: tempValueReserves, + tradingFee: poolDatum.baseFee, + amountIn: swapAmount, + direction: swapDirection, + feeSharing: poolDatum.feeSharingNumerator, + }); + tempDatumReserves = newDatumReserves; + tempValueReserves = newValueReserves; + + const orderOutValue: Assets = { + ...orderValue, + }; + orderOutValue[Asset.toString(ADA)] -= DEFAULT_BATCHER_FEE + swapAmount; + orderOutValue[Asset.toString(assetB)] = + (orderOutValue[Asset.toString(assetB)] ?? 0n) + amountOut; + orders.push({ + orderIn: orderIn, + orderOut: { + address: orderDatum.successReceiver, + value: orderOutValue, + }, + }); + } + + const newPoolDatum: PoolDatum = { + ...poolDatum, + reserveA: tempDatumReserves[0], + reserveB: tempValueReserves[1], + }; + + const newPoolValue: Assets = { + ...poolValue, + }; + newPoolValue[Asset.toString(ADA)] = + tempDatumReserves[0] + DEFAULT_INIT_POOL_ADA; + newPoolValue[Asset.toString(assetB)] = tempValueReserves[1]; + + await buildTxByPubKeyBatcher({ + lucid: lucid, + pool: { + poolIn: poolInUtxo, + poolOut: { + value: newPoolValue, + datum: Data.to(PoolDatum.toPlutus(newPoolDatum)), + }, + }, + orders: orders, + }); + await buildTxByScriptBatcher({ + lucid: lucid, + pool: { + poolIn: poolInUtxo, + poolOut: { + value: newPoolValue, + datum: Data.to(PoolDatum.toPlutus(newPoolDatum)), + }, + }, + orders: orders, + }); +} + +void main(); diff --git a/src/hash.ts b/src/hash.ts new file mode 100644 index 0000000..dc14fff --- /dev/null +++ b/src/hash.ts @@ -0,0 +1,7 @@ +import { SHA3 } from "sha3"; + +export function sha3(hex: string): string { + const hash = new SHA3(256); + hash.update(hex, "hex"); + return hash.digest("hex"); +} diff --git a/src/provider.ts b/src/provider.ts new file mode 100644 index 0000000..b978207 --- /dev/null +++ b/src/provider.ts @@ -0,0 +1,57 @@ +import { + C, + Credential, + Delegation, + fromHex, + OutRef, + PROTOCOL_PARAMETERS_DEFAULT, + ProtocolParameters, + Provider, + UTxO, +} from "lucid-cardano"; + +import { Redeemer } from "./types/redeemer"; + +export class EmulatorProvider implements Provider { + async getProtocolParameters(): Promise { + return PROTOCOL_PARAMETERS_DEFAULT; + } + async getUtxos(_addressOrCredential: string | Credential): Promise { + return []; + } + async getUtxosWithUnit( + _addressOrCredential: string | Credential, + _unit: string + ): Promise { + return []; + } + async getUtxoByUnit(_unit: string): Promise { + throw new Error("Method not implemented."); + } + getUtxosByOutRef(_outRefs: OutRef[]): Promise { + throw new Error("Method not implemented."); + } + getDelegation(_rewardAddress: string): Promise { + throw new Error("Method not implemented."); + } + getDatum(_datumHash: string): Promise { + throw new Error("Method not implemented."); + } + awaitTx( + _txHash: string, + _checkInterval?: number | undefined + ): Promise { + throw new Error("Method not implemented."); + } + async submitTx(tx: string): Promise { + const cslTx = C.Transaction.from_bytes(fromHex(tx)); + // console.log(cslTx.to_json()) + const cslTxBody = cslTx.body(); + const cslTxId = C.hash_transaction(cslTxBody); + const cslRedeemers = cslTx.witness_set().redeemers(); + if (cslRedeemers) { + Redeemer.printRedeemers(cslRedeemers); + } + return cslTxId.to_hex(); + } +} diff --git a/src/script.ts b/src/script.ts new file mode 100644 index 0000000..338e44c --- /dev/null +++ b/src/script.ts @@ -0,0 +1,297 @@ +import fs from "fs"; +import { + applyParamsToScript, + Constr, + Credential, + fromHex, + fromText, + Lucid, + MintingPolicy, + Script, + SpendingValidator, + UTxO, + WithdrawalValidator, +} from "lucid-cardano"; + +import { Asset } from "./types/asset"; +import { TxIn } from "./types/tx"; + +type PlutusValidatorCompiled = { + title: string; + compiledCode: string; +}; +type PlutusCompiled = { + validators: PlutusValidatorCompiled[]; +}; + +function getInitialParameters(): { + seedTxIn: TxIn; + factoryNFTName: string; + poolNFTName: string; + globalSettingNFTName: string; +} { + return { + seedTxIn: { + txId: "2cc240daa819b2ec18a9fc9a8c86c6f2145328a64debd14ead32c589a6bfb22d", + index: 1, + }, + factoryNFTName: "MSF", + poolNFTName: "MSP", + globalSettingNFTName: "MSGS", + }; +} + +function readValidator(): { + order: SpendingValidator; + expiredOrderCancellation: WithdrawalValidator; + pool: SpendingValidator; + poolBatching: WithdrawalValidator; + authen: MintingPolicy; + factory: SpendingValidator; +} { + const file = fs.readFileSync("plutus.json", "utf-8"); + const plutusCompiled: PlutusCompiled = JSON.parse(file); + const orderValidatorComplied = plutusCompiled.validators.find( + (v) => v.title === "order_validator.validate_order" + ); + const expiredOrderCancelValidatorComplied = plutusCompiled.validators.find( + (v) => v.title === "order_validator.validate_expired_order_cancel" + ); + const poolValidatorComplied = plutusCompiled.validators.find( + (v) => v.title === "pool_validator.validate_pool" + ); + const authenMintingComplied = plutusCompiled.validators.find( + (v) => v.title === "authen_minting_policy.validate_authen" + ); + const factoryScriptComplied = plutusCompiled.validators.find( + (v) => v.title === "factory_validator.validate_factory" + ); + const poolBatchingValidatorComplied = plutusCompiled.validators.find( + (v) => v.title === "pool_validator.validate_pool_batching" + ); + if ( + !orderValidatorComplied || + !expiredOrderCancelValidatorComplied || + !poolValidatorComplied || + !poolBatchingValidatorComplied || + !authenMintingComplied || + !factoryScriptComplied + ) { + throw Error("Validator not found"); + } + + return { + order: { + type: "PlutusV2", + script: orderValidatorComplied.compiledCode, + }, + expiredOrderCancellation: { + type: "PlutusV2", + script: expiredOrderCancelValidatorComplied.compiledCode, + }, + pool: { + type: "PlutusV2", + script: poolValidatorComplied.compiledCode, + }, + poolBatching: { + type: "PlutusV2", + script: poolBatchingValidatorComplied.compiledCode, + }, + authen: { + type: "PlutusV2", + script: authenMintingComplied.compiledCode, + }, + factory: { + type: "PlutusV2", + script: factoryScriptComplied.compiledCode, + }, + }; +} + +type ContractScript = { + authenPolicyId: string; + authenAddress: string; + poolAddress: string; + orderAddress: string; + factoryAddress: string; + expiredOrderCancellationAddress: string; + poolBatchingAddress: string; + poolBatchingCredential: Credential; + poolAuthAsset: Asset; + factoryAuthAsset: Asset; + globalSettingAsset: Asset; + references: { + poolRef: UTxO; + orderRef: UTxO; + lpRef: UTxO; + factoryRef: UTxO; + expiredOrderCancelRef: UTxO; + poolBatchingRef: UTxO; + }; +}; + +let contractScript: ContractScript | undefined = undefined; + +export function getContractScripts(lucid: Lucid): ContractScript { + if (contractScript) { + return contractScript; + } + const validators = readValidator(); + const initialParameters = getInitialParameters(); + const authenMintingScript: Script = { + type: "PlutusV2", + script: applyParamsToScript(validators.authen.script, [ + TxIn.toPlutus(initialParameters.seedTxIn), + ]), + }; + const authenPolicyId = lucid.utils.mintingPolicyToId(authenMintingScript); + const poolScript: Script = { + type: "PlutusV2", + script: applyParamsToScript(validators.pool.script, [authenPolicyId]), + }; + const poolHash = lucid.utils.validatorToScriptHash(poolScript); + const poolBatchingScript: Script = { + type: "PlutusV2", + script: applyParamsToScript(validators.poolBatching.script, [ + authenPolicyId, + new Constr(1, [poolHash]), + ]), + }; + const poolBatchingHash = + lucid.utils.validatorToScriptHash(poolBatchingScript); + const poolBatchingStakeCredential = new Constr(0, [ + new Constr(1, [poolBatchingHash]), + ]); + + const expiredOrderCancellationScript: Script = { + type: "PlutusV2", + script: applyParamsToScript(validators.expiredOrderCancellation.script, []), + }; + const expiredOrderCancellationHash = lucid.utils.validatorToScriptHash( + expiredOrderCancellationScript + ); + const expiredOrderCancellationStakeCredential = new Constr(0, [ + new Constr(1, [expiredOrderCancellationHash]), + ]); + + const orderScript: Script = { + type: "PlutusV2", + script: applyParamsToScript(validators.order.script, [ + poolBatchingStakeCredential, + expiredOrderCancellationStakeCredential, + ]), + }; + + const factoryScript: Script = { + type: "PlutusV2", + script: applyParamsToScript(validators.factory.script, [ + authenPolicyId, + poolHash, + poolBatchingStakeCredential, + ]), + }; + + const authenAddress = lucid.utils.validatorToAddress(authenMintingScript); + const poolAddress = lucid.utils.validatorToAddress(poolScript); + const orderAddress = lucid.utils.validatorToAddress(orderScript); + const factoryAddress = lucid.utils.validatorToAddress(factoryScript); + const expiredOrderCancellationAddress = lucid.utils.validatorToRewardAddress( + expiredOrderCancellationScript + ); + const poolBatchingAddress = + lucid.utils.validatorToRewardAddress(poolBatchingScript); + + const referencesAddr = + "addr_test1vzztre5epvtj5p72sh28nvrs3e6s4xxn95f66cvg0sqsk7qd3mah0"; + const testReferenceTxHash = + "eb5d5d3cf842b171b09a1878fc8c16cf7a5ad6a0d18e3122feb31078e224680a"; + + const authenSize = fromHex(authenMintingScript.script).length; + const orderSize = fromHex(orderScript.script).length; + const poolSize = fromHex(poolScript.script).length; + const factorySize = fromHex(factoryScript.script).length; + const expiredOrderSize = fromHex( + expiredOrderCancellationScript.script + ).length; + const poolBatchingSize = fromHex(poolBatchingScript.script).length; + + console.log(` + - Authen size: ${authenSize} bytes + - Order size: ${orderSize} bytes + - Pool size: ${poolSize} bytes + - Factory size: ${factorySize} bytes + - Expired Order Cancel size: ${expiredOrderSize} bytes + - Pool batching size: ${poolBatchingSize} bytes + `); + contractScript = { + authenPolicyId, + authenAddress, + orderAddress, + poolAddress, + factoryAddress, + expiredOrderCancellationAddress, + poolBatchingAddress, + poolBatchingCredential: { + type: "Script", + hash: poolBatchingHash, + }, + poolAuthAsset: { + policyId: authenPolicyId, + tokenName: fromText(initialParameters.poolNFTName), + }, + factoryAuthAsset: { + policyId: authenPolicyId, + tokenName: fromText(initialParameters.factoryNFTName), + }, + globalSettingAsset: { + policyId: authenPolicyId, + tokenName: fromText(initialParameters.globalSettingNFTName), + }, + references: { + poolRef: { + txHash: testReferenceTxHash, + outputIndex: 1, + address: referencesAddr, + scriptRef: poolScript, + assets: {}, + }, + orderRef: { + txHash: testReferenceTxHash, + outputIndex: 2, + address: referencesAddr, + scriptRef: orderScript, + assets: {}, + }, + lpRef: { + txHash: testReferenceTxHash, + outputIndex: 3, + address: referencesAddr, + scriptRef: authenMintingScript, + assets: {}, + }, + factoryRef: { + txHash: testReferenceTxHash, + outputIndex: 4, + address: referencesAddr, + scriptRef: factoryScript, + assets: {}, + }, + expiredOrderCancelRef: { + txHash: testReferenceTxHash, + outputIndex: 5, + address: referencesAddr, + scriptRef: expiredOrderCancellationScript, + assets: {}, + }, + poolBatchingRef: { + txHash: testReferenceTxHash, + outputIndex: 6, + address: referencesAddr, + scriptRef: poolBatchingScript, + assets: {}, + }, + }, + }; + + return contractScript; +} diff --git a/src/types/address.ts b/src/types/address.ts new file mode 100644 index 0000000..9858858 --- /dev/null +++ b/src/types/address.ts @@ -0,0 +1,151 @@ +import invariant from "@minswap/tiny-invariant"; +import { + Address, + C, + Constr, + Credential, + Data, + getAddressDetails, +} from "lucid-cardano"; + +import { NetworkId } from "./network"; + +export namespace LucidCredential { + export function toPlutus(data: Credential): Constr { + const constructor = data.type === "Key" ? 0 : 1; + return new Constr(constructor, [data.hash]); + } + + export function fromPlutus(data: Constr): Credential { + switch (data.index) { + case 0: { + return { + type: "Key", + hash: data.fields[0] as string, + }; + } + case 1: { + return { + type: "Script", + hash: data.fields[0] as string, + }; + } + default: { + throw new Error( + `Index of Credentail must be 0 or 1, actual: ${data.index}` + ); + } + } + } + + export function toCSLStakeCredential( + credential: Credential + ): C.StakeCredential { + switch (credential.type) { + case "Key": { + return C.StakeCredential.from_keyhash( + C.Ed25519KeyHash.from_hex(credential.hash) + ); + } + case "Script": { + return C.StakeCredential.from_scripthash( + C.ScriptHash.from_hex(credential.hash) + ); + } + } + } +} + +export namespace AddressPlutusData { + export function toPlutus(address: Address): Constr { + const addressDetails = getAddressDetails(address); + if (addressDetails.type === "Base") { + invariant( + addressDetails.paymentCredential && addressDetails.stakeCredential, + "baseAddress must have both paymentCredential and stakeCredential" + ); + + return new Constr(0, [ + LucidCredential.toPlutus(addressDetails.paymentCredential), + new Constr(0, [ + new Constr(0, [ + LucidCredential.toPlutus(addressDetails.stakeCredential), + ]), + ]), + ]); + } + if (addressDetails.type === "Enterprise") { + invariant( + addressDetails.paymentCredential, + "EnterpriseAddress must has paymentCredential" + ); + return new Constr(0, [ + LucidCredential.toPlutus(addressDetails.paymentCredential), + new Constr(1, []), + ]); + } + throw new Error("only supports base address, enterprise address"); + } + + export function fromPlutus( + networkId: NetworkId, + data: Constr + ): Address { + switch (data.index) { + case 0: { + const paymentCredential = LucidCredential.fromPlutus( + data.fields[0] as Constr + ); + const cslPaymentCredential = + LucidCredential.toCSLStakeCredential(paymentCredential); + const maybeStakeCredentialConstr = data.fields[1] as Constr; + switch (maybeStakeCredentialConstr.index) { + case 0: { + // Base Address or Pointer Address + const stakeCredentialConstr = maybeStakeCredentialConstr + .fields[0] as Constr; + switch (stakeCredentialConstr.index) { + case 0: { + const stakeCredential = LucidCredential.fromPlutus( + stakeCredentialConstr.fields[0] as Constr + ); + const cslStakeCredential = + LucidCredential.toCSLStakeCredential(stakeCredential); + const cslAddress = C.BaseAddress.new( + networkId, + cslPaymentCredential, + cslStakeCredential + ).to_address(); + return cslAddress.to_bech32(undefined); + } + case 1: { + throw new Error(`Pointer Address has not been supported yet`); + } + default: { + throw new Error( + `Index of StakeCredentail must be 0 or 1, actual: ${stakeCredentialConstr.index}` + ); + } + } + } + case 1: { + // Enterprise Address + const cslAddress = C.EnterpriseAddress.new( + networkId, + cslPaymentCredential + ).to_address(); + return cslAddress.to_bech32(undefined); + } + default: { + throw new Error( + `Index of Maybe Stake Credentail must be 0 or 1, actual: ${maybeStakeCredentialConstr.index}` + ); + } + } + } + default: { + throw new Error(`Index of Address must be 0, actual: ${data.index}`); + } + } + } +} diff --git a/src/types/asset.ts b/src/types/asset.ts new file mode 100644 index 0000000..522e9a4 --- /dev/null +++ b/src/types/asset.ts @@ -0,0 +1,32 @@ +import { Constr, Data } from "lucid-cardano" +export const ADA: Asset = { + policyId: "", + tokenName: "" +} + +export type Asset = { + policyId: string, + tokenName: string +} + +export namespace Asset { + export function equals(a1: Asset, a2: Asset): boolean { + return a1.policyId === a2.policyId && a1.tokenName === a2.tokenName + } + export function toPlutus(asset: Asset): Constr { + return new Constr(0, [ + asset.policyId, + asset.tokenName + ]) + } + + export function toString(asset: Asset): string { + if (Asset.equals(ADA, asset)) { + return "lovelace"; + } + if (asset.tokenName === "") { + return asset.policyId; + } + return `${asset.policyId}${asset.tokenName}`; + } +} \ No newline at end of file diff --git a/src/types/global-setting.ts b/src/types/global-setting.ts new file mode 100644 index 0000000..592c0c6 --- /dev/null +++ b/src/types/global-setting.ts @@ -0,0 +1,25 @@ +import { Constr, Data } from "lucid-cardano"; + +import { AddressPlutusData } from "./address"; + +export type GlobalSetting = { + batchers: string[], + poolFeeUpdater: string, + feeSharingTaker: string, + poolStakeKeyUpdater: string, + poolDynamicFeeUpdater: string, + admin: string, +} + +export namespace GlobalSetting { + export function toPlutus(gs: GlobalSetting): Constr { + return new Constr(0, [ + gs.batchers.map(AddressPlutusData.toPlutus), + AddressPlutusData.toPlutus(gs.poolFeeUpdater), + AddressPlutusData.toPlutus(gs.feeSharingTaker), + AddressPlutusData.toPlutus(gs.poolStakeKeyUpdater), + AddressPlutusData.toPlutus(gs.poolDynamicFeeUpdater), + AddressPlutusData.toPlutus(gs.admin) + ]) + } +} \ No newline at end of file diff --git a/src/types/network.ts b/src/types/network.ts new file mode 100644 index 0000000..0afdd55 --- /dev/null +++ b/src/types/network.ts @@ -0,0 +1,5 @@ +export enum NetworkId { + TESTNET = 0, + MAINNET, + } + \ No newline at end of file diff --git a/src/types/order.ts b/src/types/order.ts new file mode 100644 index 0000000..cedeaf6 --- /dev/null +++ b/src/types/order.ts @@ -0,0 +1,167 @@ +import { Constr, Data } from "lucid-cardano" + +import { AddressPlutusData } from "./address"; +import { Asset } from "./asset"; + +export enum OrderExtraDatumType { + NO_DATUM = 0, + DATUM_HASH, + INLINE_DATUM, +} + +export type OrderExtraDatum = + | { + type: OrderExtraDatumType.NO_DATUM; + } + | { + type: OrderExtraDatumType.DATUM_HASH | OrderExtraDatumType.INLINE_DATUM; + hash: string; + }; + +export namespace OrderExtraDatum { + export function toPlutus(d: OrderExtraDatum): Constr { + switch (d.type) { + case OrderExtraDatumType.NO_DATUM: { + return new Constr(d.type, []) + } + case OrderExtraDatumType.DATUM_HASH: { + return new Constr(d.type, [ + d.hash + ]) + } + case OrderExtraDatumType.INLINE_DATUM: { + return new Constr(d.type, [ + d.hash + ]) + } + } + } +} + +export type OrderExpiry = { + expiredTime: bigint; + maxCancellingTip: bigint; +} + +export enum OrderDirection { + B_TO_A = 0, + A_TO_B, +} + +export namespace OrderDirection { + export function toPlutus(o: OrderDirection): Constr { + return new Constr(o, []) + } +} + +export enum OrderKillable { + PENDING_ON_FAILED = 0, + KILL_ON_FAILED, +} + +export namespace OrderKillable { + export function toPlutus(o: OrderKillable): Constr { + return new Constr(o, []) + } +} + +export enum OrderAmountType { + SPECIFIC_AMOUNT = 0, + ALL, +} + +export type OrderSwapAmountOption = + | { + type: OrderAmountType.SPECIFIC_AMOUNT; + swapAmount: bigint; + } + | { + type: OrderAmountType.ALL; + deductedAmount: bigint; + }; + +export namespace OrderSwapAmountOption { + export function toPlutus(o: OrderSwapAmountOption): Constr { + switch (o.type) { + case OrderAmountType.SPECIFIC_AMOUNT: { + return new Constr(o.type, [ + o.swapAmount + ]) + } + case OrderAmountType.ALL: { + return new Constr(o.type, [ + o.deductedAmount + ]) + } + } + } +} + +export type OrderSwapExactInStep = { + direction: OrderDirection; + swapAmountOption: OrderSwapAmountOption; + minimumReceived: bigint; + killable: OrderKillable; +} + +export namespace OrderStep { + export function toPlutus(step: OrderSwapExactInStep): Constr { + return new Constr(0, [ + OrderDirection.toPlutus(step.direction), + OrderSwapAmountOption.toPlutus(step.swapAmountOption), + step.minimumReceived, + OrderKillable.toPlutus(step.killable) + ]) + } +} + +export enum AuthorizationMethodType { + SIGNATURE = 0, + SPEND_SCRIPT, + WITHDRAW_SCRIPT, + MINT_SCRIPT +} + +export type AuthorizationMethod = { + type: AuthorizationMethodType, + hash: string; +} + +export namespace AuthorizationMethod { + export function toPlutus(m: AuthorizationMethod): Constr { + return new Constr(m.type, [ + m.hash + ]) + } +} + +export type OrderDatum = { + canceller: AuthorizationMethod, + refundReceiver: string; + refundReceiverDatum: OrderExtraDatum; + successReceiver: string; + successReceiverDatum: OrderExtraDatum; + lpAsset: Asset; + step: OrderSwapExactInStep; + maxBatcherFee: bigint; + expiredOptions?: OrderExpiry; +} + +export namespace OrderDatum { + export function toPlutus(dat: OrderDatum): Constr{ + return new Constr(0, [ + AuthorizationMethod.toPlutus(dat.canceller), + AddressPlutusData.toPlutus(dat.refundReceiver), + OrderExtraDatum.toPlutus(dat.refundReceiverDatum), + AddressPlutusData.toPlutus(dat.successReceiver), + OrderExtraDatum.toPlutus(dat.successReceiverDatum), + Asset.toPlutus(dat.lpAsset), + OrderStep.toPlutus(dat.step), + dat.maxBatcherFee, + dat.expiredOptions ? new Constr(0, [ + dat.expiredOptions.expiredTime, + dat.expiredOptions.maxCancellingTip + ]) : new Constr(1, []) + ]) + } +} \ No newline at end of file diff --git a/src/types/pool.ts b/src/types/pool.ts new file mode 100644 index 0000000..4992789 --- /dev/null +++ b/src/types/pool.ts @@ -0,0 +1,44 @@ +import { + Constr, + Credential, + Data, +} from "lucid-cardano"; + +import { LucidCredential } from "./address"; +import { Asset } from "./asset"; + +export type PoolBaseFee = { + feeANumerator: bigint; + feeBNumerator: bigint; +}; + +export type PoolDatum = { + poolBatchingStakeCredential: Credential; + assetA: Asset; + assetB: Asset; + totalLiquidity: bigint; + reserveA: bigint; + reserveB: bigint; + baseFee: PoolBaseFee; + feeSharingNumerator?: bigint; + allowDynamicFee: boolean; +}; + +export namespace PoolDatum { + export function toPlutus(dat: PoolDatum): Constr { + return new Constr(0, [ + new Constr(0, [ + LucidCredential.toPlutus(dat.poolBatchingStakeCredential) + ]), + Asset.toPlutus(dat.assetA), + Asset.toPlutus(dat.assetB), + dat.totalLiquidity, + dat.reserveA, + dat.reserveB, + dat.baseFee.feeANumerator, + dat.baseFee.feeBNumerator, + dat.feeSharingNumerator ? new Constr(0, [dat.feeSharingNumerator]) : new Constr(1, []), + new Constr(dat.allowDynamicFee ? 1 : 0, []) + ]) + } +} \ No newline at end of file diff --git a/src/types/redeemer.ts b/src/types/redeemer.ts new file mode 100644 index 0000000..6843896 --- /dev/null +++ b/src/types/redeemer.ts @@ -0,0 +1,45 @@ +import { C } from "lucid-cardano" + +export namespace Redeemer { + export function printRedeemers(redeemers: C.Redeemers): void { + let totalCpu = 0n + let totalMem = 0n + for (let i = 0; i < redeemers.len(); i++) { + const redeemer = redeemers.get(i) + const tag = redeemer.tag() + const index = redeemer.index().to_str() + const exUnit = redeemer.ex_units() + const cpu = exUnit.steps().to_str() + const mem = exUnit.mem().to_str() + totalCpu += BigInt(cpu) + totalMem += BigInt(mem) + + let kind = "" + switch (tag.kind()) { + case C.RedeemerTagKind.Spend: { + kind = "Spend" + break; + } + case C.RedeemerTagKind.Mint: { + kind = "Mint" + break; + } + case C.RedeemerTagKind.Cert: { + kind = "Cert" + break; + } + case C.RedeemerTagKind.Reward: { + kind = "Reward" + break; + } + default: { + throw new Error(`ExUnit: Unsupported Redeemer Kind: ${tag.kind()}`); + } + } + + // const text = kind + " index " + index + " cost " + mem + " mem and " + cpu + " cpu" + // console.log(text) + } + console.log(`Total: ${totalMem} mem and ${totalCpu} cpu`) + } +} \ No newline at end of file diff --git a/src/types/tx.ts b/src/types/tx.ts new file mode 100644 index 0000000..adf9a83 --- /dev/null +++ b/src/types/tx.ts @@ -0,0 +1,27 @@ +import { Constr, Data } from "lucid-cardano" + +export type TxIn = { + txId: string, + index: number +} + +export namespace TxIn { + export function toPlutus(txIn: TxIn): Constr { + return new Constr(0, [ + new Constr(0, [ + txIn.txId + ]), + BigInt(txIn.index) + ]) + } + + export function compare(a: TxIn, b: TxIn): number { + if (a.txId === b.txId) { + return a.index - b.index; + } else if (a.txId < b.txId) { + return -1 + } else { + return 1 + } + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f1e59e7 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "node", + "lib": ["ES2022", "DOM"], + "outDir": "build-tsc", + "skipLibCheck": true, + "esModuleInterop": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + // "noImplicitOverride": true, + // "noUnusedParameters": true, + // "noImplicitReturns": true, + // "noImplicitThis": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src", "examples", "test"], +} diff --git a/validators/always_success.ak b/validators/always_success.ak new file mode 100644 index 0000000..11d6dad --- /dev/null +++ b/validators/always_success.ak @@ -0,0 +1,8 @@ +use aiken/transaction.{ScriptContext, Spend} + +validator { + fn spend(_d: Data, _r: Data, ctx: ScriptContext) { + expect ScriptContext { purpose: Spend(_), .. } = ctx + True + } +} diff --git a/validators/authen_minting_policy.ak b/validators/authen_minting_policy.ak index 7b84a42..96e0b6f 100644 --- a/validators/authen_minting_policy.ak +++ b/validators/authen_minting_policy.ak @@ -1,15 +1,17 @@ +use aiken/builtin use aiken/dict use aiken/list use aiken/transaction.{ Input, Mint, Output, OutputReference, ScriptContext, Spend, Transaction, } +use aiken/transaction/credential.{Address, ScriptCredential} use aiken/transaction/value use amm_dex_v2/pool_validation use amm_dex_v2/types.{ - Asset, AuthenRedeemer, CreatePool, FactoryDatum, FactoryRedeemer, - MintFactoryAuthen, + Asset, AuthenRedeemer, CreatePool, DexInitialization, FactoryDatum, + FactoryRedeemer, GlobalSetting, } -use amm_dex_v2/utils.{factory_auth_asset_name} +use amm_dex_v2/utils validator( // @out_ref is a Reference of an Unspent Transaction Output, @@ -33,7 +35,7 @@ validator( value.quantity_of( out_value, authen_policy_id, - factory_auth_asset_name, + utils.factory_auth_asset_name, ) == 1 }, ) @@ -74,8 +76,8 @@ validator( ) } // The redeemer can be called once to initialize the whole AMM V2 system - MintFactoryAuthen -> { - let Transaction { inputs, mint, outputs, datums, .. } = transaction + DexInitialization -> { + let Transaction { inputs, mint, outputs, .. } = transaction // validate that `out_ref` must be presented in the Transaction Inputs expect [_] = @@ -87,17 +89,27 @@ validator( }, ) - // validate that the redeemer only mint a single Factory Token + // there are two NFT tokens that are minted in this transaction + // - 1 Factory NFT that have the same policy id with the own script hash + // and token name is defined in @factory_auth_asset_name + // - 1 Global Setting NFT that have the same policy id with the own script hash + // and token name is defined in @global_setting_asset_name let mint_value = value.from_minted_value(mint) - expect [(minted_pid, minted_an, minted_amount)] = - value.flatten(mint_value) expect and { - minted_pid == authen_policy_id, - minted_an == factory_auth_asset_name, - minted_amount == 1, + list.length(value.flatten(mint_value)) == 2, + value.quantity_of( + mint_value, + authen_policy_id, + utils.global_setting_asset_name, + ) == 1, + value.quantity_of( + mint_value, + authen_policy_id, + utils.factory_auth_asset_name, + ) == 1, } // validate that there's only 1 Factory UTxO in the Transaction Outputs - // The Factory UTxO must contain Factory Token in the value + // The Factory UTxO must contain 1 Factory Token in the value expect [factory_output] = list.filter( outputs, @@ -106,19 +118,126 @@ validator( value.quantity_of( out_value, authen_policy_id, - factory_auth_asset_name, + utils.factory_auth_asset_name, ) == 1 }, ) let Output { datum: factory_raw_datum, .. } = factory_output expect factory_datum: FactoryDatum = - utils.must_find_script_datum(datums, factory_raw_datum) + utils.must_find_script_inline_datum(factory_raw_datum) let FactoryDatum { head, tail } = factory_datum + + // validate that there's only 1 Global Setting UTxO in the Transaction Outputs + // The Global Setting UTxO must contain 1 Global Setting Token in the value + expect [global_setting_output] = + list.filter( + outputs, + fn(output) { + let Output { + address: Address { payment_credential: payment_cred, .. }, + .. + } = output + when payment_cred is { + ScriptCredential(h) -> h == authen_policy_id + _ -> False + } + }, + ) + let Output { + value: global_setting_value, + datum: global_setting_datum_raw, + .. + } = global_setting_output + expect global_setting: GlobalSetting = + utils.must_find_script_inline_datum(global_setting_datum_raw) + let GlobalSetting { batchers, .. } = global_setting and { head == #"00", tail == #"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + // authorized batchers must not be empty + !builtin.null_list(batchers), + // The Global Setting UTxO must contain 1 Global Setting Token in the value + value.quantity_of( + global_setting_value, + authen_policy_id, + utils.global_setting_asset_name, + ) == 1, } } } } + + fn validate_spend_global_setting( + datum: GlobalSetting, + _redeemer: Data, + context: ScriptContext, + ) { + let ScriptContext { transaction, purpose } = context + expect Spend(global_setting_input_ref) = purpose + let Transaction { + inputs, + outputs, + extra_signatories, + withdrawals, + mint, + .. + } = transaction + expect Some(global_setting_input) = + transaction.find_input(inputs, global_setting_input_ref) + let Input { + output: Output { + value: global_setting_value_input, + address: Address { + payment_credential: global_setting_payment_credential, + .. + }, + .. + }, + .. + } = global_setting_input + expect ScriptCredential(global_setting_script_hash) = + global_setting_payment_credential + + let GlobalSetting { admin, .. } = datum + let global_setting_output = outputs |> builtin.head_list + let Output { + value: global_setting_value_out, + address: Address { + payment_credential: global_setting_payment_credential_out, + .. + }, + datum: global_setting_out_raw_datum, + .. + } = global_setting_output + expect global_setting_out_datum: GlobalSetting = + utils.must_find_script_inline_datum(global_setting_out_raw_datum) + let GlobalSetting { batchers, .. } = global_setting_out_datum + + and { + // Transaction must be executed by the correct admin + pool_validation.authorize_license_holder( + license_address: admin, + transaction_inputs: inputs, + withdrawals: withdrawals, + extra_signatories: extra_signatories, + ), + // Both Global Setting input and output must have the same payment credential + // and keep the Global Setting Token + value.quantity_of( + global_setting_value_input, + global_setting_script_hash, + utils.global_setting_asset_name, + ) == 1, + value.quantity_of( + global_setting_value_out, + global_setting_script_hash, + utils.global_setting_asset_name, + ) == 1, + global_setting_payment_credential_out == global_setting_payment_credential, + // transaction won't mint anything + value.is_zero(value.from_minted_value(mint)), + // validate authorized batchers must not be empty + !builtin.null_list(batchers), + } + } } diff --git a/validators/factory_validator.ak b/validators/factory_validator.ak index 0384fd1..3a17da3 100644 --- a/validators/factory_validator.ak +++ b/validators/factory_validator.ak @@ -1,7 +1,7 @@ use aiken/builtin use aiken/list use aiken/transaction.{Input, Output, ScriptContext, Spend, Transaction} -use aiken/transaction/credential.{Address, ScriptCredential} +use aiken/transaction/credential.{Address, ScriptCredential, StakeCredential} use aiken/transaction/value.{PolicyId, ada_asset_name, ada_policy_id} use amm_dex_v2/math use amm_dex_v2/pool_validation @@ -15,6 +15,8 @@ validator( authen_policy_id: PolicyId, // ValidatorHash of Pool Contract pool_hash: ValidatorHash, + // Stake Credential of Pool Batching Contract + pool_batching_stake_credential: StakeCredential, ) { fn validate_factory( datum: FactoryDatum, @@ -23,17 +25,7 @@ validator( ) { let ScriptContext { transaction, purpose } = context expect Spend(factory_ref) = purpose - let Transaction { - inputs, - reference_inputs, - mint, - outputs, - datums, - withdrawals, - extra_signatories, - validity_range, - .. - } = transaction + let Transaction { inputs, mint, outputs, .. } = transaction let FactoryRedeemer { asset_a, asset_b } = redeemer let FactoryDatum { head: current_head, tail: current_tail } = datum let Asset { policy_id: asset_a_policy_id, asset_name: asset_a_asset_name } = @@ -115,9 +107,9 @@ validator( let Output { datum: factory_output_1_raw_datum, .. } = factory_output_1 let Output { datum: factory_output_2_raw_datum, .. } = factory_output_2 expect factory_outout_datum_1: FactoryDatum = - utils.must_find_script_datum(datums, factory_output_1_raw_datum) + utils.must_find_script_inline_datum(factory_output_1_raw_datum) expect factory_outout_datum_2: FactoryDatum = - utils.must_find_script_datum(datums, factory_output_2_raw_datum) + utils.must_find_script_inline_datum(factory_output_2_raw_datum) let FactoryDatum { head: new_head_1, tail: new_tail_1 } = factory_outout_datum_1 let FactoryDatum { head: new_head_2, tail: new_tail_2 } = @@ -158,19 +150,19 @@ validator( let Output { value: pool_output_value, datum: pool_output_raw_datum, .. } = pool_output expect pool_out_datum: PoolDatum = - utils.must_find_script_datum(datums, pool_output_raw_datum) + utils.must_find_script_inline_datum(pool_output_raw_datum) let PoolDatum { + pool_batching_stake_credential: pool_stake_credential, asset_a: pool_datum_asset_a, asset_b: pool_datum_asset_b, total_liquidity: pool_datum_total_liquidity, reserve_a: pool_datum_reserve_a, reserve_b: pool_datum_reserve_b, - trading_fee_numerator: pool_datum_trading_fee_numerator, - trading_fee_denominator: pool_datum_trading_fee_denominator, - profit_sharing_opt: pool_datum_profit_sharing_opt, + base_fee_a_numerator: pool_datum_base_fee_a_numerator, + base_fee_b_numerator: pool_datum_base_fee_b_numerator, + fee_sharing_numerator_opt: pool_datum_fee_sharing_numerator_opt, + allow_dynamic_fee: pool_allow_dynamic_fee, } = pool_out_datum - // profit_sharing must be empty - expect None = pool_datum_profit_sharing_opt let estimated_amount_a = value.quantity_of( pool_output_value, @@ -179,7 +171,7 @@ validator( ) let amount_a = if utils.is_ada_asset(asset_a_policy_id, asset_a_asset_name) { - estimated_amount_a - 3000000 + estimated_amount_a - utils.min_pool_ada } else { estimated_amount_a } @@ -194,35 +186,14 @@ validator( 9223372036854775807 - ( total_liquidity - utils.default_burn_liquidity ) let expected_pool_out_value = value.zero() - |> value.add(ada_policy_id, ada_asset_name, 3000000) + |> value.add(ada_policy_id, ada_asset_name, utils.min_pool_ada) |> value.add(asset_a_policy_id, asset_a_asset_name, amount_a) |> value.add(asset_b_policy_id, asset_b_asset_name, amount_b) |> value.add(authen_policy_id, lp_asset_name, remaining_liquidity) |> value.add(authen_policy_id, utils.pool_auth_asset_name, 1) - let is_valid_trading_fee = - if - list.has( - [(5, 10000), (3, 1000), (1, 100)], - (pool_datum_trading_fee_numerator, pool_datum_trading_fee_denominator), - ){ - - True - } else { - and { - pool_validation.is_admin_existence( - admin_policy_id: utils.admin_policy_id, - reference_inputs: reference_inputs, - withdrawals: withdrawals, - signatories: extra_signatories, - validity_range: validity_range, - ), - pool_validation.validate_trading_fee_percent( - pool_datum_trading_fee_numerator, - pool_datum_trading_fee_denominator, - ), - } - } and { + // stake_credential must be the same with configured credential + pool_stake_credential == pool_batching_stake_credential, // asset_a and asset_b must be the same with Factory Redeemer pool_datum_asset_a == asset_a, pool_datum_asset_b == asset_b, @@ -231,12 +202,23 @@ validator( // Pool Reserve must be the same between datum and value pool_datum_reserve_a == amount_a, pool_datum_reserve_b == amount_b, - // Initial Pool Reserves and liquditiy must be positive + // Initial Pool Reserves must be positive and the liquditiy must be greater than the burn liquidity amount_a > 0, amount_b > 0, - total_liquidity > 0, - // trading_fee_percentage must be between **0.05%** and **10%** - is_valid_trading_fee, + total_liquidity > utils.default_burn_liquidity, + // base_fee_a_numerator and base_fee_b_numerator must be the same + pool_datum_base_fee_a_numerator == pool_datum_base_fee_b_numerator, + // base_fee_a_numerator and base_fee_b_numerator must be between **5** and **2000** + pool_validation.validate_fee_percent( + fee_num: pool_datum_base_fee_a_numerator, + max_fee_num: utils.max_base_fee_numerator, + min_fee_num: utils.min_base_fee_numerator, + ), + // Dynamic Fee is not allowed in Pool Creation + pool_allow_dynamic_fee == False, + // fee_sharing_numerator_opt must be empty + pool_datum_fee_sharing_numerator_opt == None, + // Transaction must mint necessary assets value.from_minted_value(mint) == pool_validation.get_pool_creation_expected_mint( authen_policy_id: authen_policy_id, lp_asset_name: lp_asset_name, diff --git a/validators/order_validator.ak b/validators/order_validator.ak index af74061..c1e25e9 100644 --- a/validators/order_validator.ak +++ b/validators/order_validator.ak @@ -1,22 +1,25 @@ +use aiken/builtin use aiken/dict -use aiken/interval.{Finite, Interval, IntervalBound} use aiken/list use aiken/transaction.{ Input, Output, ScriptContext, Spend, Transaction, WithdrawFrom, } use aiken/transaction/credential.{ - Address, ScriptCredential, StakeCredential, VerificationKeyCredential, + Address, Inline, ScriptCredential, StakeCredential, } +use aiken/transaction/value use amm_dex_v2/order_validation use amm_dex_v2/types.{ - ApplyOrder, CancelExpiredOrderByAnyone, CancelOrderByOwner, OrderDatum, - OrderRedeemer, OrderSpendingRedeemer, ValidatorHash, + ApplyOrder, CancelExpiredOrderByAnyone, CancelOrderByOwner, OAMMintScript, + OAMSignature, OAMSpendScript, OAMWithdrawScript, OrderDatum, OrderRedeemer, } use amm_dex_v2/utils validator( - // the Stake Credential of Order Batching Validator - stake_credential: StakeCredential, + // the Stake Credential of Pool Batching Validator + pool_batching_credential: StakeCredential, + // the Stake Credential of Expired Order Cancellation Validator + expired_order_cancel_credential: StakeCredential, ) { fn validate_order(raw_datum: Data, raw_redeemer: Data, context: ScriptContext) { let ScriptContext { transaction, purpose } = context @@ -26,24 +29,23 @@ validator( ApplyOrder -> { let Transaction { withdrawals, .. } = transaction // validate that an Order can be spent if there's a `Order Batching` validator in the `withdrawals` - dict.has_key(withdrawals, stake_credential) + dict.has_key(withdrawals, pool_batching_credential) } CancelOrderByOwner -> { - let Transaction { inputs, extra_signatories, .. } = transaction + let Transaction { inputs, extra_signatories, withdrawals, mint, .. } = + transaction expect order_datum: OrderDatum = raw_datum - let OrderDatum { - sender: Address { payment_credential: owner_payment_credential, .. }, - .. - } = order_datum - // validate that the transaction has _sender_'s signature or _sender_ script UTxO in the Transaction Inputs - when owner_payment_credential is { - VerificationKeyCredential(owner_pkh) -> - // Verify transaction must be signed by Owner - list.has(extra_signatories, owner_pkh) - ScriptCredential(_) -> - // In case owner is script address, this script will require at least 1 owner UTxO in input - // If owner UTxO has enough condition to unlock itself, it can unlock this script as well - list.length( + let OrderDatum { canceller, .. } = order_datum + // Canceller can be one of 4 authorization methods + when canceller is { + // In case the wallet is a PubKey, its signature is required + OAMSignature(pub_key_hash) -> + list.has(extra_signatories, pub_key_hash) + // In case the wallet is a Script and offer Spend method + // its Utxo has to present in the transaction inputs + OAMSpendScript(script_hash) -> { + let canceller_credential = ScriptCredential(script_hash) + !builtin.null_list( list.filter( inputs, fn(input) { @@ -51,75 +53,73 @@ validator( let Output { address: out_address, .. } = output let Address { payment_credential: out_payment_credential, .. } = out_address - out_payment_credential == owner_payment_credential + out_payment_credential == canceller_credential }, ), - ) > 0 + ) + } + // In case the wallet is a Script and offer Withdrawal method + // it has to make a withdrawal and present in transaction withdrawals + OAMWithdrawScript(script_hash) -> { + let credential = Inline(ScriptCredential(script_hash)) + dict.has_key(withdrawals, credential) + } + // In case the wallet is a Script and offer Minting method + // it has to mint tokens that has defined policy id and present in transaction minting + // Token's quantity must not be zero + OAMMintScript(script_hash) -> { + let fst_token_quantity = + mint + |> value.from_minted_value() + |> value.tokens(script_hash) + |> dict.to_list() + |> builtin.head_list + |> builtin.snd_pair + fst_token_quantity != 0 + } } } CancelExpiredOrderByAnyone -> { let Transaction { withdrawals, .. } = transaction // validate that an Order can be spent if there's a `Order Batching` validator in the `withdrawals` - dict.has_key(withdrawals, stake_credential) + dict.has_key(withdrawals, expired_order_cancel_credential) } } } } -validator( - // the hash of Liquidity Pool Script - pool_hash: ValidatorHash, -) { - fn validate_order_spending( - redeemer: OrderSpendingRedeemer, +validator { + fn validate_expired_order_cancel( + _redeemer: Data, context: ScriptContext, ) -> Bool { expect ScriptContext { transaction, purpose: WithdrawFrom(_) } = context - let OrderSpendingRedeemer { pool_input_index } = redeemer - - let Transaction { inputs, .. } = transaction - let Input { - output: Output { - address: Address { payment_credential: pool_payment_credential, .. }, - .. - }, - .. - } = utils.list_at_index(inputs, pool_input_index) - - // validate that there's a Pool Input which have Address's Payment Credential matching with `pool_hash` - if ScriptCredential(pool_hash) == pool_payment_credential { - True - } else { - // Otherwise it have to validating expired orders are cancelled in the correct way by anyone. - let Transaction { outputs, validity_range, datums, .. } = transaction - // Assume all script inputs are order scripts. - // All scripts that have the same Order Datum structure will be accepted in this transaction. - let order_inputs = - list.filter( - inputs, - fn(input) { - let Input { - output: Output { address: Address { payment_credential, .. }, .. }, - .. - } = input - when payment_credential is { - ScriptCredential(_) -> True - _ -> False - } - }, - ) - - let Interval { - lower_bound: IntervalBound { bound_type: lower_bound_type, .. }, - .. - } = validity_range - expect Finite(start_valid_time_range) = lower_bound_type - order_validation.validate_cancel_expired_orders( - order_inputs: order_inputs, - all_outputs: outputs, - datum_map: datums, - start_valid_time_range: start_valid_time_range, + let Transaction { inputs, outputs, validity_range, datums, .. } = + transaction + // Assume all script inputs are order scripts. + // All scripts that have the same Order Datum structure will be accepted in this transaction. + let order_inputs = + list.filter( + inputs, + fn(input) { + let Input { + output: Output { address: Address { payment_credential, .. }, .. }, + .. + } = input + when payment_credential is { + ScriptCredential(_) -> True + _ -> False + } + }, ) - } + + let start_valid_time_range = + utils.must_get_finite_start_validity(validity_range) + order_validation.validate_cancel_expired_orders( + order_inputs: order_inputs, + all_outputs: outputs, + datum_map: datums, + start_valid_time_range: start_valid_time_range, + ) } } diff --git a/validators/pool_validator.ak b/validators/pool_validator.ak index 5ae57c5..9dee989 100644 --- a/validators/pool_validator.ak +++ b/validators/pool_validator.ak @@ -1,11 +1,19 @@ use aiken/builtin +use aiken/bytearray +use aiken/dict use aiken/list -use aiken/transaction.{ScriptContext, Spend, Transaction} +use aiken/transaction.{ + Input, Output, ScriptContext, Spend, Transaction, WithdrawFrom, +} +use aiken/transaction/credential.{Address, Credential} use aiken/transaction/value.{PolicyId} +use amm_dex_v2/order_validation use amm_dex_v2/pool_validation use amm_dex_v2/types.{ - Batching, MultiRouting, PoolDatum, PoolRedeemer, - UpdatePoolFeeOrStakeCredential, WithdrawLiquidityShare, + Batching, BatchingPool, GlobalSetting, OrderDatum, PoolBatchingRedeemer, + PoolDatum, PoolRedeemer, SwapMultiRouting, SwapRouting, UpdateDynamicFee, + UpdatePoolFee, UpdatePoolParameters, UpdatePoolStakeCredential, + WithdrawFeeSharing, } use amm_dex_v2/utils @@ -14,169 +22,362 @@ validator( authen_policy_id: PolicyId, ) { fn validate_pool( - raw_datum: Data, + datum: PoolDatum, redeemer: PoolRedeemer, context: ScriptContext, ) { expect ScriptContext { transaction, purpose: Spend(pool_input_ref) } = context when redeemer is { - Batching(input_indexes, orders_fee, license_index) -> { - expect datum: PoolDatum = raw_datum - let Transaction { inputs, outputs, datums, validity_range, mint, .. } = - transaction - // Batching Redeemer provides @license_index which help save calculation cost - let license_input = utils.list_at_index(inputs, license_index) - // A valid license token is the token having expired timestamp as TokenName and must be within current time and current time + _maximum_deadline_range_ - let (batcher_address, end_valid_time_range) = - pool_validation.validate_license_expiration_and_find_license_holder( - license_pid: utils.batcher_license_policy_id, - license_input: license_input, - validity_range: validity_range, - ) - and { - // Input indexes must not be empty list - !builtin.null_list(input_indexes), - // Input indexes must be unique - utils.is_list_unique(input_indexes), - // Batcher need to provide all Batcher fee for each order - utils.compare_list_length(input_indexes, orders_fee), - // validate Transaction won't mint any assets - value.is_zero(value.from_minted_value(mint)), - pool_validation.validate_batching( - authen_policy_id: authen_policy_id, - all_inputs: inputs, - all_outputs: outputs, - all_datums: datums, - pool_input_ref: pool_input_ref, - pool_in_datum: datum, - batcher_address: batcher_address, - end_valid_time_range: end_valid_time_range, - input_indexes: input_indexes, - orders_fee: orders_fee, - ), - } + Batching -> { + let Transaction { withdrawals, .. } = transaction + let PoolDatum { pool_batching_stake_credential, .. } = datum + dict.has_key(withdrawals, pool_batching_stake_credential) } - MultiRouting( - license_index, - routing_in_indexes, - routing_out_indexes, - order_fee, - ) -> { - let routing_in_indexes_len = list.length(routing_in_indexes) - let routing_out_indexes_len = list.length(routing_out_indexes) - // validate routing_in_indexes and routing_out_indexes must be unique, - // have the same length and contain more than 1 element. - expect and { - routing_in_indexes_len == routing_out_indexes_len, - routing_out_indexes_len >= 2, - utils.is_list_unique(routing_in_indexes), - utils.is_list_unique(routing_out_indexes), - } - let Transaction { inputs, outputs, datums, validity_range, mint, .. } = - transaction - // Batching Redeemer provides @license_index which help save calculation cost - let license_input = utils.list_at_index(inputs, license_index) - let (batcher_address, end_valid_time_range) = - pool_validation.validate_license_expiration_and_find_license_holder( - license_pid: utils.batcher_license_policy_id, - license_input: license_input, - validity_range: validity_range, - ) - and { - // validate Transaction won't mint any assets - value.is_zero(value.from_minted_value(mint)), - pool_validation.validate_swap_multi_routing( - authen_policy_id: authen_policy_id, - all_inputs: inputs, - all_outputs: outputs, - all_datums: datums, - pool_input_ref: pool_input_ref, - batcher_address: batcher_address, - end_valid_time_range: end_valid_time_range, - routing_in_indexes: routing_in_indexes, - routing_out_indexes: routing_out_indexes, - order_fee: order_fee, - ), - } - } - UpdatePoolFeeOrStakeCredential(action) -> { - expect datum: PoolDatum = raw_datum + UpdatePoolParameters(action) -> { let Transaction { inputs, reference_inputs, outputs, - datums, - redeemers, mint, withdrawals, extra_signatories, - validity_range, .. } = transaction expect Some(pool_input) = transaction.find_input(inputs, pool_input_ref) - and { - // Transaction requires admin token to execute - pool_validation.is_admin_existence( - admin_policy_id: utils.admin_policy_id, + let Input { output: Output { address: pool_address, .. }, .. } = + pool_input + let global_setting = + pool_validation.get_and_validate_global_setting( reference_inputs: reference_inputs, + authen_policy_id: authen_policy_id, + ) + let GlobalSetting { + pool_fee_updater, + pool_stake_key_updater, + pool_dynamic_fee_updater, + .. + } = global_setting + let authorizer = + when action is { + UpdatePoolFee -> pool_fee_updater + UpdateDynamicFee -> pool_dynamic_fee_updater + UpdatePoolStakeCredential -> pool_stake_key_updater + } + and { + // Transaction must be executed by the correct authorizer + pool_validation.authorize_license_holder( + license_address: authorizer, + transaction_inputs: inputs, withdrawals: withdrawals, - signatories: extra_signatories, - validity_range: validity_range, + extra_signatories: extra_signatories, ), - // Transaction contain only 1 Spending Script (Pool Script). + // Verify that the transaction spends only one Single Pool Script and does not contain any other scripts in its inputs, except for the Author, in cases where the Author is a script // It will avoid bad Admin can steal money from Order Contract. - pool_validation.has_single_spending(redeemers), + pool_validation.has_only_pool_and_author( + inputs: inputs, + pool_address: pool_address, + author_address: authorizer, + ), // This Redeemer won't mint anything value.is_zero(value.from_minted_value(mint)), - pool_validation.validate_update_pool_datum_or_stake_credential( + pool_validation.validate_update_pool_parameters( action: action, authen_policy_id: authen_policy_id, pool_input: pool_input, pool_in_datum: datum, all_outputs: outputs, - all_datums: datums, ), } } - WithdrawLiquidityShare -> { - expect datum: PoolDatum = raw_datum + WithdrawFeeSharing -> { let Transaction { inputs, reference_inputs, outputs, - datums, - redeemers, mint, withdrawals, extra_signatories, - validity_range, .. } = transaction expect Some(pool_input) = transaction.find_input(inputs, pool_input_ref) - and { - // Transaction requires admin token to execute - pool_validation.is_admin_existence( - admin_policy_id: utils.admin_policy_id, + let Input { output: Output { address: pool_address, .. }, .. } = + pool_input + let global_setting = + pool_validation.get_and_validate_global_setting( reference_inputs: reference_inputs, + authen_policy_id: authen_policy_id, + ) + let GlobalSetting { fee_sharing_taker, .. } = global_setting + and { + // Transaction must be executed by the correct authorizer + pool_validation.authorize_license_holder( + license_address: fee_sharing_taker, + transaction_inputs: inputs, withdrawals: withdrawals, - signatories: extra_signatories, - validity_range: validity_range, + extra_signatories: extra_signatories, ), - // Transaction contain only 1 Spending Script (Pool Script). + // Verify that the transaction spends only one Single Pool Script and does not contain any other scripts in its inputs, except for the Author, in cases where the Author is a script // It will avoid bad Admin can steal money from Order Contract. - pool_validation.has_single_spending(redeemers), + pool_validation.has_only_pool_and_author( + inputs: inputs, + pool_address: pool_address, + author_address: fee_sharing_taker, + ), // This Redeemer won't mint anything value.is_zero(value.from_minted_value(mint)), - pool_validation.validate_withdraw_liquidity_share( + pool_validation.validate_withdraw_fee_sharing( authen_policy_id: authen_policy_id, pool_input: pool_input, pool_in_datum: datum, all_outputs: outputs, - all_datums: datums, ), } } } } } + +validator( + // The PolicyID of Authen Minting Policy + authen_policy_id: PolicyId, + // The Payment Credential of Pool Validator + pool_payment_cred: Credential, +) { + fn validate_pool_batching( + redeemer: PoolBatchingRedeemer, + context: ScriptContext, + ) { + expect ScriptContext { + transaction, + purpose: WithdrawFrom(stake_credential), + } = context + let Transaction { + inputs, + outputs, + datums, + validity_range, + mint, + reference_inputs, + extra_signatories, + withdrawals, + .. + } = transaction + let PoolBatchingRedeemer { + batcher_index, + orders_fee, + input_indexes, + pool_input_indexes_opt, + vol_fees, + } = redeemer + let global_setting = + pool_validation.get_and_validate_global_setting( + reference_inputs: reference_inputs, + authen_policy_id: authen_policy_id, + ) + let GlobalSetting { batchers, .. } = global_setting + let current_time_approximation = + utils.must_get_current_time_approximation(validity_range) + + // Due to authorized batchers is a list so we use @batcher_index to save the On-chain cost + // on searching the batcher address in this section + let batcher_address = utils.list_at_index(batchers, batcher_index) + expect and { + // Transaction must be executed by the authorized batchers + pool_validation.authorize_license_holder( + license_address: batcher_address, + transaction_inputs: inputs, + withdrawals: withdrawals, + extra_signatories: extra_signatories, + ), + // Input indexes must not be empty list and be unique + utils.is_unique_bytearray_unsorted(input_indexes), + // validate Transaction won't mint any assets + value.is_zero(value.from_minted_value(mint)), + } + + let pool_inputs = + list.filter( + inputs, + fn(input) { + let Input { output: Output { address: addr, .. }, .. } = input + let Address { payment_credential: payment_cred, .. } = addr + payment_cred == pool_payment_cred + }, + ) + let pool_outputs = + list.filter( + outputs, + fn(output) { + let Output { address: addr, .. } = output + let Address { payment_credential: payment_cred, .. } = addr + payment_cred == pool_payment_cred + }, + ) + + // We assume that inputs not belonging to the batcher or liquidity pool are orders. + // These inputs' structure will be verified in the @apply_orders function and SwapMultiRouting branch. + // We do not force finding the order script hash here, as we allow for the possibility of upgrading the order contract (possibly to Plutus V3). + let order_inputs = + list.filter( + inputs, + fn(input) { + let Input { output: out, .. } = input + let Output { address: addr, .. } = out + let Address { payment_credential: payment_cred, .. } = addr + addr != batcher_address && payment_cred != pool_payment_cred + }, + ) + // Currently, transaction inputs will be sorted by TxId and TxIndex of UTxO. + // We have to calculate indexes of orders inputs sorting by the ASC created time + // on the off-chain and on-chain will sort the TxIns by the indexes + // Input Indexes in parameter will be the index indexes of @order_inputs + let sorted_order_inputs = + bytearray.foldr( + input_indexes, + [], + fn(idx, ips) { list.push(ips, utils.list_at_index(order_inputs, idx)) }, + ) + + expect and { + // Order Inputs and Input Indexes must have the same length + builtin.length_of_bytearray(input_indexes) == list.length(order_inputs), + // Pool Inputs & Outputs must have the same length + utils.compare_list_length(pool_inputs, pool_outputs), + } + + when pool_inputs is { + [pool_input] -> { + // In case transaction only contains 1 Pool Input & Output, all order types are accepted except SwapMultiRouting + let pool_output = pool_outputs |> builtin.head_list + expect [vol_fee] = vol_fees + let Input { output: pool_in_output, .. } = pool_input + let BatchingPool { + asset_a, + asset_b, + lp_asset, + trading_fee_a_numerator, + trading_fee_b_numerator, + fee_sharing_numerator_opt, + pool_state_in, + pool_state_out, + } = + pool_validation.get_batching_pool( + stake_credential: stake_credential, + pool_input: pool_in_output, + pool_output: pool_output, + authen_policy_id: authen_policy_id, + require_total_liquidity_unchange: False, + vol_fee: vol_fee, + ) + pool_state_out == order_validation.apply_orders( + datum_map: datums, + asset_a: asset_a, + asset_b: asset_b, + lp_asset: lp_asset, + trading_fee_a_numerator: trading_fee_a_numerator, + trading_fee_b_numerator: trading_fee_b_numerator, + fee_sharing_numerator_opt: fee_sharing_numerator_opt, + current_time_approximation: current_time_approximation, + order_inputs: sorted_order_inputs, + all_outputs: outputs, + orders_fee: orders_fee, + pool_state: pool_state_in, + ) + } + [] -> False + _ -> { + // In case transaction only contains more than 1 Pool Input & Output, only single SwapMultiRouting Order is accepted + expect [order_input] = sorted_order_inputs + let order_output = outputs |> builtin.head_list + expect [order_fee] = orders_fee + let Input { + output: Output { + value: order_in_value, + datum: raw_order_in_datum, + .. + }, + .. + } = order_input + let Output { value: order_out_value, .. } = order_output + expect order_in_datum: OrderDatum = + utils.must_find_script_datum(datums, raw_order_in_datum) + let OrderDatum { + success_receiver, + success_receiver_datum, + step: order_step, + max_batcher_fee, + lp_asset: order_lp_asset, + expiry_setting_opt, + .. + } = order_in_datum + expect SwapMultiRouting(routings, swap_amount_option, minimum_receive) = + order_step + let SwapRouting { lp_asset: first_routing_lp_asset, .. } = + routings |> builtin.head_list + expect Some(pool_input_indexes) = pool_input_indexes_opt + expect and { + // max_batcher_fee must be positive + max_batcher_fee > 0, + // Used Batcher Fee must be positive and less than or equal batcher fee + order_fee > 0, + order_fee <= max_batcher_fee, + // Order Output must be returned to receiver and might have receiver_datum + order_validation.validate_order_receiver( + receiver: success_receiver, + receiver_datum: success_receiver_datum, + output: order_output, + ), + // In case expired setting is turned on, the execution time must not exceed the expired_time + when expiry_setting_opt is { + None -> True + Some((expired_time, _)) -> + current_time_approximation <= expired_time + }, + // Order LP Asset must be the first LP Asset on the routing config + order_lp_asset == first_routing_lp_asset, + // minimum_receive must be positive + minimum_receive > 0, + // The number of Pool Inputs and Pool Outputs must be the same with _routings_ length + utils.compare_list_length(pool_inputs, routings), + // Pool Input Indexes must be unique + utils.is_unique_bytearray_unsorted(pool_input_indexes), + // This contract allows the order routing through at most 3 Pools + builtin.length_of_bytearray(pool_input_indexes) <= 3, + } + let sorted_pool_inputs = + bytearray.foldr( + pool_input_indexes, + [], + fn(idx, ps) { list.push(ps, utils.list_at_index(pool_inputs, idx)) }, + ) + let batching_pools = + utils.zip_with( + sorted_pool_inputs, + pool_outputs, + vol_fees, + fn(pool_in, pool_out, vol_fee) { + let Input { output: pool_in_output, .. } = pool_in + pool_validation.get_batching_pool( + stake_credential: stake_credential, + pool_input: pool_in_output, + pool_output: pool_out, + authen_policy_id: authen_policy_id, + require_total_liquidity_unchange: True, + vol_fee: vol_fee, + ) + }, + ) + order_validation.validate_swap_multi_routing_order( + pools: batching_pools, + routings: routings, + order_in_value: order_in_value, + order_out_value: order_out_value, + swap_amount_option: swap_amount_option, + minimum_receive: minimum_receive, + used_batcher_fee: order_fee, + ) + } + } + } +} diff --git a/validators/sample_multi_sign.ak b/validators/sample_multi_sign.ak index 9bd73e3..a25e723 100644 --- a/validators/sample_multi_sign.ak +++ b/validators/sample_multi_sign.ak @@ -1,52 +1,43 @@ -use aiken/dict use aiken/hash.{Blake2b_224, Hash} use aiken/list use aiken/transaction.{ InlineDatum, Input, Output, ScriptContext, Spend, Transaction, WithdrawFrom, } -use aiken/transaction/credential.{Address, Inline, VerificationKey} -use aiken/transaction/value.{PolicyId} -use amm_dex_v2/pool_validation +use aiken/transaction/credential.{ + Address, Inline, ScriptCredential, VerificationKey, +} type MultiSignDatum { pub_key_hashes: List>, } -validator(admin_pid: PolicyId) { +validator { fn withdraw(_redeemer: Data, context: ScriptContext) { expect ScriptContext { - transaction: Transaction { - reference_inputs, - extra_signatories, - validity_range, - .. - }, - purpose: WithdrawFrom(stake_cred), + transaction: Transaction { reference_inputs, extra_signatories, .. }, + purpose: WithdrawFrom(stake_credential), } = context - let admin_input_opt = - list.find( - reference_inputs, - fn(input) { - let Input { output: Output { value: val, .. }, .. } = input - ( val |> value.tokens(admin_pid) |> dict.size() ) > 0 - }, - ) - expect Some(admin_input) = admin_input_opt - let (_, _) = - pool_validation.validate_license_expiration_and_find_license_holder( - license_pid: admin_pid, - license_input: admin_input, - validity_range: validity_range, - ) - expect Input { - output: Output { - address: Address { payment_credential: payment_cred, .. }, - datum: InlineDatum(raw_datum), - .. - }, - .. - } = admin_input - expect stake_cred == Inline(payment_cred) + expect Inline(own_cred) = stake_credential + expect ScriptCredential(own_hash) = own_cred + expect Some(multi_sign_input) = + reference_inputs + |> list.find( + fn(input) { + let Input { + output: Output { + address: Address { payment_credential: payment_cred, .. }, + .. + }, + .. + } = input + when payment_cred is { + ScriptCredential(hash) -> hash == own_hash + _ -> False + } + }, + ) + expect Input { output: Output { datum: InlineDatum(raw_datum), .. }, .. } = + multi_sign_input expect ref_datum: MultiSignDatum = raw_datum list.all(ref_datum.pub_key_hashes, fn(h) { list.has(extra_signatories, h) }) }