Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 40,364 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Fulfill Advanced... | 527869 | 10 secs ago | IN | 0.00097 ETH | 0.00001335 | ||||
Fulfill Availabl... | 527843 | 36 secs ago | IN | 0.1098 ETH | 0.00009105 | ||||
Fulfill Advanced... | 527808 | 1 min ago | IN | 0.009899 ETH | 0.00001102 | ||||
Fulfill Advanced... | 527801 | 1 min ago | IN | 0.247 ETH | 0.00001196 | ||||
Fulfill Advanced... | 527717 | 2 mins ago | IN | 0.043999 ETH | 0.00001286 | ||||
Fulfill Advanced... | 527707 | 2 mins ago | IN | 0.00739 ETH | 0.00001214 | ||||
Fulfill Advanced... | 527695 | 3 mins ago | IN | 0.242 ETH | 0.00001438 | ||||
Fulfill Advanced... | 527499 | 6 mins ago | IN | 0.029 ETH | 0.00001281 | ||||
Fulfill Availabl... | 527499 | 6 mins ago | IN | 0.003899 ETH | 0.00003134 | ||||
Fulfill Advanced... | 527410 | 7 mins ago | IN | 0.00739 ETH | 0.00001115 | ||||
Fulfill Advanced... | 527398 | 8 mins ago | IN | 0.0091 ETH | 0.00001192 | ||||
Fulfill Advanced... | 527347 | 8 mins ago | IN | 0.242 ETH | 0.00001276 | ||||
Fulfill Advanced... | 527257 | 10 mins ago | IN | 0.00739 ETH | 0.00001214 | ||||
Fulfill Advanced... | 527173 | 11 mins ago | IN | 0.24 ETH | 0.00001196 | ||||
Fulfill Availabl... | 527165 | 12 mins ago | IN | 0.01478 ETH | 0.00002109 | ||||
Fulfill Advanced... | 527147 | 12 mins ago | IN | 0.0102 ETH | 0.00001184 | ||||
Fulfill Advanced... | 527136 | 12 mins ago | IN | 0.24 ETH | 0.00001239 | ||||
Fulfill Advanced... | 527128 | 12 mins ago | IN | 0.015 ETH | 0.0000118 | ||||
Fulfill Advanced... | 527109 | 12 mins ago | IN | 0.015 ETH | 0.00001176 | ||||
Fulfill Advanced... | 527086 | 13 mins ago | IN | 0.0029 ETH | 0.00001204 | ||||
Cancel | 527052 | 13 mins ago | IN | 0 ETH | 0.00000506 | ||||
Fulfill Advanced... | 527052 | 13 mins ago | IN | 0.0005 ETH | 0.00000952 | ||||
Fulfill Availabl... | 527035 | 14 mins ago | IN | 0.0522 ETH | 0.00002456 | ||||
Fulfill Advanced... | 527031 | 14 mins ago | IN | 0.0002 ETH | 0.00000845 | ||||
Fulfill Advanced... | 527030 | 14 mins ago | IN | 0.0002 ETH | 0.00000953 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
527869 | 10 secs ago | 0.0000194 ETH | ||||
527869 | 10 secs ago | 0.0009506 ETH | ||||
527869 | 10 secs ago | 0.0009506 ETH | ||||
527869 | 10 secs ago | 0.00097 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.00022 ETH | ||||
527843 | 36 secs ago | 0.01078 ETH | ||||
527843 | 36 secs ago | 0.000216 ETH | ||||
527843 | 36 secs ago | 0.010584 ETH |
Loading...
Loading
This contract contains unverified libraries: SignatureChecker
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
Seaport
Compiler Version
v0.8.24+commit.e11b9ed9
ZkSolc Version
v1.5.3
Optimization Enabled:
Yes with Mode 3
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {ConsiderationInterface} from "seaport-types/src/interfaces/ConsiderationInterface.sol"; import {OrderType} from "seaport-types/src/lib/ConsiderationEnums.sol"; import {AdvancedOrder, BasicOrderParameters, CriteriaResolver, Execution, Fulfillment, FulfillmentComponent, Order, OrderComponents, OrderParameters} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {ReferenceOrderCombiner} from "./lib/ReferenceOrderCombiner.sol"; import {OrderToExecute} from "./lib/ReferenceConsiderationStructs.sol"; /** * @title Seaport * @author 0age * @custom:coauthor d1ll0n * @custom:coauthor transmissions11 * @custom:coauthor James Wenzel * @custom:coauthor Daniel Viau * @custom:version 1.6-reference * @notice Consideration is a generalized native token/ERC20/ERC721/ERC1155 * marketplace. It minimizes external calls to the greatest extent * possible and provides lightweight methods for common routes as well * as more flexible methods for composing advanced orders or groups of * orders. Each order contains an arbitrary number of items that may be * spent (the "offer") along with an arbitrary number of items that must * be received back by the indicated recipients (the "consideration"). */ contract Seaport is ConsiderationInterface, ReferenceOrderCombiner { /** * @notice Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceOrderCombiner(conduitController) {} /** * @notice Accept native token transfers during execution that may then be * used to facilitate native token transfers, where any tokens that * remain will be transferred to the caller. Native tokens are only * acceptable mid-fulfillment (and not during basic fulfillment). */ receive() external payable { // Ensure the reentrancy guard is currently set to accept native tokens. _assertAcceptingNativeTokens(); } /** * @notice Fulfill an order offering an ERC20, ERC721, or ERC1155 item by * supplying Ether (or other native tokens), ERC20 tokens, an ERC721 * item, or an ERC1155 item as consideration. Six permutations are * supported: Native token to ERC721, Native token to ERC1155, ERC20 * to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and ERC1155 to * ERC20 (with native tokens supplied as msg.value). For an order to * be eligible for fulfillment via this method, it must contain a * single offer item (though that item may have a greater amount if * the item is not an ERC721). An arbitrary number of "additional * recipients" may also be supplied which will each receive native * tokens or ERC20 items from the fulfiller as consideration. Refer * to the documentation for a more comprehensive summary of how to * utilize with this method and what orders are compatible with it. * * @param parameters Additional information on the fulfilled order. Note * that the offerer and the fulfiller must first approve * this contract (or their chosen conduit if indicated) * before any tokens can be transferred. Also note that * contract recipients of ERC1155 consideration items must * implement `onERC1155Received` in order to receive those * items. * * @return fulfilled A boolean indicating whether the order has been * fulfilled. */ function fulfillBasicOrder( BasicOrderParameters calldata parameters ) external payable override nonReentrant(false) returns (bool fulfilled) { // Validate and fulfill the basic order. fulfilled = _validateAndFulfillBasicOrder(parameters); } /** * @notice Fulfill an order offering an ERC20, ERC721, or ERC1155 item by * supplying Ether (or other native tokens), ERC20 tokens, an ERC721 * item, or an ERC1155 item as consideration. Six permutations are * supported: Native token to ERC721, Native token to ERC1155, ERC20 * to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and ERC1155 to * ERC20 (with native tokens supplied as msg.value). For an order to * be eligible for fulfillment via this method, it must contain a * single offer item (though that item may have a greater amount if * the item is not an ERC721). An arbitrary number of "additional * recipients" may also be supplied which will each receive native * tokens or ERC20 items from the fulfiller as consideration. Refer * to the documentation for a more comprehensive summary of how to * utilize with this method and what orders are compatible with it. * Note that this function costs less gas than `fulfillBasicOrder` * due to the zero bytes in the function selector (0x00000000) which * also results in earlier function dispatch. * * @param parameters Additional information on the fulfilled order. Note * that the offerer and the fulfiller must first approve * this contract (or their chosen conduit if indicated) * before any tokens can be transferred. Also note that * contract recipients of ERC1155 consideration items must * implement `onERC1155Received` in order to receive those * items. * * @return fulfilled A boolean indicating whether the order has been * fulfilled. */ function fulfillBasicOrder_efficient_6GL6yc( BasicOrderParameters calldata parameters ) external payable override nonReentrant(false) returns (bool fulfilled) { // Validate and fulfill the basic order. fulfilled = _validateAndFulfillBasicOrder(parameters); } /** * @notice Fulfill an order with an arbitrary number of items for offer and * consideration. Note that this function does not support * criteria-based orders or partial filling of orders (though * filling the remainder of a partially-filled order is supported). * * @param order The order to fulfill. Note that both the * offerer and the fulfiller must first approve * this contract (or the corresponding conduit if * indicated) to transfer any relevant tokens on * their behalf and that contracts must implement * `onERC1155Received` to receive ERC1155 tokens * as consideration. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used (and direct approvals set on * Consideration). * * @return fulfilled A boolean indicating whether the order has been * fulfilled. */ function fulfillOrder( Order calldata order, bytes32 fulfillerConduitKey ) external payable override nonReentrant(order.parameters.orderType == OrderType.CONTRACT) returns (bool fulfilled) { // Convert order to "advanced" order, then validate and fulfill it. fulfilled = _validateAndFulfillAdvancedOrder( _convertOrderToAdvanced(order), new CriteriaResolver[](0), // No criteria resolvers supplied. fulfillerConduitKey, msg.sender ); } /** * @notice Fill an order, fully or partially, with an arbitrary number of * items for offer and consideration alongside criteria resolvers * containing specific token identifiers and associated proofs. * * @param advancedOrder The order to fulfill along with the fraction * of the order to attempt to fill. Note that * both the offerer and the fulfiller must first * approve this contract (or their proxy if * indicated by the order) to transfer any * relevant tokens on their behalf and that * contracts must implement `onERC1155Received` * to receive ERC1155 tokens as consideration. * Also note that all offer and consideration * components must have no remainder after * multiplication of the respective amount with * the supplied fraction for the partial fill to * be considered valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a proof * that the supplied token identifier is * contained in the merkle root held by the item * in question's criteria element. Note that an * empty criteria indicates that any * (transferable) token identifier on the token * in question is valid and that no associated * proof needs to be supplied. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used (and direct approvals set on * Consideration). * @param recipient The intended recipient for all received items, * with `address(0)` indicating that the caller * should receive the items. * * @return fulfilled A boolean indicating whether the order has been * fulfilled. */ function fulfillAdvancedOrder( AdvancedOrder calldata advancedOrder, CriteriaResolver[] calldata criteriaResolvers, bytes32 fulfillerConduitKey, address recipient ) external payable override nonReentrant(advancedOrder.parameters.orderType == OrderType.CONTRACT) returns (bool fulfilled) { // Validate and fulfill the order. fulfilled = _validateAndFulfillAdvancedOrder( advancedOrder, criteriaResolvers, fulfillerConduitKey, recipient == address(0) ? msg.sender : recipient ); } /** * @notice Attempt to fill a group of orders, each with an arbitrary number * of items for offer and consideration. Any order that is not * currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * Note that this function does not support criteria-based orders or * partial filling of orders (though filling the remainder of a * partially-filled order is supported). * * @param orders The orders to fulfill. Note that both * the offerer and the fulfiller must first * approve this contract (or the * corresponding conduit if indicated) to * transfer any relevant tokens on their * behalf and that contracts must implement * `onERC1155Received` to receive ERC1155 * tokens as consideration. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used (and * direct approvals set on Consideration). * @param maximumFulfilled The maximum number of orders to fulfill. * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. */ function fulfillAvailableOrders( Order[] calldata orders, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, uint256 maximumFulfilled ) external payable override nonReentrant(true) returns (bool[] memory availableOrders, Execution[] memory executions) { // Convert orders to "advanced" orders. AdvancedOrder[] memory advancedOrders = _convertOrdersToAdvanced( orders ); // Convert Advanced Orders to Orders To Execute OrderToExecute[] memory ordersToExecute = _convertAdvancedToOrdersToExecute( advancedOrders ); // Fulfill all available orders. return _fulfillAvailableAdvancedOrders( advancedOrders, ordersToExecute, new CriteriaResolver[](0), // No criteria resolvers supplied. offerFulfillments, considerationFulfillments, fulfillerConduitKey, msg.sender, maximumFulfilled ); } /** * @notice Attempt to fill a group of orders, fully or partially, with an * arbitrary number of items for offer and consideration per order * alongside criteria resolvers containing specific token * identifiers and associated proofs. Any order that is not * currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * * @param advancedOrders The orders to fulfill along with the * fraction of those orders to attempt to * fill. Note that both the offerer and the * fulfiller must first approve this * contract (or their proxy if indicated by * the order) to transfer any relevant * tokens on their behalf and that * contracts must implement * `onERC1155Received` in order to receive * ERC1155 tokens as consideration. Also * note that all offer and consideration * components must have no remainder after * multiplication of the respective amount * with the supplied fraction for an * order's partial fill amount to be * considered valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a * proof that the supplied token identifier * is contained in the merkle root held by * the item in question's criteria element. * Note that an empty criteria indicates * that any (transferable) token * identifier on the token in question is * valid and that no associated proof needs * to be supplied. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used (and * direct approvals set on Consideration). * @param maximumFulfilled The maximum number of orders to fulfill. * * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. */ function fulfillAvailableAdvancedOrders( AdvancedOrder[] memory advancedOrders, CriteriaResolver[] calldata criteriaResolvers, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, address recipient, uint256 maximumFulfilled ) external payable override nonReentrant(true) returns (bool[] memory availableOrders, Execution[] memory executions) { // Convert Advanced Orders to Orders to Execute OrderToExecute[] memory ordersToExecute = _convertAdvancedToOrdersToExecute( advancedOrders ); // Fulfill all available orders. return _fulfillAvailableAdvancedOrders( advancedOrders, ordersToExecute, criteriaResolvers, offerFulfillments, considerationFulfillments, fulfillerConduitKey, recipient == address(0) ? msg.sender : recipient, maximumFulfilled ); } /** * @notice Match an arbitrary number of orders, each with an arbitrary * number of items for offer and consideration along with a set of * fulfillments allocating offer components to consideration * components. Note that this function does not support * criteria-based or partial filling of orders (though filling the * remainder of a partially-filled order is supported). * * @param orders The orders to match. Note that both the offerer and * fulfiller on each order must first approve this * contract (or their conduit if indicated by the * order) to transfer any relevant tokens on their * behalf and each consideration recipient must * implement `onERC1155Received` in order to receive * ERC1155 tokens. * @param fulfillments An array of elements allocating offer components to * consideration components. Note that each * consideration component must be fully met in order * for the match operation to be valid. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of this * array. */ function matchOrders( Order[] calldata orders, Fulfillment[] calldata fulfillments ) external payable override nonReentrant(true) returns (Execution[] memory executions) { // Convert to advanced, validate, and match orders using fulfillments. return _matchAdvancedOrders( _convertOrdersToAdvanced(orders), new CriteriaResolver[](0), // No criteria resolvers supplied. fulfillments, msg.sender ); } /** * @notice Match an arbitrary number of full or partial orders, each with an * arbitrary number of items for offer and consideration, supplying * criteria resolvers containing specific token identifiers and * associated proofs as well as fulfillments allocating offer * components to consideration components. * * @param advancedOrders The advanced orders to match. Note that both the * offerer and fulfiller on each order must first * approve this contract (or their proxy if * indicated by the order) to transfer any relevant * tokens on their behalf and each consideration * recipient must implement `onERC1155Received` in * order to receive ERC1155 tokens. Also note that * the offer and consideration components for each * order must have no remainder after multiplying * the respective amount with the supplied fraction * in order for the group of partial fills to be * considered valid. * @param criteriaResolvers An array where each element contains a reference * to a specific order as well as that order's * offer or consideration, a token identifier, and * a proof that the supplied token identifier is * contained in the order's merkle root. Note that * an empty root indicates that any (transferable) * token identifier is valid and that no associated * proof needs to be supplied. * @param fulfillments An array of elements allocating offer components * to consideration components. Note that each * consideration component must be fully met in * order for the match operation to be valid. * @param recipient The intended recipient for all unspent offer * item amounts, or the caller if the null address * is supplied. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of this * array. */ function matchAdvancedOrders( AdvancedOrder[] memory advancedOrders, CriteriaResolver[] calldata criteriaResolvers, Fulfillment[] calldata fulfillments, address recipient ) external payable override nonReentrant(true) returns (Execution[] memory executions) { // Validate and match the advanced orders using supplied fulfillments. return _matchAdvancedOrders( advancedOrders, criteriaResolvers, fulfillments, recipient == address(0) ? msg.sender : recipient ); } /** * @notice Cancel an arbitrary number of orders. Note that only the offerer * or the zone of a given order may cancel it. * * @param orders The orders to cancel. * * @return cancelled A boolean indicating whether the supplied orders have * been successfully cancelled. */ function cancel( OrderComponents[] calldata orders ) external override notEntered returns (bool cancelled) { // Cancel the orders. cancelled = _cancel(orders); } /** * @notice Validate an arbitrary number of orders, thereby registering them * as valid and allowing the fulfiller to skip verification. Note * that anyone can validate a signed order but only the offerer can * validate an order without supplying a signature. * * @param orders The orders to validate. * * @return validated A boolean indicating whether the supplied orders have * been successfully validated. */ function validate( Order[] calldata orders ) external override notEntered returns (bool validated) { // Validate the orders. validated = _validate(orders); } /** * @notice Cancel all orders from a given offerer with a given zone in bulk * by incrementing a counter. Note that only the offerer may * increment the counter. * * @return newCounter The new counter. */ function incrementCounter() external override notEntered returns (uint256 newCounter) { // Increment current counter for the supplied offerer. newCounter = _incrementCounter(); } /** * @notice Retrieve the order hash for a given order. * * @param order The components of the order. * * @return orderHash the order hash. */ function getOrderHash( OrderComponents calldata order ) external view override returns (bytes32 orderHash) { // Derive order hash by supplying order parameters along with the // counter. orderHash = _deriveOrderHash( OrderParameters( order.offerer, order.zone, order.offer, order.consideration, order.orderType, order.startTime, order.endTime, order.zoneHash, order.salt, order.conduitKey, order.consideration.length ), order.counter ); } /** * @notice Retrieve the status of a given order by hash, including whether * the order has been cancelled or validated and the fraction of the * order that has been filled. Since the _orderStatus[orderHash] * does not get set for contract orders, getOrderStatus will always * return (false, false, 0, 0) for those hashes. Note that this * function is susceptible to view reentrancy and so should be used * with care when calling from other contracts. * * @param orderHash The order hash in question. * * @return isValidated A boolean indicating whether the order in question * has been validated (i.e. previously approved or * partially filled). * @return isCancelled A boolean indicating whether the order in question * has been cancelled. * @return totalFilled The total portion of the order that has been filled * (i.e. the "numerator"). * @return totalSize The total size of the order that is either filled or * unfilled (i.e. the "denominator"). */ function getOrderStatus( bytes32 orderHash ) external view override returns ( bool isValidated, bool isCancelled, uint256 totalFilled, uint256 totalSize ) { // Retrieve the order status using the order hash. return _getOrderStatus(orderHash); } /** * @notice Retrieve the current counter for a given offerer. * * @param offerer The offerer in question. * * @return counter The current counter. */ function getCounter( address offerer ) external view override returns (uint256 counter) { // Return the counter for the supplied offerer. counter = _getCounter(offerer); } /** * @notice Retrieve configuration information for this contract. * * @return version The contract version. * @return domainSeparator The domain separator for this contract. * @return conduitController The conduit Controller set for this contract. */ function information() external view override returns ( string memory version, bytes32 domainSeparator, address conduitController ) { // Return the information for this contract. return _information(); } /** * @dev Gets the contract offerer nonce for the specified contract offerer. * Note that this function is susceptible to view reentrancy and so * should be used with care when calling from other contracts. * * @param contractOfferer The contract offerer for which to get the nonce. * * @return nonce The contract offerer nonce. */ function getContractOffererNonce( address contractOfferer ) external view override returns (uint256 nonce) { nonce = _contractNonces[contractOfferer]; } /** * @notice Retrieve the name of this contract. * * @return contractName The name of this contract. */ function name() external pure override returns (string memory contractName) { // Return the name of the contract. contractName = _name(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ItemType, OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { ReceivedItem, SpentItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { ConduitTransfer } from "seaport-types/src/conduit/lib/ConduitStructs.sol"; // This file should only be used by the Reference Implementation /** * @dev A struct used to hold the numerator and denominator of an order in-memory * during validation, before it is written to storage when updating order * status. */ struct StoredFractions { uint256 storedNumerator; uint256 storedDenominator; } /** * @dev An intermediate struct used to hold information about an order after * validation to prepare for execution. */ struct OrderValidation { bytes32 orderHash; uint256 newNumerator; uint256 newDenominator; OrderToExecute orderToExecute; } /** * @dev A struct used to hold the parameters used to validate an order. */ struct OrderValidationParams { bool revertOnInvalid; uint256 maximumFulfilled; address recipient; } /** * @dev A struct used to hold Consideration Indexes and Fulfillment validity. */ struct ConsiderationItemIndicesAndValidity { uint256 orderIndex; uint256 itemIndex; bool invalidFulfillment; bool missingItemAmount; } /** * @dev A struct used to hold all ItemTypes/Token of a Basic Order Fulfillment * used in _prepareBasicFulfillmentFromCalldata */ struct FulfillmentItemTypes { OrderType orderType; ItemType receivedItemType; ItemType additionalRecipientsItemType; address additionalRecipientsToken; ItemType offeredItemType; } /** * @dev A struct used to hold all the hashes of a Basic Order Fulfillment * used in _prepareBasicFulfillmentFromCalldata and _hashOrder */ struct BasicFulfillmentHashes { bytes32 typeHash; bytes32 orderHash; bytes32 offerItemsHash; bytes32[] considerationHashes; bytes32 receivedItemsHash; bytes32 receivedItemHash; bytes32 offerItemHash; } /** * @dev A struct that is an explicit version of advancedOrders without * memory optimization, that provides an array of spentItems * and receivedItems for fulfillment and event emission. */ struct OrderToExecute { address offerer; SpentItem[] spentItems; // Offer ReceivedItem[] receivedItems; // Consideration bytes32 conduitKey; uint120 numerator; uint256[] spentItemOriginalAmounts; uint256[] receivedItemOriginalAmounts; } /** * @dev A struct containing the data used to apply a * fraction to an order. */ struct FractionData { uint256 numerator; // The portion of the order that should be filled. uint256 denominator; // The total size of the order bytes32 fulfillerConduitKey; // The fulfiller's conduit key. uint256 startTime; // The start time of the order. uint256 endTime; // The end time of the order. } /** * @dev A struct containing conduit transfer data and its * corresponding conduitKey. */ struct AccumulatorStruct { bytes32 conduitKey; ConduitTransfer[] transfers; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ItemType, OrderType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { AdvancedOrder, ConsiderationItem, CriteriaResolver, Execution, Fulfillment, FulfillmentComponent, OfferItem, OrderParameters, ReceivedItem, SpentItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { SeaportInterface } from "seaport-types/src/interfaces/SeaportInterface.sol"; import { AccumulatorStruct, OrderToExecute, StoredFractions, OrderValidation, OrderValidationParams } from "./ReferenceConsiderationStructs.sol"; import { ReferenceOrderFulfiller } from "./ReferenceOrderFulfiller.sol"; import { ReferenceFulfillmentApplier } from "./ReferenceFulfillmentApplier.sol"; /** * @title OrderCombiner * @author 0age * @notice OrderCombiner contains logic for fulfilling combinations of orders, * either by matching offer items to consideration items or by * fulfilling orders where available. */ contract ReferenceOrderCombiner is ReferenceOrderFulfiller, ReferenceFulfillmentApplier { /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceOrderFulfiller(conduitController) {} /** * @notice Internal function to attempt to fill a group of orders, fully or * partially, with an arbitrary number of items for offer and * consideration per order alongside criteria resolvers containing * specific token identifiers and associated proofs. Any order that * is not currently active, has already been fully filled, or has * been cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * * @param advancedOrders The orders to fulfill along with the * fraction of those orders to attempt to * fill. Note that both the offerer and the * fulfiller must first approve this * contract (or their proxy if indicated by * the order) to transfer any relevant * tokens on their behalf and that * contracts must implement * `onERC1155Received` in order to receive * ERC1155 tokens as consideration. Also * note that all offer and consideration * components must have no remainder after * multiplication of the respective amount * with the supplied fraction for an * order's partial fill amount to be * considered valid. * * @param ordersToExecute The orders to execute. This is an * explicit version of advancedOrders * without memory optimization, that * provides an array of spentItems and * receivedItems for fulfillment and * event emission. * * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a * proof that the supplied token identifier * is contained in the merkle root held by * the item in question's criteria element. * Note that an empty criteria indicates * that any (transferable) token * identifier on the token in question is * valid and that no associated proof needs * to be supplied. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used (and * direct approvals set on Consideration). * @param recipient The intended recipient for all received * items. * @param maximumFulfilled The maximum number of orders to fulfill. * * @return availableOrders An array of booleans indicating if each * order with an index corresponding to the * index of the returned boolean was * fulfillable or not. * @return executions An array of elements indicating the * sequence of transfers performed as part * of matching the given orders. */ function _fulfillAvailableAdvancedOrders( AdvancedOrder[] memory advancedOrders, OrderToExecute[] memory ordersToExecute, CriteriaResolver[] memory criteriaResolvers, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, address recipient, uint256 maximumFulfilled ) internal returns (bool[] memory availableOrders, Execution[] memory executions) { // Validate orders, apply amounts, & determine if they use conduits. ( bytes32[] memory orderHashes, bool containsNonOpen ) = _validateOrdersAndPrepareToFulfill( advancedOrders, ordersToExecute, criteriaResolvers, OrderValidationParams( false, // Signifies that invalid orders should NOT revert. maximumFulfilled, recipient ) ); // Execute transfers. (availableOrders, executions) = _executeAvailableFulfillments( advancedOrders, ordersToExecute, offerFulfillments, considerationFulfillments, fulfillerConduitKey, recipient, orderHashes, containsNonOpen ); // Return order fulfillment details and executions. return (availableOrders, executions); } /** * @dev Internal function to validate a group of orders, update their * statuses, reduce amounts by their previously filled fractions, apply * criteria resolvers, and emit OrderFulfilled events. * * @param advancedOrders The advanced orders to validate and reduce by * their previously filled amounts. * @param ordersToExecute The orders to validate and execute. * @param criteriaResolvers An array where each element contains a reference * to a specific order as well as that order's * offer or consideration, a token identifier, and * a proof that the supplied token identifier is * contained in the order's merkle root. Note that * a root of zero indicates that any transferable * token identifier is valid and that no proof * needs to be supplied. * @param orderValidationParams Various order validation params. * * @return orderHashes The hashes of the orders being fulfilled. * @return containsNonOpen A boolean indicating whether any restricted or * contract orders are present within the provided * array of advanced orders. */ function _validateOrdersAndPrepareToFulfill( AdvancedOrder[] memory advancedOrders, OrderToExecute[] memory ordersToExecute, CriteriaResolver[] memory criteriaResolvers, OrderValidationParams memory orderValidationParams ) internal returns (bytes32[] memory orderHashes, bool containsNonOpen) { // Track the order hash for each order being fulfilled. orderHashes = new bytes32[](advancedOrders.length); // Declare a variable for tracking whether native offer items are // present on orders that are not contract orders. bool anyNativeOfferItemsOnNonContractOrders; StoredFractions[] memory storedFractions = new StoredFractions[]( advancedOrders.length ); // Iterate over each order. for (uint256 i = 0; i < advancedOrders.length; ++i) { // Retrieve the current order. AdvancedOrder memory advancedOrder = advancedOrders[i]; // Validate the order and determine fraction to fill. OrderValidation memory orderValidation = _validateOrder( advancedOrder, orderValidationParams.revertOnInvalid ); // Do not track hash or adjust prices if order is not fulfilled. if (orderValidation.newNumerator == 0) { // Mark fill fraction as zero if the order is not fulfilled. advancedOrder.numerator = 0; // Mark fill fraction as zero as the order will not be used. orderValidation.orderToExecute.numerator = 0; ordersToExecute[i] = orderValidation.orderToExecute; // Continue iterating through the remaining orders. continue; } // Otherwise, track the order hash in question. orderHashes[i] = orderValidation.orderHash; // Store the numerator and denominator for the order status. storedFractions[i] = StoredFractions({ storedNumerator: orderValidation.newNumerator, storedDenominator: orderValidation.newDenominator }); { // Retrieve array of offer items for the order in question. OfferItem[] memory offer = advancedOrder.parameters.offer; // Determine the order type, used to check for eligibility for // native token offer items as well as for the presence of // restricted and contract orders (or non-open orders). OrderType orderType = advancedOrder.parameters.orderType; { bool isNonContractOrder = orderType != OrderType.CONTRACT; bool isNonOpenOrder = orderType != OrderType.FULL_OPEN && orderType != OrderType.PARTIAL_OPEN; if (containsNonOpen == true || isNonOpenOrder == true) { containsNonOpen = true; } // Iterate over each offer item on the order. for (uint256 j = 0; j < offer.length; ++j) { // Retrieve the offer item. OfferItem memory offerItem = offer[j]; // Determine if there are any native offer items on // non-contract orders. anyNativeOfferItemsOnNonContractOrders = anyNativeOfferItemsOnNonContractOrders || (offerItem.itemType == ItemType.NATIVE && isNonContractOrder); // Apply order fill fraction to offer item end amount. uint256 endAmount = _getFraction( orderValidation.newNumerator, orderValidation.newDenominator, offerItem.endAmount ); // Reuse same fraction if start & end amounts are equal. if (offerItem.startAmount == offerItem.endAmount) { // Apply derived amount to both start & end amount. offerItem.startAmount = endAmount; } else { // Apply order fill fraction to item start amount. offerItem.startAmount = _getFraction( orderValidation.newNumerator, orderValidation.newDenominator, offerItem.startAmount ); } // Update end amount in memory to match derived amount. offerItem.endAmount = endAmount; // Adjust offer amount using current time; round down. offerItem.startAmount = _locateCurrentAmount( offerItem.startAmount, offerItem.endAmount, advancedOrder.parameters.startTime, advancedOrder.parameters.endTime, false // Round down. ); // Modify the OrderToExecute Spent Item Amount. orderValidation .orderToExecute .spentItems[j] .amount = offerItem.startAmount; // Modify the OrderToExecute Spent Item Original amount. orderValidation.orderToExecute.spentItemOriginalAmounts[ j ] = (offerItem.startAmount); } } { // Get array of consideration items for order in question. ConsiderationItem[] memory consideration = ( advancedOrder.parameters.consideration ); // Iterate over each consideration item on the order. for (uint256 j = 0; j < consideration.length; ++j) { // Retrieve the consideration item. ConsiderationItem memory considerationItem = ( consideration[j] ); // Apply fraction to consideration item end amount. uint256 endAmount = _getFraction( orderValidation.newNumerator, orderValidation.newDenominator, considerationItem.endAmount ); // Reuse same fraction if start & end amounts are equal. if ( considerationItem.startAmount == (considerationItem.endAmount) ) { // Apply derived amount to both start & end amount. considerationItem.startAmount = endAmount; } else { // Apply fraction to item start amount. considerationItem.startAmount = _getFraction( orderValidation.newNumerator, orderValidation.newDenominator, considerationItem.startAmount ); } uint256 currentAmount = ( _locateCurrentAmount( considerationItem.startAmount, endAmount, advancedOrder.parameters.startTime, advancedOrder.parameters.endTime, true // round up ) ); considerationItem.startAmount = currentAmount; // Modify the OrderToExecute Received item amount. orderValidation .orderToExecute .receivedItems[j] .amount = considerationItem.startAmount; // Modify OrderToExecute Received item original amount. orderValidation .orderToExecute .receivedItemOriginalAmounts[j] = ( considerationItem.startAmount ); } } } ordersToExecute[i] = orderValidation.orderToExecute; } if ( anyNativeOfferItemsOnNonContractOrders && (msg.sig != SeaportInterface.matchAdvancedOrders.selector && msg.sig != SeaportInterface.matchOrders.selector) ) { revert InvalidNativeOfferItem(); } // Apply criteria resolvers to each order as applicable. _applyCriteriaResolvers( advancedOrders, ordersToExecute, criteriaResolvers ); bool someOrderAvailable; // Iterate over each order to check authorization status (for restricted // orders), generate orders (for contract orders), and emit events (for // all available orders) signifying that they have been fulfilled. for (uint256 i = 0; i < advancedOrders.length; ++i) { // Do not emit an event if no order hash is present. if (orderHashes[i] == bytes32(0)) { continue; } // Determine if max number orders have already been fulfilled. if (orderValidationParams.maximumFulfilled == 0) { orderHashes[i] = bytes32(0); ordersToExecute[i].numerator = 0; // Continue iterating through the remaining orders. continue; } // Retrieve parameters for the order in question. OrderParameters memory orderParameters = ( advancedOrders[i].parameters ); // Ensure restricted orders have valid submitter or pass zone check. ( bool valid /* bool checked */, ) = _checkRestrictedAdvancedOrderAuthorization( advancedOrders[i], ordersToExecute[i], _shorten(orderHashes, i), orderHashes[i], orderValidationParams.revertOnInvalid ); if (!valid) { orderHashes[i] = bytes32(0); ordersToExecute[i].numerator = 0; continue; } // Update status if the order is still valid or skip if not checked if (orderParameters.orderType != OrderType.CONTRACT) { if ( !_updateStatus( orderHashes[i], storedFractions[i].storedNumerator, storedFractions[i].storedDenominator, _revertOnFailedUpdate( orderParameters, orderValidationParams.revertOnInvalid ) ) ) { orderHashes[i] = bytes32(0); ordersToExecute[i].numerator = 0; continue; } } else { bytes32 orderHash = _getGeneratedOrder( ordersToExecute[i], orderParameters, advancedOrders[i].extraData, orderValidationParams.revertOnInvalid ); orderHashes[i] = orderHash; if (orderHash == bytes32(0)) { ordersToExecute[i].numerator = 0; continue; } } // Decrement the number of fulfilled orders. orderValidationParams.maximumFulfilled--; // Get the array of spentItems from the orderToExecute struct. SpentItem[] memory spentItems = ordersToExecute[i].spentItems; // Get the array of spent receivedItems from the // orderToExecute struct. ReceivedItem[] memory receivedItems = ( ordersToExecute[i].receivedItems ); // Emit an event signifying that the order has been fulfilled. emit OrderFulfilled( orderHashes[i], orderParameters.offerer, orderParameters.zone, orderValidationParams.recipient, spentItems, receivedItems ); someOrderAvailable = true; } // Revert if no orders are available. if (!someOrderAvailable) { revert NoSpecifiedOrdersAvailable(); } } function _shorten( bytes32[] memory orderHashes, uint256 index ) internal pure returns (bytes32[] memory) { bytes32[] memory shortened = new bytes32[](index); for (uint256 i = 0; i < index; i++) { shortened[i] = orderHashes[i]; } return shortened; } /** * @dev Internal function to fulfill a group of validated orders, fully or * partially, with an arbitrary number of items for offer and * consideration per order and to execute transfers. Any order that is * not currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration items * will then be aggregated where possible as indicated by the supplied * offer and consideration component arrays and aggregated items will * be transferred to the fulfiller or to each intended recipient, * respectively. Note that a failing item transfer or an issue with * order formatting will cause the entire batch to fail. * * @param ordersToExecute The orders to execute. This is an * explicit version of advancedOrders * without memory optimization, that * provides an array of spentItems and * receivedItems for fulfillment and * event emission. * Note that both the offerer and the * fulfiller must first approve this * contract (or the conduit if indicated * by the order) to transfer any relevant * tokens on their behalf and that * contracts must implement * `onERC1155Received` in order to receive * ERC1155 tokens as consideration. Also * note that all offer and consideration * components must have no remainder after * multiplication of the respective amount * with the supplied fraction for an * order's partial fill amount to be * considered valid. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used (and * direct approvals set on Consideration). * @param recipient The intended recipient for all received * items. * @param orderHashes An array of order hashes for each order. * @param containsNonOpen A boolean indicating whether any restricted or * contract orders are present within the provided * array of advanced orders. * * @return availableOrders An array of booleans indicating if each * order with an index corresponding to the * index of the returned boolean was * fulfillable or not. * @return executions An array of elements indicating the * sequence of transfers performed as part * of matching the given orders. */ function _executeAvailableFulfillments( AdvancedOrder[] memory advancedOrders, OrderToExecute[] memory ordersToExecute, FulfillmentComponent[][] memory offerFulfillments, FulfillmentComponent[][] memory considerationFulfillments, bytes32 fulfillerConduitKey, address recipient, bytes32[] memory orderHashes, bool containsNonOpen ) internal returns (bool[] memory availableOrders, Execution[] memory executions) { // Retrieve length of offer fulfillments array and place on the stack. uint256 totalOfferFulfillments = offerFulfillments.length; // Retrieve length of consideration fulfillments array & place on stack. uint256 totalConsiderationFulfillments = ( considerationFulfillments.length ); // Allocate an execution for each offer and consideration fulfillment. executions = new Execution[]( totalOfferFulfillments + totalConsiderationFulfillments ); // Iterate over each offer fulfillment. for (uint256 i = 0; i < totalOfferFulfillments; ++i) { // Derive aggregated execution corresponding with fulfillment and // assign the execution to the executions array. executions[i] = _aggregateAvailable( ordersToExecute, Side.OFFER, offerFulfillments[i], fulfillerConduitKey, recipient ); } // Iterate over each consideration fulfillment. for (uint256 i = 0; i < totalConsiderationFulfillments; ++i) { // Derive aggregated execution corresponding with fulfillment and // assign the execution to the executions array. executions[i + totalOfferFulfillments] = _aggregateAvailable( ordersToExecute, Side.CONSIDERATION, considerationFulfillments[i], fulfillerConduitKey, address(0) // unused ); } // Perform final checks and compress executions into standard and batch. availableOrders = _performFinalChecksAndExecuteOrders( advancedOrders, ordersToExecute, executions, orderHashes, recipient, containsNonOpen ); return (availableOrders, executions); } /** * @dev Internal function to perform a final check that each consideration * item for an arbitrary number of fulfilled orders has been met and to * trigger associated executions, transferring the respective items. * * @param ordersToExecute The orders to check and perform executions. * @param executions An array of uncompressed elements indicating * the sequence of transfers to perform when * fulfilling the given orders. * * @param executions An array of elements indicating the sequence of * transfers to perform when fulfilling the given * orders. * @param orderHashes An array of order hashes for each order. * @param containsNonOpen A boolean indicating whether any restricted or * contract orders are present within the provided * array of advanced orders. * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. */ function _performFinalChecksAndExecuteOrders( AdvancedOrder[] memory advancedOrders, OrderToExecute[] memory ordersToExecute, Execution[] memory executions, bytes32[] memory orderHashes, address recipient, bool containsNonOpen ) internal returns (bool[] memory availableOrders) { // Retrieve the length of the advanced orders array and place on stack. uint256 totalOrders = advancedOrders.length; // Initialize array for tracking available orders. availableOrders = new bool[](totalOrders); // Create the accumulator struct. AccumulatorStruct memory accumulatorStruct; { // Iterate over each execution. for (uint256 i = 0; i < executions.length; ++i) { // Retrieve the execution and the associated received item. Execution memory execution = executions[i]; ReceivedItem memory item = execution.item; // Skip transfers if the execution amount is zero. if (item.amount == 0) { continue; } // If execution transfers native tokens, reduce value available. if (item.itemType == ItemType.NATIVE) { // Ensure that sufficient native tokens are still available. if (item.amount > address(this).balance) { revert InsufficientNativeTokensSupplied(); } } // Transfer the item specified by the execution. _transfer( item, execution.offerer, execution.conduitKey, accumulatorStruct ); } } // Duplicate recipient onto stack to avoid stack-too-deep. address _recipient = recipient; // Iterate over orders to ensure all consideration items are met. for (uint256 i = 0; i < ordersToExecute.length; ++i) { // Retrieve the order in question. OrderToExecute memory orderToExecute = ordersToExecute[i]; // Skip consideration item checks for order if not fulfilled. if (orderToExecute.numerator == 0) { // Note: orders do not need to be marked as unavailable as a // new memory region has been allocated. Review carefully if // altering compiler version or managing memory manually. continue; } // Mark the order as available. availableOrders[i] = true; // Retrieve the original order in question. AdvancedOrder memory advancedOrder = advancedOrders[i]; // Retrieve the order parameters. OrderParameters memory parameters = advancedOrder.parameters; { // Retrieve offer items. SpentItem[] memory offer = orderToExecute.spentItems; // Read length of offer array & place on the stack. uint256 totalOfferItems = offer.length; // Iterate over each offer item to restore it. for (uint256 j = 0; j < totalOfferItems; ++j) { SpentItem memory offerSpentItem = offer[j]; // Retrieve remaining amount on the offer item. uint256 unspentAmount = offerSpentItem.amount; // Retrieve original amount on the offer item. uint256 originalAmount = ( orderToExecute.spentItemOriginalAmounts[j] ); // Transfer to recipient if unspent amount is not zero. // Note that the transfer will not be reflected in the // executions array. if (unspentAmount != 0) { _transfer( _convertSpentItemToReceivedItemWithRecipient( offerSpentItem, _recipient ), parameters.offerer, parameters.conduitKey, accumulatorStruct ); } // Restore original amount on the offer item. offerSpentItem.amount = originalAmount; } } { // Retrieve consideration items to ensure they are fulfilled. ReceivedItem[] memory consideration = ( orderToExecute.receivedItems ); // Iterate over each consideration item to ensure it is met. for (uint256 j = 0; j < consideration.length; ++j) { // Retrieve remaining amount on the consideration item. uint256 unmetAmount = consideration[j].amount; // Revert if the remaining amount is not zero. if (unmetAmount != 0) { revert ConsiderationNotMet(i, j, unmetAmount); } // Restore original amount. consideration[j].amount = ( orderToExecute.receivedItemOriginalAmounts[j] ); } } } // Trigger any remaining accumulated transfers via call to the // conduit. _triggerIfArmed(accumulatorStruct); // If any native token remains after fulfillments, return it to the // caller. if (address(this).balance != 0) { _transferNativeTokens(payable(msg.sender), address(this).balance); } // If any restricted or contract orders are present in the group of // orders being fulfilled, perform any validateOrder or ratifyOrder // calls after all executions and related transfers are complete. if (containsNonOpen) { // Iterate over orders to ensure all consideration items are met. for (uint256 i = 0; i < ordersToExecute.length; ++i) { // Retrieve the order in question. OrderToExecute memory orderToExecute = ordersToExecute[i]; // Skip consideration item checks for order if not fulfilled. if (orderToExecute.numerator == 0) { continue; } // Retrieve the original order in question. AdvancedOrder memory advancedOrder = advancedOrders[i]; // Ensure restricted orders have valid submitter or pass check. _assertRestrictedAdvancedOrderValidity( advancedOrder, orderToExecute, orderHashes, orderHashes[i], advancedOrder.parameters.zoneHash, advancedOrder.parameters.orderType, orderToExecute.offerer, advancedOrder.parameters.zone ); } } // Return the array containing available orders. return availableOrders; } /** * @dev Internal function to convert a spent item to an equivalent * ReceivedItem with a specified recipient. * * @param offerItem The "offerItem" represented by a SpentItem * struct. * @param recipient The intended recipient of the converted * ReceivedItem * * @return ReceivedItem The derived ReceivedItem including the * specified recipient. */ function _convertSpentItemToReceivedItemWithRecipient( SpentItem memory offerItem, address recipient ) internal pure returns (ReceivedItem memory) { address payable _recipient; _recipient = payable(recipient); return ReceivedItem( offerItem.itemType, offerItem.token, offerItem.identifier, offerItem.amount, _recipient ); } /** * @dev Internal function to match an arbitrary number of full or partial * orders, each with an arbitrary number of items for offer and * consideration, supplying criteria resolvers containing specific * token identifiers and associated proofs as well as fulfillments * allocating offer components to consideration components. * * @param advancedOrders The advanced orders to match. Note that both the * offerer and fulfiller on each order must first * approve this contract (or their conduit if * indicated by the order) to transfer any relevant * tokens on their behalf and each consideration * recipient must implement `onERC1155Received` in * order to receive ERC1155 tokens. Also note that * the offer and consideration components for each * order must have no remainder after multiplying * the respective amount with the supplied fraction * in order for the group of partial fills to be * considered valid. * @param criteriaResolvers An array where each element contains a reference * to a specific order as well as that order's * offer or consideration, a token identifier, and * a proof that the supplied token identifier is * contained in the order's merkle root. Note that * an empty root indicates that any (transferable) * token identifier is valid and that no associated * proof needs to be supplied. * @param fulfillments An array of elements allocating offer components * to consideration components. Note that each * consideration component must be fully met in * order for the match operation to be valid. * @param recipient The intended recipient for all unspent offer * item amounts. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the * given orders. */ function _matchAdvancedOrders( AdvancedOrder[] memory advancedOrders, CriteriaResolver[] memory criteriaResolvers, Fulfillment[] calldata fulfillments, address recipient ) internal returns (Execution[] memory executions) { // Convert Advanced Orders to Orders to Execute OrderToExecute[] memory ordersToExecute = ( _convertAdvancedToOrdersToExecute(advancedOrders) ); // Validate orders, apply amounts, & determine if they utilize conduits. ( bytes32[] memory orderHashes, bool containsNonOpen ) = _validateOrdersAndPrepareToFulfill( advancedOrders, ordersToExecute, criteriaResolvers, OrderValidationParams( true, // Signifies that invalid orders should revert. advancedOrders.length, recipient ) ); // Emit OrdersMatched event. emit OrdersMatched(orderHashes); // Fulfill the orders using the supplied fulfillments. return _fulfillAdvancedOrders( advancedOrders, ordersToExecute, fulfillments, orderHashes, recipient, containsNonOpen ); } /** * @dev Internal function to fulfill an arbitrary number of orders, either * full or partial, after validating, adjusting amounts, and applying * criteria resolvers. * * @param ordersToExecute The orders to match, including a fraction to * attempt to fill for each order. * @param fulfillments An array of elements allocating offer * components to consideration components. Note * that the final amount of each consideration * component must be zero for a match operation to * be considered valid. * @param orderHashes An array of order hashes for each order. * * @param containsNonOpen A boolean indicating whether any restricted or * contract orders are present within the provided * array of advanced orders. * * @return executions An array of elements indicating the sequence * of transfers performed as part of * matching the given orders. */ function _fulfillAdvancedOrders( AdvancedOrder[] memory advancedOrders, OrderToExecute[] memory ordersToExecute, Fulfillment[] calldata fulfillments, bytes32[] memory orderHashes, address recipient, bool containsNonOpen ) internal returns (Execution[] memory executions) { // Retrieve fulfillments array length and place on the stack. uint256 totalFulfillments = fulfillments.length; // Allocate executions by fulfillment and apply them to each execution. executions = new Execution[](totalFulfillments); // Iterate over each fulfillment. for (uint256 i = 0; i < totalFulfillments; ++i) { /// Retrieve the fulfillment in question. Fulfillment calldata fulfillment = fulfillments[i]; // Derive the execution corresponding with the fulfillment and // assign the execution to the executions array. executions[i] = _applyFulfillment( ordersToExecute, fulfillment.offerComponents, fulfillment.considerationComponents, i ); } // Perform final checks and execute orders. _performFinalChecksAndExecuteOrders( advancedOrders, ordersToExecute, executions, orderHashes, recipient, containsNonOpen ); // Return executions. return executions; } /** * @dev Internal view function to determine whether a status update failure * should cause a revert or allow a skipped order. The call must revert * if an `authorizeOrder` call has been successfully performed and the * status update cannot be performed, regardless of whether the order * could be otherwise marked as skipped. Note that a revert is not * required on a failed update if the call originates from the zone, as * no `authorizeOrder` call is performed in that case. * * @param orderParameters The order parameters in question. * @param revertOnInvalid A boolean indicating whether the call should * revert for non-restricted order types. * * @return revertOnFailedUpdate A boolean indicating whether the order * should revert on a failed status update. */ function _revertOnFailedUpdate( OrderParameters memory orderParameters, bool revertOnInvalid ) internal view returns (bool revertOnFailedUpdate) { OrderType orderType = orderParameters.orderType; address zone = orderParameters.zone; return (revertOnInvalid || ((orderType == OrderType.FULL_RESTRICTED || orderType == OrderType.PARTIAL_RESTRICTED) && zone != msg.sender)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; enum OrderType { // 0: no partial fills, anyone can execute FULL_OPEN, // 1: partial fills supported, anyone can execute PARTIAL_OPEN, // 2: no partial fills, only offerer or zone can execute FULL_RESTRICTED, // 3: partial fills supported, only offerer or zone can execute PARTIAL_RESTRICTED, // 4: contract order type CONTRACT } enum BasicOrderType { // 0: no partial fills, anyone can execute ETH_TO_ERC721_FULL_OPEN, // 1: partial fills supported, anyone can execute ETH_TO_ERC721_PARTIAL_OPEN, // 2: no partial fills, only offerer or zone can execute ETH_TO_ERC721_FULL_RESTRICTED, // 3: partial fills supported, only offerer or zone can execute ETH_TO_ERC721_PARTIAL_RESTRICTED, // 4: no partial fills, anyone can execute ETH_TO_ERC1155_FULL_OPEN, // 5: partial fills supported, anyone can execute ETH_TO_ERC1155_PARTIAL_OPEN, // 6: no partial fills, only offerer or zone can execute ETH_TO_ERC1155_FULL_RESTRICTED, // 7: partial fills supported, only offerer or zone can execute ETH_TO_ERC1155_PARTIAL_RESTRICTED, // 8: no partial fills, anyone can execute ERC20_TO_ERC721_FULL_OPEN, // 9: partial fills supported, anyone can execute ERC20_TO_ERC721_PARTIAL_OPEN, // 10: no partial fills, only offerer or zone can execute ERC20_TO_ERC721_FULL_RESTRICTED, // 11: partial fills supported, only offerer or zone can execute ERC20_TO_ERC721_PARTIAL_RESTRICTED, // 12: no partial fills, anyone can execute ERC20_TO_ERC1155_FULL_OPEN, // 13: partial fills supported, anyone can execute ERC20_TO_ERC1155_PARTIAL_OPEN, // 14: no partial fills, only offerer or zone can execute ERC20_TO_ERC1155_FULL_RESTRICTED, // 15: partial fills supported, only offerer or zone can execute ERC20_TO_ERC1155_PARTIAL_RESTRICTED, // 16: no partial fills, anyone can execute ERC721_TO_ERC20_FULL_OPEN, // 17: partial fills supported, anyone can execute ERC721_TO_ERC20_PARTIAL_OPEN, // 18: no partial fills, only offerer or zone can execute ERC721_TO_ERC20_FULL_RESTRICTED, // 19: partial fills supported, only offerer or zone can execute ERC721_TO_ERC20_PARTIAL_RESTRICTED, // 20: no partial fills, anyone can execute ERC1155_TO_ERC20_FULL_OPEN, // 21: partial fills supported, anyone can execute ERC1155_TO_ERC20_PARTIAL_OPEN, // 22: no partial fills, only offerer or zone can execute ERC1155_TO_ERC20_FULL_RESTRICTED, // 23: partial fills supported, only offerer or zone can execute ERC1155_TO_ERC20_PARTIAL_RESTRICTED } enum BasicOrderRouteType { // 0: provide Ether (or other native token) to receive offered ERC721 item. ETH_TO_ERC721, // 1: provide Ether (or other native token) to receive offered ERC1155 item. ETH_TO_ERC1155, // 2: provide ERC20 item to receive offered ERC721 item. ERC20_TO_ERC721, // 3: provide ERC20 item to receive offered ERC1155 item. ERC20_TO_ERC1155, // 4: provide ERC721 item to receive offered ERC20 item. ERC721_TO_ERC20, // 5: provide ERC1155 item to receive offered ERC20 item. ERC1155_TO_ERC20 } enum ItemType { // 0: ETH on mainnet, MATIC on polygon, etc. NATIVE, // 1: ERC20 items (ERC777 and ERC20 analogues could also technically work) ERC20, // 2: ERC721 items ERC721, // 3: ERC1155 items ERC1155, // 4: ERC721 items where a number of tokenIds are supported ERC721_WITH_CRITERIA, // 5: ERC1155 items where a number of ids are supported ERC1155_WITH_CRITERIA } enum Side { // 0: Items that can be spent OFFER, // 1: Items that must be received CONSIDERATION }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { BasicOrderType, ItemType, OrderType, Side } from "./ConsiderationEnums.sol"; import { CalldataPointer, MemoryPointer } from "../helpers/PointerLibraries.sol"; /** * @dev An order contains eleven components: an offerer, a zone (or account that * can cancel the order or restrict who can fulfill the order depending on * the type), the order type (specifying partial fill support as well as * restricted order status), the start and end time, a hash that will be * provided to the zone when validating restricted orders, a salt, a key * corresponding to a given conduit, a counter, and an arbitrary number of * offer items that can be spent along with consideration items that must * be received by their respective recipient. */ struct OrderComponents { address offerer; address zone; OfferItem[] offer; ConsiderationItem[] consideration; OrderType orderType; uint256 startTime; uint256 endTime; bytes32 zoneHash; uint256 salt; bytes32 conduitKey; uint256 counter; } /** * @dev An offer item has five components: an item type (ETH or other native * tokens, ERC20, ERC721, and ERC1155, as well as criteria-based ERC721 and * ERC1155), a token address, a dual-purpose "identifierOrCriteria" * component that will either represent a tokenId or a merkle root * depending on the item type, and a start and end amount that support * increasing or decreasing amounts over the duration of the respective * order. */ struct OfferItem { ItemType itemType; address token; uint256 identifierOrCriteria; uint256 startAmount; uint256 endAmount; } /** * @dev A consideration item has the same five components as an offer item and * an additional sixth component designating the required recipient of the * item. */ struct ConsiderationItem { ItemType itemType; address token; uint256 identifierOrCriteria; uint256 startAmount; uint256 endAmount; address payable recipient; } /** * @dev A spent item is translated from a utilized offer item and has four * components: an item type (ETH or other native tokens, ERC20, ERC721, and * ERC1155), a token address, a tokenId, and an amount. */ struct SpentItem { ItemType itemType; address token; uint256 identifier; uint256 amount; } /** * @dev A received item is translated from a utilized consideration item and has * the same four components as a spent item, as well as an additional fifth * component designating the required recipient of the item. */ struct ReceivedItem { ItemType itemType; address token; uint256 identifier; uint256 amount; address payable recipient; } /** * @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155 * matching, a group of six functions may be called that only requires a * subset of the usual order arguments. Note the use of a "basicOrderType" * enum; this represents both the usual order type as well as the "route" * of the basic order (a simple derivation function for the basic order * type is `basicOrderType = orderType + (4 * basicOrderRoute)`.) */ struct BasicOrderParameters { // calldata offset address considerationToken; // 0x24 uint256 considerationIdentifier; // 0x44 uint256 considerationAmount; // 0x64 address payable offerer; // 0x84 address zone; // 0xa4 address offerToken; // 0xc4 uint256 offerIdentifier; // 0xe4 uint256 offerAmount; // 0x104 BasicOrderType basicOrderType; // 0x124 uint256 startTime; // 0x144 uint256 endTime; // 0x164 bytes32 zoneHash; // 0x184 uint256 salt; // 0x1a4 bytes32 offererConduitKey; // 0x1c4 bytes32 fulfillerConduitKey; // 0x1e4 uint256 totalOriginalAdditionalRecipients; // 0x204 AdditionalRecipient[] additionalRecipients; // 0x224 bytes signature; // 0x244 // Total length, excluding dynamic array data: 0x264 (580) } /** * @dev Basic orders can supply any number of additional recipients, with the * implied assumption that they are supplied from the offered ETH (or other * native token) or ERC20 token for the order. */ struct AdditionalRecipient { uint256 amount; address payable recipient; } /** * @dev The full set of order components, with the exception of the counter, * must be supplied when fulfilling more sophisticated orders or groups of * orders. The total number of original consideration items must also be * supplied, as the caller may specify additional consideration items. */ struct OrderParameters { address offerer; // 0x00 address zone; // 0x20 OfferItem[] offer; // 0x40 ConsiderationItem[] consideration; // 0x60 OrderType orderType; // 0x80 uint256 startTime; // 0xa0 uint256 endTime; // 0xc0 bytes32 zoneHash; // 0xe0 uint256 salt; // 0x100 bytes32 conduitKey; // 0x120 uint256 totalOriginalConsiderationItems; // 0x140 // offer.length // 0x160 } /** * @dev Orders require a signature in addition to the other order parameters. */ struct Order { OrderParameters parameters; bytes signature; } /** * @dev Advanced orders include a numerator (i.e. a fraction to attempt to fill) * and a denominator (the total size of the order) in addition to the * signature and other order parameters. It also supports an optional field * for supplying extra data; this data will be provided to the zone if the * order type is restricted and the zone is not the caller, or will be * provided to the offerer as context for contract order types. */ struct AdvancedOrder { OrderParameters parameters; uint120 numerator; uint120 denominator; bytes signature; bytes extraData; } /** * @dev Orders can be validated (either explicitly via `validate`, or as a * consequence of a full or partial fill), specifically cancelled (they can * also be cancelled in bulk via incrementing a per-zone counter), and * partially or fully filled (with the fraction filled represented by a * numerator and denominator). */ struct OrderStatus { bool isValidated; bool isCancelled; uint120 numerator; uint120 denominator; } /** * @dev A criteria resolver specifies an order, side (offer vs. consideration), * and item index. It then provides a chosen identifier (i.e. tokenId) * alongside a merkle proof demonstrating the identifier meets the required * criteria. */ struct CriteriaResolver { uint256 orderIndex; Side side; uint256 index; uint256 identifier; bytes32[] criteriaProof; } /** * @dev A fulfillment is applied to a group of orders. It decrements a series of * offer and consideration items, then generates a single execution * element. A given fulfillment can be applied to as many offer and * consideration items as desired, but must contain at least one offer and * at least one consideration that match. The fulfillment must also remain * consistent on all key parameters across all offer items (same offerer, * token, type, tokenId, and conduit preference) as well as across all * consideration items (token, type, tokenId, and recipient). */ struct Fulfillment { FulfillmentComponent[] offerComponents; FulfillmentComponent[] considerationComponents; } /** * @dev Each fulfillment component contains one index referencing a specific * order and another referencing a specific offer or consideration item. */ struct FulfillmentComponent { uint256 orderIndex; uint256 itemIndex; } /** * @dev An execution is triggered once all consideration items have been zeroed * out. It sends the item in question from the offerer to the item's * recipient, optionally sourcing approvals from either this contract * directly or from the offerer's chosen conduit if one is specified. An * execution is not provided as an argument, but rather is derived via * orders, criteria resolvers, and fulfillments (where the total number of * executions will be less than or equal to the total number of indicated * fulfillments) and returned as part of `matchOrders`. */ struct Execution { ReceivedItem item; address offerer; bytes32 conduitKey; } /** * @dev Restricted orders are validated post-execution by calling validateOrder * on the zone. This struct provides context about the order fulfillment * and any supplied extraData, as well as all order hashes fulfilled in a * call to a match or fulfillAvailable method. */ struct ZoneParameters { bytes32 orderHash; address fulfiller; address offerer; SpentItem[] offer; ReceivedItem[] consideration; bytes extraData; bytes32[] orderHashes; uint256 startTime; uint256 endTime; bytes32 zoneHash; } /** * @dev Zones and contract offerers can communicate which schemas they implement * along with any associated metadata related to each schema. */ struct Schema { uint256 id; bytes metadata; } using StructPointers for OrderComponents global; using StructPointers for OfferItem global; using StructPointers for ConsiderationItem global; using StructPointers for SpentItem global; using StructPointers for ReceivedItem global; using StructPointers for BasicOrderParameters global; using StructPointers for AdditionalRecipient global; using StructPointers for OrderParameters global; using StructPointers for Order global; using StructPointers for AdvancedOrder global; using StructPointers for OrderStatus global; using StructPointers for CriteriaResolver global; using StructPointers for Fulfillment global; using StructPointers for FulfillmentComponent global; using StructPointers for Execution global; using StructPointers for ZoneParameters global; /** * @dev This library provides a set of functions for converting structs to * pointers. */ library StructPointers { /** * @dev Get a MemoryPointer from OrderComponents. * * @param obj The OrderComponents object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( OrderComponents memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from OrderComponents. * * @param obj The OrderComponents object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( OrderComponents calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from OfferItem. * * @param obj The OfferItem object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( OfferItem memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from OfferItem. * * @param obj The OfferItem object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( OfferItem calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from ConsiderationItem. * * @param obj The ConsiderationItem object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( ConsiderationItem memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from ConsiderationItem. * * @param obj The ConsiderationItem object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( ConsiderationItem calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from SpentItem. * * @param obj The SpentItem object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( SpentItem memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from SpentItem. * * @param obj The SpentItem object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( SpentItem calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from ReceivedItem. * * @param obj The ReceivedItem object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( ReceivedItem memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from ReceivedItem. * * @param obj The ReceivedItem object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( ReceivedItem calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from BasicOrderParameters. * * @param obj The BasicOrderParameters object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( BasicOrderParameters memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from BasicOrderParameters. * * @param obj The BasicOrderParameters object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( BasicOrderParameters calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from AdditionalRecipient. * * @param obj The AdditionalRecipient object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( AdditionalRecipient memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from AdditionalRecipient. * * @param obj The AdditionalRecipient object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( AdditionalRecipient calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from OrderParameters. * * @param obj The OrderParameters object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( OrderParameters memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from OrderParameters. * * @param obj The OrderParameters object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( OrderParameters calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from Order. * * @param obj The Order object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( Order memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from Order. * * @param obj The Order object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( Order calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from AdvancedOrder. * * @param obj The AdvancedOrder object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( AdvancedOrder memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from AdvancedOrder. * * @param obj The AdvancedOrder object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( AdvancedOrder calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from OrderStatus. * * @param obj The OrderStatus object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( OrderStatus memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from OrderStatus. * * @param obj The OrderStatus object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( OrderStatus calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from CriteriaResolver. * * @param obj The CriteriaResolver object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( CriteriaResolver memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from CriteriaResolver. * * @param obj The CriteriaResolver object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( CriteriaResolver calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from Fulfillment. * * @param obj The Fulfillment object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( Fulfillment memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from Fulfillment. * * @param obj The Fulfillment object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( Fulfillment calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from FulfillmentComponent. * * @param obj The FulfillmentComponent object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( FulfillmentComponent memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from FulfillmentComponent. * * @param obj The FulfillmentComponent object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( FulfillmentComponent calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from Execution. * * @param obj The Execution object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( Execution memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from Execution. * * @param obj The Execution object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( Execution calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from ZoneParameters. * * @param obj The ZoneParameters object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( ZoneParameters memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from ZoneParameters. * * @param obj The ZoneParameters object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( ZoneParameters calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { AdvancedOrder, BasicOrderParameters, CriteriaResolver, Execution, Fulfillment, FulfillmentComponent, Order, OrderComponents } from "../lib/ConsiderationStructs.sol"; /** * @title ConsiderationInterface * @author 0age * @custom:version 1.6 * @notice Consideration is a generalized native token/ERC20/ERC721/ERC1155 * marketplace. It minimizes external calls to the greatest extent * possible and provides lightweight methods for common routes as well * as more flexible methods for composing advanced orders. * * @dev ConsiderationInterface contains all external function interfaces for * Consideration. */ interface ConsiderationInterface { /** * @notice Fulfill an order offering an ERC721 token by supplying Ether (or * the native token for the given chain) as consideration for the * order. An arbitrary number of "additional recipients" may also be * supplied which will each receive native tokens from the fulfiller * as consideration. * * @param parameters Additional information on the fulfilled order. Note * that the offerer must first approve this contract (or * their preferred conduit if indicated by the order) for * their offered ERC721 token to be transferred. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillBasicOrder( BasicOrderParameters calldata parameters ) external payable returns (bool fulfilled); /** * @notice Fulfill an order with an arbitrary number of items for offer and * consideration. Note that this function does not support * criteria-based orders or partial filling of orders (though * filling the remainder of a partially-filled order is supported). * * @param order The order to fulfill. Note that both the * offerer and the fulfiller must first approve * this contract (or the corresponding conduit if * indicated) to transfer any relevant tokens on * their behalf and that contracts must implement * `onERC1155Received` to receive ERC1155 tokens * as consideration. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used, with direct approvals set on * Consideration. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillOrder( Order calldata order, bytes32 fulfillerConduitKey ) external payable returns (bool fulfilled); /** * @notice Fill an order, fully or partially, with an arbitrary number of * items for offer and consideration alongside criteria resolvers * containing specific token identifiers and associated proofs. * * @param advancedOrder The order to fulfill along with the fraction * of the order to attempt to fill. Note that * both the offerer and the fulfiller must first * approve this contract (or their preferred * conduit if indicated by the order) to transfer * any relevant tokens on their behalf and that * contracts must implement `onERC1155Received` * to receive ERC1155 tokens as consideration. * Also note that all offer and consideration * components must have no remainder after * multiplication of the respective amount with * the supplied fraction for the partial fill to * be considered valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a proof * that the supplied token identifier is * contained in the merkle root held by the item * in question's criteria element. Note that an * empty criteria indicates that any * (transferable) token identifier on the token * in question is valid and that no associated * proof needs to be supplied. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used, with direct approvals set on * Consideration. * @param recipient The intended recipient for all received items, * with `address(0)` indicating that the caller * should receive the items. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillAdvancedOrder( AdvancedOrder calldata advancedOrder, CriteriaResolver[] calldata criteriaResolvers, bytes32 fulfillerConduitKey, address recipient ) external payable returns (bool fulfilled); /** * @notice Attempt to fill a group of orders, each with an arbitrary number * of items for offer and consideration. Any order that is not * currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * Note that this function does not support criteria-based orders or * partial filling of orders (though filling the remainder of a * partially-filled order is supported). * * @param orders The orders to fulfill. Note that both * the offerer and the fulfiller must first * approve this contract (or the * corresponding conduit if indicated) to * transfer any relevant tokens on their * behalf and that contracts must implement * `onERC1155Received` to receive ERC1155 * tokens as consideration. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used, with * direct approvals set on this contract. * @param maximumFulfilled The maximum number of orders to fulfill. * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of * this array. */ function fulfillAvailableOrders( Order[] calldata orders, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, uint256 maximumFulfilled ) external payable returns (bool[] memory availableOrders, Execution[] memory executions); /** * @notice Attempt to fill a group of orders, fully or partially, with an * arbitrary number of items for offer and consideration per order * alongside criteria resolvers containing specific token * identifiers and associated proofs. Any order that is not * currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * * @param advancedOrders The orders to fulfill along with the * fraction of those orders to attempt to * fill. Note that both the offerer and the * fulfiller must first approve this * contract (or their preferred conduit if * indicated by the order) to transfer any * relevant tokens on their behalf and that * contracts must implement * `onERC1155Received` to enable receipt of * ERC1155 tokens as consideration. Also * note that all offer and consideration * components must have no remainder after * multiplication of the respective amount * with the supplied fraction for an * order's partial fill amount to be * considered valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a * proof that the supplied token identifier * is contained in the merkle root held by * the item in question's criteria element. * Note that an empty criteria indicates * that any (transferable) token * identifier on the token in question is * valid and that no associated proof needs * to be supplied. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used, with * direct approvals set on this contract. * @param recipient The intended recipient for all received * items, with `address(0)` indicating that * the caller should receive the items. * @param maximumFulfilled The maximum number of orders to fulfill. * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of * this array. */ function fulfillAvailableAdvancedOrders( AdvancedOrder[] calldata advancedOrders, CriteriaResolver[] calldata criteriaResolvers, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, address recipient, uint256 maximumFulfilled ) external payable returns (bool[] memory availableOrders, Execution[] memory executions); /** * @notice Match an arbitrary number of orders, each with an arbitrary * number of items for offer and consideration along with a set of * fulfillments allocating offer components to consideration * components. Note that this function does not support * criteria-based or partial filling of orders (though filling the * remainder of a partially-filled order is supported). Any unspent * offer item amounts or native tokens will be transferred to the * caller. * * @param orders The orders to match. Note that both the offerer and * fulfiller on each order must first approve this * contract (or their conduit if indicated by the order) * to transfer any relevant tokens on their behalf and * each consideration recipient must implement * `onERC1155Received` to enable ERC1155 token receipt. * @param fulfillments An array of elements allocating offer components to * consideration components. Note that each * consideration component must be fully met for the * match operation to be valid. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of this * array. */ function matchOrders( Order[] calldata orders, Fulfillment[] calldata fulfillments ) external payable returns (Execution[] memory executions); /** * @notice Match an arbitrary number of full or partial orders, each with an * arbitrary number of items for offer and consideration, supplying * criteria resolvers containing specific token identifiers and * associated proofs as well as fulfillments allocating offer * components to consideration components. Any unspent offer item * amounts will be transferred to the designated recipient (with the * null address signifying to use the caller) and any unspent native * tokens will be returned to the caller. * * @param orders The advanced orders to match. Note that both the * offerer and fulfiller on each order must first * approve this contract (or a preferred conduit if * indicated by the order) to transfer any relevant * tokens on their behalf and each consideration * recipient must implement `onERC1155Received` in * order to receive ERC1155 tokens. Also note that * the offer and consideration components for each * order must have no remainder after multiplying * the respective amount with the supplied fraction * in order for the group of partial fills to be * considered valid. * @param criteriaResolvers An array where each element contains a reference * to a specific order as well as that order's * offer or consideration, a token identifier, and * a proof that the supplied token identifier is * contained in the order's merkle root. Note that * an empty root indicates that any (transferable) * token identifier is valid and that no associated * proof needs to be supplied. * @param fulfillments An array of elements allocating offer components * to consideration components. Note that each * consideration component must be fully met in * order for the match operation to be valid. * @param recipient The intended recipient for all unspent offer * item amounts, or the caller if the null address * is supplied. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or native * tokens will not be reflected as part of this array. */ function matchAdvancedOrders( AdvancedOrder[] calldata orders, CriteriaResolver[] calldata criteriaResolvers, Fulfillment[] calldata fulfillments, address recipient ) external payable returns (Execution[] memory executions); /** * @notice Cancel an arbitrary number of orders. Note that only the offerer * or the zone of a given order may cancel it. Callers should ensure * that the intended order was cancelled by calling `getOrderStatus` * and confirming that `isCancelled` returns `true`. * * @param orders The orders to cancel. * * @return cancelled A boolean indicating whether the supplied orders have * been successfully cancelled. */ function cancel( OrderComponents[] calldata orders ) external returns (bool cancelled); /** * @notice Validate an arbitrary number of orders, thereby registering their * signatures as valid and allowing the fulfiller to skip signature * verification on fulfillment. Note that validated orders may still * be unfulfillable due to invalid item amounts or other factors; * callers should determine whether validated orders are fulfillable * by simulating the fulfillment call prior to execution. Also note * that anyone can validate a signed order, but only the offerer can * validate an order without supplying a signature. * * @param orders The orders to validate. * * @return validated A boolean indicating whether the supplied orders have * been successfully validated. */ function validate( Order[] calldata orders ) external returns (bool validated); /** * @notice Cancel all orders from a given offerer with a given zone in bulk * by incrementing a counter. Note that only the offerer may * increment the counter. * * @return newCounter The new counter. */ function incrementCounter() external returns (uint256 newCounter); /** * @notice Fulfill an order offering an ERC721 token by supplying Ether (or * the native token for the given chain) as consideration for the * order. An arbitrary number of "additional recipients" may also be * supplied which will each receive native tokens from the fulfiller * as consideration. Note that this function costs less gas than * `fulfillBasicOrder` due to the zero bytes in the function * selector (0x00000000) which also results in earlier function * dispatch. * * @param parameters Additional information on the fulfilled order. Note * that the offerer must first approve this contract (or * their preferred conduit if indicated by the order) for * their offered ERC721 token to be transferred. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillBasicOrder_efficient_6GL6yc( BasicOrderParameters calldata parameters ) external payable returns (bool fulfilled); /** * @notice Retrieve the order hash for a given order. * * @param order The components of the order. * * @return orderHash The order hash. */ function getOrderHash( OrderComponents calldata order ) external view returns (bytes32 orderHash); /** * @notice Retrieve the status of a given order by hash, including whether * the order has been cancelled or validated and the fraction of the * order that has been filled. * * @param orderHash The order hash in question. * * @return isValidated A boolean indicating whether the order in question * has been validated (i.e. previously approved or * partially filled). * @return isCancelled A boolean indicating whether the order in question * has been cancelled. * @return totalFilled The total portion of the order that has been filled * (i.e. the "numerator"). * @return totalSize The total size of the order that is either filled or * unfilled (i.e. the "denominator"). */ function getOrderStatus( bytes32 orderHash ) external view returns ( bool isValidated, bool isCancelled, uint256 totalFilled, uint256 totalSize ); /** * @notice Retrieve the current counter for a given offerer. * * @param offerer The offerer in question. * * @return counter The current counter. */ function getCounter( address offerer ) external view returns (uint256 counter); /** * @notice Retrieve configuration information for this contract. * * @return version The contract version. * @return domainSeparator The domain separator for this contract. * @return conduitController The conduit Controller set for this contract. */ function information() external view returns ( string memory version, bytes32 domainSeparator, address conduitController ); function getContractOffererNonce( address contractOfferer ) external view returns (uint256 nonce); /** * @notice Retrieve the name of this contract. * * @return contractName The name of this contract. */ function name() external view returns (string memory contractName); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; type CalldataPointer is uint256; type ReturndataPointer is uint256; type MemoryPointer is uint256; using CalldataPointerLib for CalldataPointer global; using MemoryPointerLib for MemoryPointer global; using ReturndataPointerLib for ReturndataPointer global; using CalldataReaders for CalldataPointer global; using ReturndataReaders for ReturndataPointer global; using MemoryReaders for MemoryPointer global; using MemoryWriters for MemoryPointer global; CalldataPointer constant CalldataStart = CalldataPointer.wrap(0x04); MemoryPointer constant FreeMemoryPPtr = MemoryPointer.wrap(0x40); MemoryPointer constant ZeroSlotPtr = MemoryPointer.wrap(0x60); uint256 constant IdentityPrecompileAddress = 0x4; uint256 constant OffsetOrLengthMask = 0xffffffff; uint256 constant _OneWord = 0x20; uint256 constant _FreeMemoryPointerSlot = 0x40; /// @dev Allocates `size` bytes in memory by increasing the free memory pointer /// and returns the memory pointer to the first byte of the allocated region. // (Free functions cannot have visibility.) // solhint-disable-next-line func-visibility function malloc(uint256 size) pure returns (MemoryPointer mPtr) { assembly { mPtr := mload(_FreeMemoryPointerSlot) mstore(_FreeMemoryPointerSlot, add(mPtr, size)) } } // (Free functions cannot have visibility.) // solhint-disable-next-line func-visibility function getFreeMemoryPointer() pure returns (MemoryPointer mPtr) { mPtr = FreeMemoryPPtr.readMemoryPointer(); } // (Free functions cannot have visibility.) // solhint-disable-next-line func-visibility function setFreeMemoryPointer(MemoryPointer mPtr) pure { FreeMemoryPPtr.write(mPtr); } library CalldataPointerLib { function lt( CalldataPointer a, CalldataPointer b ) internal pure returns (bool c) { assembly { c := lt(a, b) } } function gt( CalldataPointer a, CalldataPointer b ) internal pure returns (bool c) { assembly { c := gt(a, b) } } function eq( CalldataPointer a, CalldataPointer b ) internal pure returns (bool c) { assembly { c := eq(a, b) } } function isNull(CalldataPointer a) internal pure returns (bool b) { assembly { b := iszero(a) } } /// @dev Resolves an offset stored at `cdPtr + headOffset` to a calldata. /// pointer `cdPtr` must point to some parent object with a dynamic /// type's head stored at `cdPtr + headOffset`. function pptrOffset( CalldataPointer cdPtr, uint256 headOffset ) internal pure returns (CalldataPointer cdPtrChild) { cdPtrChild = cdPtr.offset( cdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask ); } /// @dev Resolves an offset stored at `cdPtr` to a calldata pointer. /// `cdPtr` must point to some parent object with a dynamic type as its /// first member, e.g. `struct { bytes data; }` function pptr( CalldataPointer cdPtr ) internal pure returns (CalldataPointer cdPtrChild) { cdPtrChild = cdPtr.offset(cdPtr.readUint256() & OffsetOrLengthMask); } /// @dev Returns the calldata pointer one word after `cdPtr`. function next( CalldataPointer cdPtr ) internal pure returns (CalldataPointer cdPtrNext) { assembly { cdPtrNext := add(cdPtr, _OneWord) } } /// @dev Returns the calldata pointer `_offset` bytes after `cdPtr`. function offset( CalldataPointer cdPtr, uint256 _offset ) internal pure returns (CalldataPointer cdPtrNext) { assembly { cdPtrNext := add(cdPtr, _offset) } } /// @dev Copies `size` bytes from calldata starting at `src` to memory at /// `dst`. function copy( CalldataPointer src, MemoryPointer dst, uint256 size ) internal pure { assembly { calldatacopy(dst, src, size) } } } library ReturndataPointerLib { function lt( ReturndataPointer a, ReturndataPointer b ) internal pure returns (bool c) { assembly { c := lt(a, b) } } function gt( ReturndataPointer a, ReturndataPointer b ) internal pure returns (bool c) { assembly { c := gt(a, b) } } function eq( ReturndataPointer a, ReturndataPointer b ) internal pure returns (bool c) { assembly { c := eq(a, b) } } function isNull(ReturndataPointer a) internal pure returns (bool b) { assembly { b := iszero(a) } } /// @dev Resolves an offset stored at `rdPtr + headOffset` to a returndata /// pointer. `rdPtr` must point to some parent object with a dynamic /// type's head stored at `rdPtr + headOffset`. function pptrOffset( ReturndataPointer rdPtr, uint256 headOffset ) internal pure returns (ReturndataPointer rdPtrChild) { rdPtrChild = rdPtr.offset( rdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask ); } /// @dev Resolves an offset stored at `rdPtr` to a returndata pointer. /// `rdPtr` must point to some parent object with a dynamic type as its /// first member, e.g. `struct { bytes data; }` function pptr( ReturndataPointer rdPtr ) internal pure returns (ReturndataPointer rdPtrChild) { rdPtrChild = rdPtr.offset(rdPtr.readUint256() & OffsetOrLengthMask); } /// @dev Returns the returndata pointer one word after `cdPtr`. function next( ReturndataPointer rdPtr ) internal pure returns (ReturndataPointer rdPtrNext) { assembly { rdPtrNext := add(rdPtr, _OneWord) } } /// @dev Returns the returndata pointer `_offset` bytes after `cdPtr`. function offset( ReturndataPointer rdPtr, uint256 _offset ) internal pure returns (ReturndataPointer rdPtrNext) { assembly { rdPtrNext := add(rdPtr, _offset) } } /// @dev Copies `size` bytes from returndata starting at `src` to memory at /// `dst`. function copy( ReturndataPointer src, MemoryPointer dst, uint256 size ) internal pure { assembly { returndatacopy(dst, src, size) } } } library MemoryPointerLib { function copy( MemoryPointer src, MemoryPointer dst, uint256 size ) internal view { assembly { let success := staticcall( gas(), IdentityPrecompileAddress, src, size, dst, size ) if or(iszero(returndatasize()), iszero(success)) { revert(0, 0) } } } function lt( MemoryPointer a, MemoryPointer b ) internal pure returns (bool c) { assembly { c := lt(a, b) } } function gt( MemoryPointer a, MemoryPointer b ) internal pure returns (bool c) { assembly { c := gt(a, b) } } function eq( MemoryPointer a, MemoryPointer b ) internal pure returns (bool c) { assembly { c := eq(a, b) } } function isNull(MemoryPointer a) internal pure returns (bool b) { assembly { b := iszero(a) } } function hash( MemoryPointer ptr, uint256 length ) internal pure returns (bytes32 _hash) { assembly { _hash := keccak256(ptr, length) } } /// @dev Returns the memory pointer one word after `mPtr`. function next( MemoryPointer mPtr ) internal pure returns (MemoryPointer mPtrNext) { assembly { mPtrNext := add(mPtr, _OneWord) } } /// @dev Returns the memory pointer `_offset` bytes after `mPtr`. function offset( MemoryPointer mPtr, uint256 _offset ) internal pure returns (MemoryPointer mPtrNext) { assembly { mPtrNext := add(mPtr, _offset) } } /// @dev Resolves a pointer at `mPtr + headOffset` to a memory /// pointer. `mPtr` must point to some parent object with a dynamic /// type's pointer stored at `mPtr + headOffset`. function pptrOffset( MemoryPointer mPtr, uint256 headOffset ) internal pure returns (MemoryPointer mPtrChild) { mPtrChild = mPtr.offset(headOffset).readMemoryPointer(); } /// @dev Resolves a pointer stored at `mPtr` to a memory pointer. /// `mPtr` must point to some parent object with a dynamic type as its /// first member, e.g. `struct { bytes data; }` function pptr( MemoryPointer mPtr ) internal pure returns (MemoryPointer mPtrChild) { mPtrChild = mPtr.readMemoryPointer(); } } library CalldataReaders { /// @dev Reads the value at `cdPtr` and applies a mask to return only the /// last 4 bytes. function readMaskedUint256( CalldataPointer cdPtr ) internal pure returns (uint256 value) { value = cdPtr.readUint256() & OffsetOrLengthMask; } /// @dev Reads the bool at `cdPtr` in calldata. function readBool( CalldataPointer cdPtr ) internal pure returns (bool value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the address at `cdPtr` in calldata. function readAddress( CalldataPointer cdPtr ) internal pure returns (address value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes1 at `cdPtr` in calldata. function readBytes1( CalldataPointer cdPtr ) internal pure returns (bytes1 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes2 at `cdPtr` in calldata. function readBytes2( CalldataPointer cdPtr ) internal pure returns (bytes2 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes3 at `cdPtr` in calldata. function readBytes3( CalldataPointer cdPtr ) internal pure returns (bytes3 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes4 at `cdPtr` in calldata. function readBytes4( CalldataPointer cdPtr ) internal pure returns (bytes4 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes5 at `cdPtr` in calldata. function readBytes5( CalldataPointer cdPtr ) internal pure returns (bytes5 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes6 at `cdPtr` in calldata. function readBytes6( CalldataPointer cdPtr ) internal pure returns (bytes6 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes7 at `cdPtr` in calldata. function readBytes7( CalldataPointer cdPtr ) internal pure returns (bytes7 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes8 at `cdPtr` in calldata. function readBytes8( CalldataPointer cdPtr ) internal pure returns (bytes8 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes9 at `cdPtr` in calldata. function readBytes9( CalldataPointer cdPtr ) internal pure returns (bytes9 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes10 at `cdPtr` in calldata. function readBytes10( CalldataPointer cdPtr ) internal pure returns (bytes10 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes11 at `cdPtr` in calldata. function readBytes11( CalldataPointer cdPtr ) internal pure returns (bytes11 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes12 at `cdPtr` in calldata. function readBytes12( CalldataPointer cdPtr ) internal pure returns (bytes12 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes13 at `cdPtr` in calldata. function readBytes13( CalldataPointer cdPtr ) internal pure returns (bytes13 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes14 at `cdPtr` in calldata. function readBytes14( CalldataPointer cdPtr ) internal pure returns (bytes14 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes15 at `cdPtr` in calldata. function readBytes15( CalldataPointer cdPtr ) internal pure returns (bytes15 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes16 at `cdPtr` in calldata. function readBytes16( CalldataPointer cdPtr ) internal pure returns (bytes16 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes17 at `cdPtr` in calldata. function readBytes17( CalldataPointer cdPtr ) internal pure returns (bytes17 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes18 at `cdPtr` in calldata. function readBytes18( CalldataPointer cdPtr ) internal pure returns (bytes18 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes19 at `cdPtr` in calldata. function readBytes19( CalldataPointer cdPtr ) internal pure returns (bytes19 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes20 at `cdPtr` in calldata. function readBytes20( CalldataPointer cdPtr ) internal pure returns (bytes20 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes21 at `cdPtr` in calldata. function readBytes21( CalldataPointer cdPtr ) internal pure returns (bytes21 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes22 at `cdPtr` in calldata. function readBytes22( CalldataPointer cdPtr ) internal pure returns (bytes22 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes23 at `cdPtr` in calldata. function readBytes23( CalldataPointer cdPtr ) internal pure returns (bytes23 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes24 at `cdPtr` in calldata. function readBytes24( CalldataPointer cdPtr ) internal pure returns (bytes24 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes25 at `cdPtr` in calldata. function readBytes25( CalldataPointer cdPtr ) internal pure returns (bytes25 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes26 at `cdPtr` in calldata. function readBytes26( CalldataPointer cdPtr ) internal pure returns (bytes26 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes27 at `cdPtr` in calldata. function readBytes27( CalldataPointer cdPtr ) internal pure returns (bytes27 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes28 at `cdPtr` in calldata. function readBytes28( CalldataPointer cdPtr ) internal pure returns (bytes28 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes29 at `cdPtr` in calldata. function readBytes29( CalldataPointer cdPtr ) internal pure returns (bytes29 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes30 at `cdPtr` in calldata. function readBytes30( CalldataPointer cdPtr ) internal pure returns (bytes30 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes31 at `cdPtr` in calldata. function readBytes31( CalldataPointer cdPtr ) internal pure returns (bytes31 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes32 at `cdPtr` in calldata. function readBytes32( CalldataPointer cdPtr ) internal pure returns (bytes32 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint8 at `cdPtr` in calldata. function readUint8( CalldataPointer cdPtr ) internal pure returns (uint8 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint16 at `cdPtr` in calldata. function readUint16( CalldataPointer cdPtr ) internal pure returns (uint16 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint24 at `cdPtr` in calldata. function readUint24( CalldataPointer cdPtr ) internal pure returns (uint24 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint32 at `cdPtr` in calldata. function readUint32( CalldataPointer cdPtr ) internal pure returns (uint32 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint40 at `cdPtr` in calldata. function readUint40( CalldataPointer cdPtr ) internal pure returns (uint40 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint48 at `cdPtr` in calldata. function readUint48( CalldataPointer cdPtr ) internal pure returns (uint48 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint56 at `cdPtr` in calldata. function readUint56( CalldataPointer cdPtr ) internal pure returns (uint56 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint64 at `cdPtr` in calldata. function readUint64( CalldataPointer cdPtr ) internal pure returns (uint64 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint72 at `cdPtr` in calldata. function readUint72( CalldataPointer cdPtr ) internal pure returns (uint72 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint80 at `cdPtr` in calldata. function readUint80( CalldataPointer cdPtr ) internal pure returns (uint80 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint88 at `cdPtr` in calldata. function readUint88( CalldataPointer cdPtr ) internal pure returns (uint88 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint96 at `cdPtr` in calldata. function readUint96( CalldataPointer cdPtr ) internal pure returns (uint96 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint104 at `cdPtr` in calldata. function readUint104( CalldataPointer cdPtr ) internal pure returns (uint104 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint112 at `cdPtr` in calldata. function readUint112( CalldataPointer cdPtr ) internal pure returns (uint112 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint120 at `cdPtr` in calldata. function readUint120( CalldataPointer cdPtr ) internal pure returns (uint120 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint128 at `cdPtr` in calldata. function readUint128( CalldataPointer cdPtr ) internal pure returns (uint128 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint136 at `cdPtr` in calldata. function readUint136( CalldataPointer cdPtr ) internal pure returns (uint136 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint144 at `cdPtr` in calldata. function readUint144( CalldataPointer cdPtr ) internal pure returns (uint144 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint152 at `cdPtr` in calldata. function readUint152( CalldataPointer cdPtr ) internal pure returns (uint152 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint160 at `cdPtr` in calldata. function readUint160( CalldataPointer cdPtr ) internal pure returns (uint160 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint168 at `cdPtr` in calldata. function readUint168( CalldataPointer cdPtr ) internal pure returns (uint168 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint176 at `cdPtr` in calldata. function readUint176( CalldataPointer cdPtr ) internal pure returns (uint176 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint184 at `cdPtr` in calldata. function readUint184( CalldataPointer cdPtr ) internal pure returns (uint184 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint192 at `cdPtr` in calldata. function readUint192( CalldataPointer cdPtr ) internal pure returns (uint192 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint200 at `cdPtr` in calldata. function readUint200( CalldataPointer cdPtr ) internal pure returns (uint200 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint208 at `cdPtr` in calldata. function readUint208( CalldataPointer cdPtr ) internal pure returns (uint208 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint216 at `cdPtr` in calldata. function readUint216( CalldataPointer cdPtr ) internal pure returns (uint216 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint224 at `cdPtr` in calldata. function readUint224( CalldataPointer cdPtr ) internal pure returns (uint224 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint232 at `cdPtr` in calldata. function readUint232( CalldataPointer cdPtr ) internal pure returns (uint232 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint240 at `cdPtr` in calldata. function readUint240( CalldataPointer cdPtr ) internal pure returns (uint240 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint248 at `cdPtr` in calldata. function readUint248( CalldataPointer cdPtr ) internal pure returns (uint248 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint256 at `cdPtr` in calldata. function readUint256( CalldataPointer cdPtr ) internal pure returns (uint256 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int8 at `cdPtr` in calldata. function readInt8( CalldataPointer cdPtr ) internal pure returns (int8 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int16 at `cdPtr` in calldata. function readInt16( CalldataPointer cdPtr ) internal pure returns (int16 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int24 at `cdPtr` in calldata. function readInt24( CalldataPointer cdPtr ) internal pure returns (int24 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int32 at `cdPtr` in calldata. function readInt32( CalldataPointer cdPtr ) internal pure returns (int32 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int40 at `cdPtr` in calldata. function readInt40( CalldataPointer cdPtr ) internal pure returns (int40 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int48 at `cdPtr` in calldata. function readInt48( CalldataPointer cdPtr ) internal pure returns (int48 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int56 at `cdPtr` in calldata. function readInt56( CalldataPointer cdPtr ) internal pure returns (int56 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int64 at `cdPtr` in calldata. function readInt64( CalldataPointer cdPtr ) internal pure returns (int64 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int72 at `cdPtr` in calldata. function readInt72( CalldataPointer cdPtr ) internal pure returns (int72 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int80 at `cdPtr` in calldata. function readInt80( CalldataPointer cdPtr ) internal pure returns (int80 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int88 at `cdPtr` in calldata. function readInt88( CalldataPointer cdPtr ) internal pure returns (int88 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int96 at `cdPtr` in calldata. function readInt96( CalldataPointer cdPtr ) internal pure returns (int96 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int104 at `cdPtr` in calldata. function readInt104( CalldataPointer cdPtr ) internal pure returns (int104 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int112 at `cdPtr` in calldata. function readInt112( CalldataPointer cdPtr ) internal pure returns (int112 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int120 at `cdPtr` in calldata. function readInt120( CalldataPointer cdPtr ) internal pure returns (int120 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int128 at `cdPtr` in calldata. function readInt128( CalldataPointer cdPtr ) internal pure returns (int128 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int136 at `cdPtr` in calldata. function readInt136( CalldataPointer cdPtr ) internal pure returns (int136 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int144 at `cdPtr` in calldata. function readInt144( CalldataPointer cdPtr ) internal pure returns (int144 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int152 at `cdPtr` in calldata. function readInt152( CalldataPointer cdPtr ) internal pure returns (int152 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int160 at `cdPtr` in calldata. function readInt160( CalldataPointer cdPtr ) internal pure returns (int160 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int168 at `cdPtr` in calldata. function readInt168( CalldataPointer cdPtr ) internal pure returns (int168 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int176 at `cdPtr` in calldata. function readInt176( CalldataPointer cdPtr ) internal pure returns (int176 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int184 at `cdPtr` in calldata. function readInt184( CalldataPointer cdPtr ) internal pure returns (int184 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int192 at `cdPtr` in calldata. function readInt192( CalldataPointer cdPtr ) internal pure returns (int192 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int200 at `cdPtr` in calldata. function readInt200( CalldataPointer cdPtr ) internal pure returns (int200 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int208 at `cdPtr` in calldata. function readInt208( CalldataPointer cdPtr ) internal pure returns (int208 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int216 at `cdPtr` in calldata. function readInt216( CalldataPointer cdPtr ) internal pure returns (int216 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int224 at `cdPtr` in calldata. function readInt224( CalldataPointer cdPtr ) internal pure returns (int224 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int232 at `cdPtr` in calldata. function readInt232( CalldataPointer cdPtr ) internal pure returns (int232 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int240 at `cdPtr` in calldata. function readInt240( CalldataPointer cdPtr ) internal pure returns (int240 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int248 at `cdPtr` in calldata. function readInt248( CalldataPointer cdPtr ) internal pure returns (int248 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int256 at `cdPtr` in calldata. function readInt256( CalldataPointer cdPtr ) internal pure returns (int256 value) { assembly { value := calldataload(cdPtr) } } } library ReturndataReaders { /// @dev Reads value at `rdPtr` & applies a mask to return only last 4 bytes function readMaskedUint256( ReturndataPointer rdPtr ) internal pure returns (uint256 value) { value = rdPtr.readUint256() & OffsetOrLengthMask; } /// @dev Reads the bool at `rdPtr` in returndata. function readBool( ReturndataPointer rdPtr ) internal pure returns (bool value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the address at `rdPtr` in returndata. function readAddress( ReturndataPointer rdPtr ) internal pure returns (address value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes1 at `rdPtr` in returndata. function readBytes1( ReturndataPointer rdPtr ) internal pure returns (bytes1 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes2 at `rdPtr` in returndata. function readBytes2( ReturndataPointer rdPtr ) internal pure returns (bytes2 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes3 at `rdPtr` in returndata. function readBytes3( ReturndataPointer rdPtr ) internal pure returns (bytes3 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes4 at `rdPtr` in returndata. function readBytes4( ReturndataPointer rdPtr ) internal pure returns (bytes4 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes5 at `rdPtr` in returndata. function readBytes5( ReturndataPointer rdPtr ) internal pure returns (bytes5 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes6 at `rdPtr` in returndata. function readBytes6( ReturndataPointer rdPtr ) internal pure returns (bytes6 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes7 at `rdPtr` in returndata. function readBytes7( ReturndataPointer rdPtr ) internal pure returns (bytes7 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes8 at `rdPtr` in returndata. function readBytes8( ReturndataPointer rdPtr ) internal pure returns (bytes8 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes9 at `rdPtr` in returndata. function readBytes9( ReturndataPointer rdPtr ) internal pure returns (bytes9 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes10 at `rdPtr` in returndata. function readBytes10( ReturndataPointer rdPtr ) internal pure returns (bytes10 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes11 at `rdPtr` in returndata. function readBytes11( ReturndataPointer rdPtr ) internal pure returns (bytes11 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes12 at `rdPtr` in returndata. function readBytes12( ReturndataPointer rdPtr ) internal pure returns (bytes12 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes13 at `rdPtr` in returndata. function readBytes13( ReturndataPointer rdPtr ) internal pure returns (bytes13 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes14 at `rdPtr` in returndata. function readBytes14( ReturndataPointer rdPtr ) internal pure returns (bytes14 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes15 at `rdPtr` in returndata. function readBytes15( ReturndataPointer rdPtr ) internal pure returns (bytes15 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes16 at `rdPtr` in returndata. function readBytes16( ReturndataPointer rdPtr ) internal pure returns (bytes16 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes17 at `rdPtr` in returndata. function readBytes17( ReturndataPointer rdPtr ) internal pure returns (bytes17 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes18 at `rdPtr` in returndata. function readBytes18( ReturndataPointer rdPtr ) internal pure returns (bytes18 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes19 at `rdPtr` in returndata. function readBytes19( ReturndataPointer rdPtr ) internal pure returns (bytes19 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes20 at `rdPtr` in returndata. function readBytes20( ReturndataPointer rdPtr ) internal pure returns (bytes20 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes21 at `rdPtr` in returndata. function readBytes21( ReturndataPointer rdPtr ) internal pure returns (bytes21 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes22 at `rdPtr` in returndata. function readBytes22( ReturndataPointer rdPtr ) internal pure returns (bytes22 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes23 at `rdPtr` in returndata. function readBytes23( ReturndataPointer rdPtr ) internal pure returns (bytes23 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes24 at `rdPtr` in returndata. function readBytes24( ReturndataPointer rdPtr ) internal pure returns (bytes24 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes25 at `rdPtr` in returndata. function readBytes25( ReturndataPointer rdPtr ) internal pure returns (bytes25 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes26 at `rdPtr` in returndata. function readBytes26( ReturndataPointer rdPtr ) internal pure returns (bytes26 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes27 at `rdPtr` in returndata. function readBytes27( ReturndataPointer rdPtr ) internal pure returns (bytes27 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes28 at `rdPtr` in returndata. function readBytes28( ReturndataPointer rdPtr ) internal pure returns (bytes28 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes29 at `rdPtr` in returndata. function readBytes29( ReturndataPointer rdPtr ) internal pure returns (bytes29 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes30 at `rdPtr` in returndata. function readBytes30( ReturndataPointer rdPtr ) internal pure returns (bytes30 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes31 at `rdPtr` in returndata. function readBytes31( ReturndataPointer rdPtr ) internal pure returns (bytes31 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes32 at `rdPtr` in returndata. function readBytes32( ReturndataPointer rdPtr ) internal pure returns (bytes32 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint8 at `rdPtr` in returndata. function readUint8( ReturndataPointer rdPtr ) internal pure returns (uint8 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint16 at `rdPtr` in returndata. function readUint16( ReturndataPointer rdPtr ) internal pure returns (uint16 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint24 at `rdPtr` in returndata. function readUint24( ReturndataPointer rdPtr ) internal pure returns (uint24 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint32 at `rdPtr` in returndata. function readUint32( ReturndataPointer rdPtr ) internal pure returns (uint32 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint40 at `rdPtr` in returndata. function readUint40( ReturndataPointer rdPtr ) internal pure returns (uint40 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint48 at `rdPtr` in returndata. function readUint48( ReturndataPointer rdPtr ) internal pure returns (uint48 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint56 at `rdPtr` in returndata. function readUint56( ReturndataPointer rdPtr ) internal pure returns (uint56 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint64 at `rdPtr` in returndata. function readUint64( ReturndataPointer rdPtr ) internal pure returns (uint64 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint72 at `rdPtr` in returndata. function readUint72( ReturndataPointer rdPtr ) internal pure returns (uint72 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint80 at `rdPtr` in returndata. function readUint80( ReturndataPointer rdPtr ) internal pure returns (uint80 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint88 at `rdPtr` in returndata. function readUint88( ReturndataPointer rdPtr ) internal pure returns (uint88 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint96 at `rdPtr` in returndata. function readUint96( ReturndataPointer rdPtr ) internal pure returns (uint96 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint104 at `rdPtr` in returndata. function readUint104( ReturndataPointer rdPtr ) internal pure returns (uint104 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint112 at `rdPtr` in returndata. function readUint112( ReturndataPointer rdPtr ) internal pure returns (uint112 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint120 at `rdPtr` in returndata. function readUint120( ReturndataPointer rdPtr ) internal pure returns (uint120 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint128 at `rdPtr` in returndata. function readUint128( ReturndataPointer rdPtr ) internal pure returns (uint128 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint136 at `rdPtr` in returndata. function readUint136( ReturndataPointer rdPtr ) internal pure returns (uint136 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint144 at `rdPtr` in returndata. function readUint144( ReturndataPointer rdPtr ) internal pure returns (uint144 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint152 at `rdPtr` in returndata. function readUint152( ReturndataPointer rdPtr ) internal pure returns (uint152 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint160 at `rdPtr` in returndata. function readUint160( ReturndataPointer rdPtr ) internal pure returns (uint160 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint168 at `rdPtr` in returndata. function readUint168( ReturndataPointer rdPtr ) internal pure returns (uint168 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint176 at `rdPtr` in returndata. function readUint176( ReturndataPointer rdPtr ) internal pure returns (uint176 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint184 at `rdPtr` in returndata. function readUint184( ReturndataPointer rdPtr ) internal pure returns (uint184 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint192 at `rdPtr` in returndata. function readUint192( ReturndataPointer rdPtr ) internal pure returns (uint192 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint200 at `rdPtr` in returndata. function readUint200( ReturndataPointer rdPtr ) internal pure returns (uint200 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint208 at `rdPtr` in returndata. function readUint208( ReturndataPointer rdPtr ) internal pure returns (uint208 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint216 at `rdPtr` in returndata. function readUint216( ReturndataPointer rdPtr ) internal pure returns (uint216 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint224 at `rdPtr` in returndata. function readUint224( ReturndataPointer rdPtr ) internal pure returns (uint224 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint232 at `rdPtr` in returndata. function readUint232( ReturndataPointer rdPtr ) internal pure returns (uint232 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint240 at `rdPtr` in returndata. function readUint240( ReturndataPointer rdPtr ) internal pure returns (uint240 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint248 at `rdPtr` in returndata. function readUint248( ReturndataPointer rdPtr ) internal pure returns (uint248 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint256 at `rdPtr` in returndata. function readUint256( ReturndataPointer rdPtr ) internal pure returns (uint256 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int8 at `rdPtr` in returndata. function readInt8( ReturndataPointer rdPtr ) internal pure returns (int8 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int16 at `rdPtr` in returndata. function readInt16( ReturndataPointer rdPtr ) internal pure returns (int16 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int24 at `rdPtr` in returndata. function readInt24( ReturndataPointer rdPtr ) internal pure returns (int24 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int32 at `rdPtr` in returndata. function readInt32( ReturndataPointer rdPtr ) internal pure returns (int32 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int40 at `rdPtr` in returndata. function readInt40( ReturndataPointer rdPtr ) internal pure returns (int40 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int48 at `rdPtr` in returndata. function readInt48( ReturndataPointer rdPtr ) internal pure returns (int48 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int56 at `rdPtr` in returndata. function readInt56( ReturndataPointer rdPtr ) internal pure returns (int56 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int64 at `rdPtr` in returndata. function readInt64( ReturndataPointer rdPtr ) internal pure returns (int64 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int72 at `rdPtr` in returndata. function readInt72( ReturndataPointer rdPtr ) internal pure returns (int72 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int80 at `rdPtr` in returndata. function readInt80( ReturndataPointer rdPtr ) internal pure returns (int80 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int88 at `rdPtr` in returndata. function readInt88( ReturndataPointer rdPtr ) internal pure returns (int88 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int96 at `rdPtr` in returndata. function readInt96( ReturndataPointer rdPtr ) internal pure returns (int96 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int104 at `rdPtr` in returndata. function readInt104( ReturndataPointer rdPtr ) internal pure returns (int104 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int112 at `rdPtr` in returndata. function readInt112( ReturndataPointer rdPtr ) internal pure returns (int112 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int120 at `rdPtr` in returndata. function readInt120( ReturndataPointer rdPtr ) internal pure returns (int120 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int128 at `rdPtr` in returndata. function readInt128( ReturndataPointer rdPtr ) internal pure returns (int128 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int136 at `rdPtr` in returndata. function readInt136( ReturndataPointer rdPtr ) internal pure returns (int136 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int144 at `rdPtr` in returndata. function readInt144( ReturndataPointer rdPtr ) internal pure returns (int144 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int152 at `rdPtr` in returndata. function readInt152( ReturndataPointer rdPtr ) internal pure returns (int152 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int160 at `rdPtr` in returndata. function readInt160( ReturndataPointer rdPtr ) internal pure returns (int160 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int168 at `rdPtr` in returndata. function readInt168( ReturndataPointer rdPtr ) internal pure returns (int168 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int176 at `rdPtr` in returndata. function readInt176( ReturndataPointer rdPtr ) internal pure returns (int176 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int184 at `rdPtr` in returndata. function readInt184( ReturndataPointer rdPtr ) internal pure returns (int184 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int192 at `rdPtr` in returndata. function readInt192( ReturndataPointer rdPtr ) internal pure returns (int192 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int200 at `rdPtr` in returndata. function readInt200( ReturndataPointer rdPtr ) internal pure returns (int200 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int208 at `rdPtr` in returndata. function readInt208( ReturndataPointer rdPtr ) internal pure returns (int208 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int216 at `rdPtr` in returndata. function readInt216( ReturndataPointer rdPtr ) internal pure returns (int216 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int224 at `rdPtr` in returndata. function readInt224( ReturndataPointer rdPtr ) internal pure returns (int224 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int232 at `rdPtr` in returndata. function readInt232( ReturndataPointer rdPtr ) internal pure returns (int232 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int240 at `rdPtr` in returndata. function readInt240( ReturndataPointer rdPtr ) internal pure returns (int240 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int248 at `rdPtr` in returndata. function readInt248( ReturndataPointer rdPtr ) internal pure returns (int248 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int256 at `rdPtr` in returndata. function readInt256( ReturndataPointer rdPtr ) internal pure returns (int256 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } } library MemoryReaders { /// @dev Reads the memory pointer at `mPtr` in memory. function readMemoryPointer( MemoryPointer mPtr ) internal pure returns (MemoryPointer value) { assembly { value := mload(mPtr) } } /// @dev Reads value at `mPtr` & applies a mask to return only last 4 bytes function readMaskedUint256( MemoryPointer mPtr ) internal pure returns (uint256 value) { value = mPtr.readUint256() & OffsetOrLengthMask; } /// @dev Reads the bool at `mPtr` in memory. function readBool(MemoryPointer mPtr) internal pure returns (bool value) { assembly { value := mload(mPtr) } } /// @dev Reads the address at `mPtr` in memory. function readAddress( MemoryPointer mPtr ) internal pure returns (address value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes1 at `mPtr` in memory. function readBytes1( MemoryPointer mPtr ) internal pure returns (bytes1 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes2 at `mPtr` in memory. function readBytes2( MemoryPointer mPtr ) internal pure returns (bytes2 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes3 at `mPtr` in memory. function readBytes3( MemoryPointer mPtr ) internal pure returns (bytes3 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes4 at `mPtr` in memory. function readBytes4( MemoryPointer mPtr ) internal pure returns (bytes4 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes5 at `mPtr` in memory. function readBytes5( MemoryPointer mPtr ) internal pure returns (bytes5 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes6 at `mPtr` in memory. function readBytes6( MemoryPointer mPtr ) internal pure returns (bytes6 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes7 at `mPtr` in memory. function readBytes7( MemoryPointer mPtr ) internal pure returns (bytes7 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes8 at `mPtr` in memory. function readBytes8( MemoryPointer mPtr ) internal pure returns (bytes8 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes9 at `mPtr` in memory. function readBytes9( MemoryPointer mPtr ) internal pure returns (bytes9 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes10 at `mPtr` in memory. function readBytes10( MemoryPointer mPtr ) internal pure returns (bytes10 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes11 at `mPtr` in memory. function readBytes11( MemoryPointer mPtr ) internal pure returns (bytes11 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes12 at `mPtr` in memory. function readBytes12( MemoryPointer mPtr ) internal pure returns (bytes12 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes13 at `mPtr` in memory. function readBytes13( MemoryPointer mPtr ) internal pure returns (bytes13 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes14 at `mPtr` in memory. function readBytes14( MemoryPointer mPtr ) internal pure returns (bytes14 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes15 at `mPtr` in memory. function readBytes15( MemoryPointer mPtr ) internal pure returns (bytes15 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes16 at `mPtr` in memory. function readBytes16( MemoryPointer mPtr ) internal pure returns (bytes16 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes17 at `mPtr` in memory. function readBytes17( MemoryPointer mPtr ) internal pure returns (bytes17 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes18 at `mPtr` in memory. function readBytes18( MemoryPointer mPtr ) internal pure returns (bytes18 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes19 at `mPtr` in memory. function readBytes19( MemoryPointer mPtr ) internal pure returns (bytes19 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes20 at `mPtr` in memory. function readBytes20( MemoryPointer mPtr ) internal pure returns (bytes20 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes21 at `mPtr` in memory. function readBytes21( MemoryPointer mPtr ) internal pure returns (bytes21 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes22 at `mPtr` in memory. function readBytes22( MemoryPointer mPtr ) internal pure returns (bytes22 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes23 at `mPtr` in memory. function readBytes23( MemoryPointer mPtr ) internal pure returns (bytes23 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes24 at `mPtr` in memory. function readBytes24( MemoryPointer mPtr ) internal pure returns (bytes24 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes25 at `mPtr` in memory. function readBytes25( MemoryPointer mPtr ) internal pure returns (bytes25 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes26 at `mPtr` in memory. function readBytes26( MemoryPointer mPtr ) internal pure returns (bytes26 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes27 at `mPtr` in memory. function readBytes27( MemoryPointer mPtr ) internal pure returns (bytes27 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes28 at `mPtr` in memory. function readBytes28( MemoryPointer mPtr ) internal pure returns (bytes28 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes29 at `mPtr` in memory. function readBytes29( MemoryPointer mPtr ) internal pure returns (bytes29 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes30 at `mPtr` in memory. function readBytes30( MemoryPointer mPtr ) internal pure returns (bytes30 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes31 at `mPtr` in memory. function readBytes31( MemoryPointer mPtr ) internal pure returns (bytes31 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes32 at `mPtr` in memory. function readBytes32( MemoryPointer mPtr ) internal pure returns (bytes32 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint8 at `mPtr` in memory. function readUint8(MemoryPointer mPtr) internal pure returns (uint8 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint16 at `mPtr` in memory. function readUint16( MemoryPointer mPtr ) internal pure returns (uint16 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint24 at `mPtr` in memory. function readUint24( MemoryPointer mPtr ) internal pure returns (uint24 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint32 at `mPtr` in memory. function readUint32( MemoryPointer mPtr ) internal pure returns (uint32 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint40 at `mPtr` in memory. function readUint40( MemoryPointer mPtr ) internal pure returns (uint40 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint48 at `mPtr` in memory. function readUint48( MemoryPointer mPtr ) internal pure returns (uint48 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint56 at `mPtr` in memory. function readUint56( MemoryPointer mPtr ) internal pure returns (uint56 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint64 at `mPtr` in memory. function readUint64( MemoryPointer mPtr ) internal pure returns (uint64 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint72 at `mPtr` in memory. function readUint72( MemoryPointer mPtr ) internal pure returns (uint72 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint80 at `mPtr` in memory. function readUint80( MemoryPointer mPtr ) internal pure returns (uint80 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint88 at `mPtr` in memory. function readUint88( MemoryPointer mPtr ) internal pure returns (uint88 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint96 at `mPtr` in memory. function readUint96( MemoryPointer mPtr ) internal pure returns (uint96 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint104 at `mPtr` in memory. function readUint104( MemoryPointer mPtr ) internal pure returns (uint104 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint112 at `mPtr` in memory. function readUint112( MemoryPointer mPtr ) internal pure returns (uint112 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint120 at `mPtr` in memory. function readUint120( MemoryPointer mPtr ) internal pure returns (uint120 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint128 at `mPtr` in memory. function readUint128( MemoryPointer mPtr ) internal pure returns (uint128 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint136 at `mPtr` in memory. function readUint136( MemoryPointer mPtr ) internal pure returns (uint136 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint144 at `mPtr` in memory. function readUint144( MemoryPointer mPtr ) internal pure returns (uint144 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint152 at `mPtr` in memory. function readUint152( MemoryPointer mPtr ) internal pure returns (uint152 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint160 at `mPtr` in memory. function readUint160( MemoryPointer mPtr ) internal pure returns (uint160 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint168 at `mPtr` in memory. function readUint168( MemoryPointer mPtr ) internal pure returns (uint168 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint176 at `mPtr` in memory. function readUint176( MemoryPointer mPtr ) internal pure returns (uint176 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint184 at `mPtr` in memory. function readUint184( MemoryPointer mPtr ) internal pure returns (uint184 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint192 at `mPtr` in memory. function readUint192( MemoryPointer mPtr ) internal pure returns (uint192 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint200 at `mPtr` in memory. function readUint200( MemoryPointer mPtr ) internal pure returns (uint200 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint208 at `mPtr` in memory. function readUint208( MemoryPointer mPtr ) internal pure returns (uint208 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint216 at `mPtr` in memory. function readUint216( MemoryPointer mPtr ) internal pure returns (uint216 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint224 at `mPtr` in memory. function readUint224( MemoryPointer mPtr ) internal pure returns (uint224 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint232 at `mPtr` in memory. function readUint232( MemoryPointer mPtr ) internal pure returns (uint232 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint240 at `mPtr` in memory. function readUint240( MemoryPointer mPtr ) internal pure returns (uint240 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint248 at `mPtr` in memory. function readUint248( MemoryPointer mPtr ) internal pure returns (uint248 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint256 at `mPtr` in memory. function readUint256( MemoryPointer mPtr ) internal pure returns (uint256 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int8 at `mPtr` in memory. function readInt8(MemoryPointer mPtr) internal pure returns (int8 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int16 at `mPtr` in memory. function readInt16(MemoryPointer mPtr) internal pure returns (int16 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int24 at `mPtr` in memory. function readInt24(MemoryPointer mPtr) internal pure returns (int24 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int32 at `mPtr` in memory. function readInt32(MemoryPointer mPtr) internal pure returns (int32 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int40 at `mPtr` in memory. function readInt40(MemoryPointer mPtr) internal pure returns (int40 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int48 at `mPtr` in memory. function readInt48(MemoryPointer mPtr) internal pure returns (int48 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int56 at `mPtr` in memory. function readInt56(MemoryPointer mPtr) internal pure returns (int56 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int64 at `mPtr` in memory. function readInt64(MemoryPointer mPtr) internal pure returns (int64 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int72 at `mPtr` in memory. function readInt72(MemoryPointer mPtr) internal pure returns (int72 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int80 at `mPtr` in memory. function readInt80(MemoryPointer mPtr) internal pure returns (int80 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int88 at `mPtr` in memory. function readInt88(MemoryPointer mPtr) internal pure returns (int88 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int96 at `mPtr` in memory. function readInt96(MemoryPointer mPtr) internal pure returns (int96 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int104 at `mPtr` in memory. function readInt104( MemoryPointer mPtr ) internal pure returns (int104 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int112 at `mPtr` in memory. function readInt112( MemoryPointer mPtr ) internal pure returns (int112 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int120 at `mPtr` in memory. function readInt120( MemoryPointer mPtr ) internal pure returns (int120 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int128 at `mPtr` in memory. function readInt128( MemoryPointer mPtr ) internal pure returns (int128 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int136 at `mPtr` in memory. function readInt136( MemoryPointer mPtr ) internal pure returns (int136 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int144 at `mPtr` in memory. function readInt144( MemoryPointer mPtr ) internal pure returns (int144 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int152 at `mPtr` in memory. function readInt152( MemoryPointer mPtr ) internal pure returns (int152 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int160 at `mPtr` in memory. function readInt160( MemoryPointer mPtr ) internal pure returns (int160 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int168 at `mPtr` in memory. function readInt168( MemoryPointer mPtr ) internal pure returns (int168 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int176 at `mPtr` in memory. function readInt176( MemoryPointer mPtr ) internal pure returns (int176 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int184 at `mPtr` in memory. function readInt184( MemoryPointer mPtr ) internal pure returns (int184 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int192 at `mPtr` in memory. function readInt192( MemoryPointer mPtr ) internal pure returns (int192 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int200 at `mPtr` in memory. function readInt200( MemoryPointer mPtr ) internal pure returns (int200 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int208 at `mPtr` in memory. function readInt208( MemoryPointer mPtr ) internal pure returns (int208 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int216 at `mPtr` in memory. function readInt216( MemoryPointer mPtr ) internal pure returns (int216 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int224 at `mPtr` in memory. function readInt224( MemoryPointer mPtr ) internal pure returns (int224 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int232 at `mPtr` in memory. function readInt232( MemoryPointer mPtr ) internal pure returns (int232 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int240 at `mPtr` in memory. function readInt240( MemoryPointer mPtr ) internal pure returns (int240 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int248 at `mPtr` in memory. function readInt248( MemoryPointer mPtr ) internal pure returns (int248 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int256 at `mPtr` in memory. function readInt256( MemoryPointer mPtr ) internal pure returns (int256 value) { assembly { value := mload(mPtr) } } } library MemoryWriters { /// @dev Writes `valuePtr` to memory at `mPtr`. function write(MemoryPointer mPtr, MemoryPointer valuePtr) internal pure { assembly { mstore(mPtr, valuePtr) } } /// @dev Writes a boolean `value` to `mPtr` in memory. function write(MemoryPointer mPtr, bool value) internal pure { assembly { mstore(mPtr, value) } } /// @dev Writes an address `value` to `mPtr` in memory. function write(MemoryPointer mPtr, address value) internal pure { assembly { mstore(mPtr, value) } } /// @dev Writes a bytes32 `value` to `mPtr` in memory. /// Separate name to disambiguate literal write parameters. function writeBytes32(MemoryPointer mPtr, bytes32 value) internal pure { assembly { mstore(mPtr, value) } } /// @dev Writes a uint256 `value` to `mPtr` in memory. function write(MemoryPointer mPtr, uint256 value) internal pure { assembly { mstore(mPtr, value) } } /// @dev Writes an int256 `value` to `mPtr` in memory. /// Separate name to disambiguate literal write parameters. function writeInt(MemoryPointer mPtr, int256 value) internal pure { assembly { mstore(mPtr, value) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ItemType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { Execution, FulfillmentComponent, ReceivedItem, SpentItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { ConsiderationItemIndicesAndValidity, OrderToExecute } from "./ReferenceConsiderationStructs.sol"; import { FulfillmentApplicationErrors } from "seaport-types/src/interfaces/FulfillmentApplicationErrors.sol"; import { TokenTransferrerErrors } from "seaport-types/src/interfaces/TokenTransferrerErrors.sol"; /** * @title FulfillmentApplier * @author 0age * @notice FulfillmentApplier contains logic related to applying fulfillments, * both as part of order matching (where offer items are matched to * consideration items) as well as fulfilling available orders (where * order items and consideration items are independently aggregated). */ contract ReferenceFulfillmentApplier is FulfillmentApplicationErrors, TokenTransferrerErrors { /** * @dev Internal pure function to match offer items to consideration items * on a group of orders via a supplied fulfillment. * * @param ordersToExecute The orders to match. * @param offerComponents An array designating offer components to * match to consideration components. * @param considerationComponents An array designating consideration * components to match to offer components. * Note that each consideration amount must * be zero in order for the match operation * to be valid. * @param fulfillmentIndex The index of the fulfillment component * that does not match the initial offer * item. * * @return execution The transfer performed as a result of the fulfillment. */ function _applyFulfillment( OrderToExecute[] memory ordersToExecute, FulfillmentComponent[] memory offerComponents, FulfillmentComponent[] memory considerationComponents, uint256 fulfillmentIndex ) internal pure returns (Execution memory execution) { // Ensure 1+ of both offer and consideration components are supplied. if ( offerComponents.length == 0 || considerationComponents.length == 0 ) { revert OfferAndConsiderationRequiredOnFulfillment(); } // Recipient does not need to be specified because it will always be set // to that of the consideration. // Validate and aggregate consideration items and store the result as a // ReceivedItem. ReceivedItem memory considerationItem = ( _aggregateValidFulfillmentConsiderationItems( ordersToExecute, considerationComponents ) ); // Skip aggregating offer items if no consideration items are available. if (considerationItem.amount == 0) { return execution; } // Validate & aggregate offer items and store result as an Execution. ( execution /** * ItemType itemType, * address token, * uint256 identifier, * address offerer, * bytes32 conduitKey, * uint256 offerAmount */ ) = _aggregateValidFulfillmentOfferItems( ordersToExecute, offerComponents, address(0) // unused ); // Ensure offer and consideration share types, tokens and identifiers. if ( execution.item.itemType != considerationItem.itemType || execution.item.token != considerationItem.token || execution.item.identifier != considerationItem.identifier ) { revert MismatchedFulfillmentOfferAndConsiderationComponents( fulfillmentIndex ); } // If total consideration amount exceeds the offer amount... if (considerationItem.amount > execution.item.amount) { // Retrieve the first consideration component from the fulfillment. FulfillmentComponent memory targetComponent = ( considerationComponents[0] ); // Add excess consideration item amount to original array of orders. ordersToExecute[targetComponent.orderIndex] .receivedItems[targetComponent.itemIndex] .amount = considerationItem.amount - execution.item.amount; // Reduce total consideration amount to equal the offer amount. considerationItem.amount = execution.item.amount; } else { // Retrieve the first offer component from the fulfillment. FulfillmentComponent memory targetComponent = (offerComponents[0]); // Add excess offer item amount to the original array of orders. ordersToExecute[targetComponent.orderIndex] .spentItems[targetComponent.itemIndex] .amount = execution.item.amount - considerationItem.amount; } // Reuse execution struct with consideration amount and recipient. // Only set the recipient if the item amount is non-zero. execution.item.amount = considerationItem.amount; if (execution.item.amount != 0) { execution.item.recipient = considerationItem.recipient; } // Return the final execution that will be triggered for relevant items. return execution; // Execution(execution, offerer, conduitKey); } /** * @dev Internal view function to aggregate offer or consideration items * from a group of orders into a single execution via a supplied array * of fulfillment components. Items that are not available to aggregate * will not be included in the aggregated execution. * * @param ordersToExecute The orders to aggregate. * @param side The side (i.e. offer or consideration). * @param fulfillmentComponents An array designating item components to * aggregate if part of an available order. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token * approvals from. The zero hash signifies that * no conduit should be used (and direct * approvals set on Consideration) * @param recipient The intended recipient for all received * items. * * @return _execution The transfer performed as a result of the fulfillment. */ function _aggregateAvailable( OrderToExecute[] memory ordersToExecute, Side side, FulfillmentComponent[] memory fulfillmentComponents, bytes32 fulfillerConduitKey, address recipient ) internal view returns (Execution memory _execution) { // Retrieve fulfillment components array length and place on stack. uint256 totalFulfillmentComponents = fulfillmentComponents.length; // Ensure at least one fulfillment component has been supplied. if (totalFulfillmentComponents == 0) { revert MissingFulfillmentComponentOnAggregation(side); } Execution memory execution; // If the fulfillment components are offer components... if (side == Side.OFFER) { // Return execution for aggregated items provided by offerer. execution = _aggregateValidFulfillmentOfferItems( ordersToExecute, fulfillmentComponents, recipient ); } else { // Otherwise, fulfillment components are consideration // components. Return execution for aggregated items provided by // the fulfiller. execution = _aggregateConsiderationItems( ordersToExecute, fulfillmentComponents, fulfillerConduitKey ); } return execution; } /** * @dev Internal pure function to check the indicated offer item * matches original item. * * @param orderToExecute The order to compare. * @param offer The offer to compare. * @param execution The aggregated offer item. * * @return invalidFulfillment A boolean indicating whether the * fulfillment is invalid. */ function _checkMatchingOffer( OrderToExecute memory orderToExecute, SpentItem memory offer, Execution memory execution ) internal pure returns (bool invalidFulfillment) { return execution.item.identifier != offer.identifier || execution.offerer != orderToExecute.offerer || execution.conduitKey != orderToExecute.conduitKey || execution.item.itemType != offer.itemType || execution.item.token != offer.token; } /** * @dev Internal pure function to aggregate a group of offer items using * supplied directives on which component items are candidates for * aggregation, skipping items on orders that are not available. * * @param ordersToExecute The orders to aggregate offer items from. * @param offerComponents An array of FulfillmentComponent structs * indicating the order index and item index of each * candidate offer item for aggregation. * @param recipient The recipient for the aggregated offer items. * * @return execution The aggregated offer items. */ function _aggregateValidFulfillmentOfferItems( OrderToExecute[] memory ordersToExecute, FulfillmentComponent[] memory offerComponents, address recipient ) internal pure returns (Execution memory execution) { bool foundItem = false; // Get the order index and item index of the offer component. uint256 orderIndex; uint256 itemIndex; OrderToExecute memory orderToExecute; // Declare variables indicating whether the aggregation is invalid. // Ensure that the order index is not out of range. bool invalidFulfillment; // Ensure that no available items have missing amounts. bool missingItemAmount; // Loop through the offer components, checking for validity. for (uint256 i = 0; i < offerComponents.length; ++i) { // Get the order index and item index of the offer component. orderIndex = offerComponents[i].orderIndex; itemIndex = offerComponents[i].itemIndex; // Ensure that the order index is not out of range. invalidFulfillment = orderIndex >= ordersToExecute.length; // Break if invalid. if (invalidFulfillment) { break; } // Get the order based on offer components order index. orderToExecute = ordersToExecute[orderIndex]; if ( orderToExecute.numerator != 0 && itemIndex < orderToExecute.spentItems.length ) { // Get the spent item based on the offer components item index. SpentItem memory offer = orderToExecute.spentItems[itemIndex]; if (!foundItem) { foundItem = true; // Create the Execution. execution = Execution( ReceivedItem( offer.itemType, offer.token, offer.identifier, offer.amount, payable(recipient) ), orderToExecute.offerer, orderToExecute.conduitKey ); // If component index > 0, swap component pointer with // pointer to first component so that any remainder after // fulfillment can be added back to the first item. if (i != 0) { FulfillmentComponent memory firstComponent = offerComponents[0]; offerComponents[0] = offerComponents[i]; offerComponents[i] = firstComponent; } } else { // Update the Received Item amount. execution.item.amount = execution.item.amount + offer.amount; // Ensure indicated offer item matches original item. invalidFulfillment = _checkMatchingOffer( orderToExecute, offer, execution ); } // Ensure the item has a nonzero amount. missingItemAmount = offer.amount == 0; invalidFulfillment = invalidFulfillment || missingItemAmount; // Zero out amount on original offerItem to indicate it's spent. offer.amount = 0; // Break if invalid. if (invalidFulfillment) { break; } } } // Revert if an order/item was out of range or was not aggregatable. if (invalidFulfillment) { if (missingItemAmount) { revert MissingItemAmount(); } revert InvalidFulfillmentComponentData(); } } /** * @dev Internal view function to aggregate consideration items from a group * of orders into a single execution via a supplied components array. * Consideration items that are not available to aggregate will not be * included in the aggregated execution. * * @param ordersToExecute The orders to aggregate. * @param considerationComponents An array designating consideration * components to aggregate if part of an * available order. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used (and direct * approvals set on Consideration) * * @return execution The transfer performed as a result of the fulfillment. */ function _aggregateConsiderationItems( OrderToExecute[] memory ordersToExecute, FulfillmentComponent[] memory considerationComponents, bytes32 fulfillerConduitKey ) internal view returns (Execution memory execution) { // Validate and aggregate consideration items on available orders and // store result as a ReceivedItem. ReceivedItem memory receiveConsiderationItem = ( _aggregateValidFulfillmentConsiderationItems( ordersToExecute, considerationComponents ) ); if (receiveConsiderationItem.amount != 0) { // Return execution for aggregated items provided by the fulfiller. execution = Execution( receiveConsiderationItem, msg.sender, fulfillerConduitKey ); } else { // Return an empty execution if the received item amount is zero. execution = Execution( receiveConsiderationItem, address(0), bytes32(0) ); } } /** * @dev Internal pure function to check the indicated consideration item * matches original item. * * @param consideration The consideration to compare. * @param receivedItem The aggregated received item. * * @return invalidFulfillment A boolean indicating whether the fulfillment * is invalid. */ function _checkMatchingConsideration( ReceivedItem memory consideration, ReceivedItem memory receivedItem ) internal pure returns (bool invalidFulfillment) { return receivedItem.recipient != consideration.recipient || receivedItem.itemType != consideration.itemType || receivedItem.token != consideration.token || receivedItem.identifier != consideration.identifier; } /** * @dev Internal pure function to aggregate a group of consideration items * using supplied directives on which component items are candidates * for aggregation, skipping items on orders that are not available. * * @param ordersToExecute The orders to aggregate consideration * items from. * @param considerationComponents An array of FulfillmentComponent structs * indicating the order index and item index * of each candidate consideration item for * aggregation. * * @return receivedItem The aggregated consideration items. */ function _aggregateValidFulfillmentConsiderationItems( OrderToExecute[] memory ordersToExecute, FulfillmentComponent[] memory considerationComponents ) internal pure returns (ReceivedItem memory receivedItem) { bool foundItem = false; // Declare struct in memory to avoid declaring multiple local variables. ConsiderationItemIndicesAndValidity memory potentialCandidate; ReceivedItem memory consideration; OrderToExecute memory orderToExecute; // Loop through the consideration components and validate // their fulfillment. for (uint256 i = 0; i < considerationComponents.length; ++i) { // Get the order index and item index of the consideration // component. potentialCandidate.orderIndex = considerationComponents[i] .orderIndex; potentialCandidate.itemIndex = considerationComponents[i].itemIndex; /// Ensure that the order index is not out of range. potentialCandidate.invalidFulfillment = potentialCandidate.orderIndex >= ordersToExecute.length; // Break if invalid. if (potentialCandidate.invalidFulfillment) { break; } // Get order based on consideration components order index. orderToExecute = ordersToExecute[potentialCandidate.orderIndex]; // Confirm that the order is being fulfilled. if ( orderToExecute.numerator != 0 && potentialCandidate.itemIndex < orderToExecute.receivedItems.length ) { // Retrieve relevant item using item index. consideration = orderToExecute.receivedItems[ potentialCandidate.itemIndex ]; if (!foundItem) { foundItem = true; // Create the received item. receivedItem = ReceivedItem( consideration.itemType, consideration.token, consideration.identifier, consideration.amount, consideration.recipient ); // If component index > 0, swap component pointer with // pointer to first component so that any remainder after // fulfillment can be added back to the first item. if (i != 0) { FulfillmentComponent memory firstComponent = considerationComponents[0]; considerationComponents[0] = considerationComponents[i]; considerationComponents[i] = firstComponent; } } else { // Update Received Item amount. receivedItem.amount = receivedItem.amount + consideration.amount; // Ensure the indicated consideration item matches // original item. potentialCandidate .invalidFulfillment = _checkMatchingConsideration( consideration, receivedItem ); } // Ensure the item has a nonzero amount. potentialCandidate.missingItemAmount = consideration.amount == 0; potentialCandidate.invalidFulfillment = potentialCandidate.invalidFulfillment || potentialCandidate.missingItemAmount; // Zero out amount on original consideration item to // indicate it is spent. consideration.amount = 0; // Break if invalid. if (potentialCandidate.invalidFulfillment) { break; } } } // Revert if an order/item was out of range or was not aggregatable. if (potentialCandidate.invalidFulfillment) { if (potentialCandidate.missingItemAmount) { revert MissingItemAmount(); } revert InvalidFulfillmentComponentData(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ItemType, OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { AdvancedOrder, ConsiderationItem, CriteriaResolver, OfferItem, Order, OrderParameters, ReceivedItem, SpentItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { AccumulatorStruct, FractionData, OrderToExecute, OrderValidation } from "./ReferenceConsiderationStructs.sol"; import { ReferenceBasicOrderFulfiller } from "./ReferenceBasicOrderFulfiller.sol"; import { ReferenceCriteriaResolution } from "./ReferenceCriteriaResolution.sol"; import { ReferenceAmountDeriver } from "./ReferenceAmountDeriver.sol"; /** * @title OrderFulfiller * @author 0age * @notice OrderFulfiller contains logic related to order fulfillment. */ contract ReferenceOrderFulfiller is ReferenceBasicOrderFulfiller, ReferenceCriteriaResolution, ReferenceAmountDeriver { /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceBasicOrderFulfiller(conduitController) {} /** * @dev Internal function to validate an order and update its status, adjust * prices based on current time, apply criteria resolvers, determine * what portion to fill, and transfer relevant tokens. * * @param advancedOrder The order to fulfill as well as the fraction * to fill. Note that all offer and consideration * components must divide with no remainder for * the partial fill to be valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a proof * that the supplied token identifier is * contained in the order's merkle root. Note * that a criteria of zero indicates that any * (transferable) token identifier is valid and * that no proof needs to be supplied. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used (and direct approvals set on * Consideration). * @param recipient The intended recipient for all received items. * * @return A boolean indicating whether the order has been fulfilled. */ function _validateAndFulfillAdvancedOrder( AdvancedOrder memory advancedOrder, CriteriaResolver[] memory criteriaResolvers, bytes32 fulfillerConduitKey, address recipient ) internal returns (bool) { // Validate the order and revert if it's invalid. OrderValidation memory orderValidation = _validateOrder( advancedOrder, true ); // Apply criteria resolvers using generated orders and details arrays. _applyCriteriaResolversAdvanced(advancedOrder, criteriaResolvers); // Retrieve the order parameters after applying criteria resolvers. OrderParameters memory orderParameters = advancedOrder.parameters; // Perform each item transfer with the appropriate fractional amount. orderValidation.orderToExecute = _applyFractions( orderParameters, orderValidation.newNumerator, orderValidation.newDenominator ); // Declare empty bytes32 array. bytes32[] memory priorOrderHashes = new bytes32[](0); if (orderParameters.orderType != OrderType.CONTRACT) { // Ensure restricted orders have valid submitter or pass zone check. _assertRestrictedAdvancedOrderAuthorization( advancedOrder, orderValidation.orderToExecute, priorOrderHashes, orderValidation.orderHash, orderParameters.zoneHash, orderParameters.orderType, orderParameters.offerer, orderParameters.zone ); // Update the order status to reflect the new numerator and denominator. // Revert if the order is not valid. _updateStatus( orderValidation.orderHash, orderValidation.newNumerator, orderValidation.newDenominator, true ); } else { bytes32 orderHash = _getGeneratedOrder( orderValidation.orderToExecute, advancedOrder.parameters, advancedOrder.extraData, true ); orderValidation.orderHash = orderHash; } // Transfer each item contained in the order. _transferEach( orderParameters, orderValidation.orderToExecute, fulfillerConduitKey, recipient ); // Declare bytes32 array with this order's hash priorOrderHashes = new bytes32[](1); priorOrderHashes[0] = orderValidation.orderHash; // Ensure restricted orders have valid submitter or pass zone check. _assertRestrictedAdvancedOrderValidity( advancedOrder, orderValidation.orderToExecute, priorOrderHashes, orderValidation.orderHash, orderParameters.zoneHash, orderParameters.orderType, orderParameters.offerer, orderParameters.zone ); // Emit an event signifying that the order has been fulfilled. emit OrderFulfilled( orderValidation.orderHash, orderParameters.offerer, orderParameters.zone, recipient, orderValidation.orderToExecute.spentItems, orderValidation.orderToExecute.receivedItems ); return true; } /** * @dev Internal view function to apply a respective fraction to the * amount being transferred on each item of an order. * * @param orderParameters The parameters for the fulfilled order. * @param numerator A value indicating the portion of the order * that should be filled. * @param denominator A value indicating the total order size. * @return orderToExecute Returns the order with items that are being * transferred. This will be used for the * OrderFulfilled Event. */ function _applyFractions( OrderParameters memory orderParameters, uint256 numerator, uint256 denominator ) internal view returns (OrderToExecute memory orderToExecute) { // Derive order duration, time elapsed, and time remaining. // Store in memory to avoid stack too deep issues. FractionData memory fractionData = FractionData( numerator, denominator, 0, // fulfillerConduitKey is not used here. orderParameters.startTime, orderParameters.endTime ); // Create the array to store the spent items for event. orderToExecute.spentItems = ( new SpentItem[](orderParameters.offer.length) ); // Declare a nested scope to minimize stack depth. { // Iterate over each offer on the order. for (uint256 i = 0; i < orderParameters.offer.length; ++i) { // Retrieve the offer item. OfferItem memory offerItem = orderParameters.offer[i]; // Offer items for the native token can not be received outside // of a match order function except as part of a contract order. if ( offerItem.itemType == ItemType.NATIVE && orderParameters.orderType != OrderType.CONTRACT ) { revert InvalidNativeOfferItem(); } // Apply fill fraction to derive offer item amount to transfer. uint256 amount = _applyFraction( offerItem.startAmount, offerItem.endAmount, fractionData, false ); // Create Spent Item for the OrderFulfilled event. orderToExecute.spentItems[i] = SpentItem( offerItem.itemType, offerItem.token, offerItem.identifierOrCriteria, amount ); } } // Create the array to store the received items for event. orderToExecute.receivedItems = ( new ReceivedItem[](orderParameters.consideration.length) ); // Declare a nested scope to minimize stack depth. { // Iterate over each consideration on the order. for (uint256 i = 0; i < orderParameters.consideration.length; ++i) { // Retrieve the consideration item. ConsiderationItem memory considerationItem = ( orderParameters.consideration[i] ); // Apply fraction & derive considerationItem amount to transfer. uint256 amount = _applyFraction( considerationItem.startAmount, considerationItem.endAmount, fractionData, true ); // Create Received Item from Offer item & add to structs array. orderToExecute.receivedItems[i] = ReceivedItem( considerationItem.itemType, considerationItem.token, considerationItem.identifierOrCriteria, amount, considerationItem.recipient ); } } // Return the order to execute. return orderToExecute; } /** * @dev Internal function to transfer each item contained in a given single * order fulfillment. * * @param orderParameters The parameters for the fulfilled order. * @param orderToExecute The items that are being transferred. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used (and direct approvals set on * Consideration). * @param recipient The intended recipient for all received items. */ function _transferEach( OrderParameters memory orderParameters, OrderToExecute memory orderToExecute, bytes32 fulfillerConduitKey, address recipient ) internal { // Create the accumulator struct. AccumulatorStruct memory accumulatorStruct; // Get the offerer of the order. address offerer = orderParameters.offerer; // Get the conduitKey of the order bytes32 conduitKey = orderParameters.conduitKey; // Declare a nested scope to minimize stack depth. { // Iterate over each spent item on the order. for (uint256 i = 0; i < orderToExecute.spentItems.length; ++i) { // Retrieve the spent item. SpentItem memory spentItem = orderToExecute.spentItems[i]; // Create Received Item from Spent Item for transfer. ReceivedItem memory receivedItem = ReceivedItem( spentItem.itemType, spentItem.token, spentItem.identifier, spentItem.amount, payable(recipient) ); // Transfer the item from the offerer to the recipient. _transfer(receivedItem, offerer, conduitKey, accumulatorStruct); } } // Declare a nested scope to minimize stack depth. { // Iterate over each received item on the order. for (uint256 i = 0; i < orderToExecute.receivedItems.length; ++i) { // Retrieve the received item. ReceivedItem memory receivedItem = ( orderToExecute.receivedItems[i] ); if (receivedItem.itemType == ItemType.NATIVE) { // Ensure that sufficient native tokens are still available. if (receivedItem.amount > address(this).balance) { revert InsufficientNativeTokensSupplied(); } } // Transfer item from caller to recipient specified by the item. _transfer( receivedItem, msg.sender, fulfillerConduitKey, accumulatorStruct ); } } // Trigger any remaining accumulated transfers via call to the conduit. _triggerIfArmed(accumulatorStruct); // If any native tokens remain after applying fulfillments... if (address(this).balance != 0) { // return them to the caller. _transferNativeTokens(payable(msg.sender), address(this).balance); } } /** * @dev Internal pure function to convert an order to an advanced order with * numerator and denominator of 1 and empty extraData. * * @param order The order to convert. * * @return advancedOrder The new advanced order. */ function _convertOrderToAdvanced( Order calldata order ) internal pure returns (AdvancedOrder memory advancedOrder) { // Convert to partial order (1/1 or full fill) and return new value. advancedOrder = AdvancedOrder( order.parameters, 1, 1, order.signature, "" ); } /** * @dev Internal pure function to convert an array of orders to an array of * advanced orders with numerator and denominator of 1. * * @param orders The orders to convert. * * @return advancedOrders The new array of partial orders. */ function _convertOrdersToAdvanced( Order[] calldata orders ) internal pure returns (AdvancedOrder[] memory advancedOrders) { // Read the number of orders from calldata and place on the stack. uint256 totalOrders = orders.length; // Allocate new empty array for each partial order in memory. advancedOrders = new AdvancedOrder[](totalOrders); // Iterate over the given orders. for (uint256 i = 0; i < totalOrders; ++i) { // Convert to partial order (1/1 or full fill) and update array. advancedOrders[i] = _convertOrderToAdvanced(orders[i]); } // Return the array of advanced orders. return advancedOrders; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ConduitItemType } from "./ConduitEnums.sol"; /** * @dev A ConduitTransfer is a struct that contains the information needed for a * conduit to transfer an item from one address to another. */ struct ConduitTransfer { ConduitItemType itemType; address token; address from; address to; uint256 identifier; uint256 amount; } /** * @dev A ConduitBatch1155Transfer is a struct that contains the information * needed for a conduit to transfer a batch of ERC-1155 tokens from one * address to another. */ struct ConduitBatch1155Transfer { address token; address from; address to; uint256[] ids; uint256[] amounts; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { AdvancedOrder, BasicOrderParameters, CriteriaResolver, Execution, Fulfillment, FulfillmentComponent, Order, OrderComponents } from "../lib/ConsiderationStructs.sol"; /** * @title SeaportInterface * @author 0age * @custom:version 1.6 * @notice Seaport is a generalized native token/ERC20/ERC721/ERC1155 * marketplace. It minimizes external calls to the greatest extent * possible and provides lightweight methods for common routes as well * as more flexible methods for composing advanced orders. * * @dev SeaportInterface contains all external function interfaces for Seaport. */ interface SeaportInterface { /** * @notice Fulfill an order offering an ERC721 token by supplying Ether (or * the native token for the given chain) as consideration for the * order. An arbitrary number of "additional recipients" may also be * supplied which will each receive native tokens from the fulfiller * as consideration. * * @param parameters Additional information on the fulfilled order. Note * that the offerer must first approve this contract (or * their preferred conduit if indicated by the order) for * their offered ERC721 token to be transferred. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillBasicOrder( BasicOrderParameters calldata parameters ) external payable returns (bool fulfilled); /** * @notice Fulfill an order with an arbitrary number of items for offer and * consideration. Note that this function does not support * criteria-based orders or partial filling of orders (though * filling the remainder of a partially-filled order is supported). * * @param order The order to fulfill. Note that both the * offerer and the fulfiller must first approve * this contract (or the corresponding conduit if * indicated) to transfer any relevant tokens on * their behalf and that contracts must implement * `onERC1155Received` to receive ERC1155 tokens * as consideration. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used, with direct approvals set on * Seaport. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillOrder( Order calldata order, bytes32 fulfillerConduitKey ) external payable returns (bool fulfilled); /** * @notice Fill an order, fully or partially, with an arbitrary number of * items for offer and consideration alongside criteria resolvers * containing specific token identifiers and associated proofs. * * @param advancedOrder The order to fulfill along with the fraction * of the order to attempt to fill. Note that * both the offerer and the fulfiller must first * approve this contract (or their preferred * conduit if indicated by the order) to transfer * any relevant tokens on their behalf and that * contracts must implement `onERC1155Received` * to receive ERC1155 tokens as consideration. * Also note that all offer and consideration * components must have no remainder after * multiplication of the respective amount with * the supplied fraction for the partial fill to * be considered valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a proof * that the supplied token identifier is * contained in the merkle root held by the item * in question's criteria element. Note that an * empty criteria indicates that any * (transferable) token identifier on the token * in question is valid and that no associated * proof needs to be supplied. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used, with direct approvals set on * Seaport. * @param recipient The intended recipient for all received items, * with `address(0)` indicating that the caller * should receive the items. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillAdvancedOrder( AdvancedOrder calldata advancedOrder, CriteriaResolver[] calldata criteriaResolvers, bytes32 fulfillerConduitKey, address recipient ) external payable returns (bool fulfilled); /** * @notice Attempt to fill a group of orders, each with an arbitrary number * of items for offer and consideration. Any order that is not * currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * Note that this function does not support criteria-based orders or * partial filling of orders (though filling the remainder of a * partially-filled order is supported). * * @param orders The orders to fulfill. Note that both * the offerer and the fulfiller must first * approve this contract (or the * corresponding conduit if indicated) to * transfer any relevant tokens on their * behalf and that contracts must implement * `onERC1155Received` to receive ERC1155 * tokens as consideration. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used, with * direct approvals set on this contract. * @param maximumFulfilled The maximum number of orders to fulfill. * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of * this array. */ function fulfillAvailableOrders( Order[] calldata orders, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, uint256 maximumFulfilled ) external payable returns (bool[] memory availableOrders, Execution[] memory executions); /** * @notice Attempt to fill a group of orders, fully or partially, with an * arbitrary number of items for offer and consideration per order * alongside criteria resolvers containing specific token * identifiers and associated proofs. Any order that is not * currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * * @param advancedOrders The orders to fulfill along with the * fraction of those orders to attempt to * fill. Note that both the offerer and the * fulfiller must first approve this * contract (or their preferred conduit if * indicated by the order) to transfer any * relevant tokens on their behalf and that * contracts must implement * `onERC1155Received` to enable receipt of * ERC1155 tokens as consideration. Also * note that all offer and consideration * components must have no remainder after * multiplication of the respective amount * with the supplied fraction for an * order's partial fill amount to be * considered valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a * proof that the supplied token identifier * is contained in the merkle root held by * the item in question's criteria element. * Note that an empty criteria indicates * that any (transferable) token * identifier on the token in question is * valid and that no associated proof needs * to be supplied. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used, with * direct approvals set on this contract. * @param recipient The intended recipient for all received * items, with `address(0)` indicating that * the caller should receive the items. * @param maximumFulfilled The maximum number of orders to fulfill. * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of * this array. */ function fulfillAvailableAdvancedOrders( AdvancedOrder[] calldata advancedOrders, CriteriaResolver[] calldata criteriaResolvers, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, address recipient, uint256 maximumFulfilled ) external payable returns (bool[] memory availableOrders, Execution[] memory executions); /** * @notice Match an arbitrary number of orders, each with an arbitrary * number of items for offer and consideration along with a set of * fulfillments allocating offer components to consideration * components. Note that this function does not support * criteria-based or partial filling of orders (though filling the * remainder of a partially-filled order is supported). Any unspent * offer item amounts or native tokens will be transferred to the * caller. * * @param orders The orders to match. Note that both the offerer and * fulfiller on each order must first approve this * contract (or their conduit if indicated by the order) * to transfer any relevant tokens on their behalf and * each consideration recipient must implement * `onERC1155Received` to enable ERC1155 token receipt. * @param fulfillments An array of elements allocating offer components to * consideration components. Note that each * consideration component must be fully met for the * match operation to be valid. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of this * array. */ function matchOrders( Order[] calldata orders, Fulfillment[] calldata fulfillments ) external payable returns (Execution[] memory executions); /** * @notice Match an arbitrary number of full or partial orders, each with an * arbitrary number of items for offer and consideration, supplying * criteria resolvers containing specific token identifiers and * associated proofs as well as fulfillments allocating offer * components to consideration components. Any unspent offer item * amounts will be transferred to the designated recipient (with the * null address signifying to use the caller) and any unspent native * tokens will be returned to the caller. * * @param orders The advanced orders to match. Note that both the * offerer and fulfiller on each order must first * approve this contract (or a preferred conduit if * indicated by the order) to transfer any relevant * tokens on their behalf and each consideration * recipient must implement `onERC1155Received` in * order to receive ERC1155 tokens. Also note that * the offer and consideration components for each * order must have no remainder after multiplying * the respective amount with the supplied fraction * in order for the group of partial fills to be * considered valid. * @param criteriaResolvers An array where each element contains a reference * to a specific order as well as that order's * offer or consideration, a token identifier, and * a proof that the supplied token identifier is * contained in the order's merkle root. Note that * an empty root indicates that any (transferable) * token identifier is valid and that no associated * proof needs to be supplied. * @param fulfillments An array of elements allocating offer components * to consideration components. Note that each * consideration component must be fully met in * order for the match operation to be valid. * @param recipient The intended recipient for all unspent offer * item amounts, or the caller if the null address * is supplied. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or native * tokens will not be reflected as part of this array. */ function matchAdvancedOrders( AdvancedOrder[] calldata orders, CriteriaResolver[] calldata criteriaResolvers, Fulfillment[] calldata fulfillments, address recipient ) external payable returns (Execution[] memory executions); /** * @notice Cancel an arbitrary number of orders. Note that only the offerer * or the zone of a given order may cancel it. Callers should ensure * that the intended order was cancelled by calling `getOrderStatus` * and confirming that `isCancelled` returns `true`. * * @param orders The orders to cancel. * * @return cancelled A boolean indicating whether the supplied orders have * been successfully cancelled. */ function cancel( OrderComponents[] calldata orders ) external returns (bool cancelled); /** * @notice Validate an arbitrary number of orders, thereby registering their * signatures as valid and allowing the fulfiller to skip signature * verification on fulfillment. Note that validated orders may still * be unfulfillable due to invalid item amounts or other factors; * callers should determine whether validated orders are fulfillable * by simulating the fulfillment call prior to execution. Also note * that anyone can validate a signed order, but only the offerer can * validate an order without supplying a signature. * * @param orders The orders to validate. * * @return validated A boolean indicating whether the supplied orders have * been successfully validated. */ function validate( Order[] calldata orders ) external returns (bool validated); /** * @notice Cancel all orders from a given offerer with a given zone in bulk * by incrementing a counter. Note that only the offerer may * increment the counter. * * @return newCounter The new counter. */ function incrementCounter() external returns (uint256 newCounter); /** * @notice Fulfill an order offering an ERC721 token by supplying Ether (or * the native token for the given chain) as consideration for the * order. An arbitrary number of "additional recipients" may also be * supplied which will each receive native tokens from the fulfiller * as consideration. Note that this function costs less gas than * `fulfillBasicOrder` due to the zero bytes in the function * selector (0x00000000) which also results in earlier function * dispatch. * * @param parameters Additional information on the fulfilled order. Note * that the offerer must first approve this contract (or * their preferred conduit if indicated by the order) for * their offered ERC721 token to be transferred. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillBasicOrder_efficient_6GL6yc( BasicOrderParameters calldata parameters ) external payable returns (bool fulfilled); /** * @notice Retrieve the order hash for a given order. * * @param order The components of the order. * * @return orderHash The order hash. */ function getOrderHash( OrderComponents calldata order ) external view returns (bytes32 orderHash); /** * @notice Retrieve the status of a given order by hash, including whether * the order has been cancelled or validated and the fraction of the * order that has been filled. * * @param orderHash The order hash in question. * * @return isValidated A boolean indicating whether the order in question * has been validated (i.e. previously approved or * partially filled). * @return isCancelled A boolean indicating whether the order in question * has been cancelled. * @return totalFilled The total portion of the order that has been filled * (i.e. the "numerator"). * @return totalSize The total size of the order that is either filled or * unfilled (i.e. the "denominator"). */ function getOrderStatus( bytes32 orderHash ) external view returns ( bool isValidated, bool isCancelled, uint256 totalFilled, uint256 totalSize ); /** * @notice Retrieve the current counter for a given offerer. * * @param offerer The offerer in question. * * @return counter The current counter. */ function getCounter( address offerer ) external view returns (uint256 counter); /** * @notice Retrieve configuration information for this contract. * * @return version The contract version. * @return domainSeparator The domain separator for this contract. * @return conduitController The conduit Controller set for this contract. */ function information() external view returns ( string memory version, bytes32 domainSeparator, address conduitController ); function getContractOffererNonce( address contractOfferer ) external view returns (uint256 nonce); /** * @notice Retrieve the name of this contract. * * @return contractName The name of this contract. */ function name() external view returns (string memory contractName); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { AmountDerivationErrors } from "seaport-types/src/interfaces/AmountDerivationErrors.sol"; import { FractionData } from "./ReferenceConsiderationStructs.sol"; /** * @title ReferenceAmountDeriver * @author 0age * @notice ReferenceAmountDeriver contains view and pure functions related to * deriving item amounts based on partial fill quantity and on linear * interpolation based on current time when the start amount and end * amount differ. */ contract ReferenceAmountDeriver is AmountDerivationErrors { /** * @dev Internal view function to derive the current amount of a given item * based on the current price, the starting price, and the ending * price. If the start and end prices differ, the current price will be * interpolated on a linear basis. * * @param startAmount The starting amount of the item. * @param endAmount The ending amount of the item. * @param startTime The starting time of the order. * @param endTime The end time of the order. * @param roundUp A boolean indicating whether the resultant amount * should be rounded up or down. * * @return The current amount. */ function _locateCurrentAmount( uint256 startAmount, uint256 endAmount, uint256 startTime, uint256 endTime, bool roundUp ) internal view returns (uint256) { // Only modify end amount if it doesn't already equal start amount. if (startAmount != endAmount) { // Leave extra amount to add for rounding at zero (i.e. round down). uint256 extraCeiling = 0; // Derive the duration for the order and place it on the stack. uint256 duration = endTime - startTime; // Derive time elapsed since the order started & place on stack. uint256 elapsed = block.timestamp - startTime; // Derive time remaining until order expires and place on stack. uint256 remaining = duration - elapsed; // If rounding up, set rounding factor to one less than denominator. if (roundUp) { extraCeiling = duration - 1; } // Aggregate new amounts weighted by time with rounding factor. uint256 totalBeforeDivision = ((startAmount * remaining) + (endAmount * elapsed) + extraCeiling); // Divide totalBeforeDivision by duration to get the new amount. uint256 newAmount = totalBeforeDivision / duration; // Return the current amount. return newAmount; } // Return the original amount. return endAmount; } /** * @dev Internal pure function to return a fraction of a given value and to * ensure the resultant value does not have any fractional component. * * @param numerator A value indicating the portion of the order that * should be filled. * @param denominator A value indicating the total size of the order. * @param value The value for which to compute the fraction. * * @return newValue The value after applying the fraction. */ function _getFraction( uint256 numerator, uint256 denominator, uint256 value ) internal pure returns (uint256 newValue) { // Return value early in cases where the fraction resolves to 1. if (numerator == denominator) { return value; } // Multiply the numerator by the value and ensure no overflow occurs. uint256 valueTimesNumerator = value * numerator; // Divide that value by the denominator to get the new value. newValue = valueTimesNumerator / denominator; // Ensure that division gave a final result with no remainder. bool exact = ((newValue * denominator) / numerator) == value; if (!exact) { revert InexactFraction(); } } /** * @dev Internal view function to apply a fraction to a consideration * or offer item. * * @param startAmount The starting amount of the item. * @param endAmount The ending amount of the item. * @param fractionData A struct containing the data used to apply a * fraction to an order. * @param roundUp A boolean indicating whether the resultant * amount should be rounded up or down. * * @return amount The received item to transfer with the final amount. */ function _applyFraction( uint256 startAmount, uint256 endAmount, FractionData memory fractionData, bool roundUp ) internal view returns (uint256 amount) { // If start amount equals end amount, apply fraction to end amount. if (startAmount == endAmount) { amount = _getFraction( fractionData.numerator, fractionData.denominator, endAmount ); } else { // Otherwise, apply fraction to both to interpolated final amount. amount = _locateCurrentAmount( _getFraction( fractionData.numerator, fractionData.denominator, startAmount ), _getFraction( fractionData.numerator, fractionData.denominator, endAmount ), fractionData.startTime, fractionData.endTime, roundUp ); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { Side } from "../lib/ConsiderationEnums.sol"; /** * @title FulfillmentApplicationErrors * @author 0age * @notice FulfillmentApplicationErrors contains errors related to fulfillment * application and aggregation. */ interface FulfillmentApplicationErrors { /** * @dev Revert with an error when a fulfillment is provided that does not * declare at least one component as part of a call to fulfill * available orders. */ error MissingFulfillmentComponentOnAggregation(Side side); /** * @dev Revert with an error when a fulfillment is provided that does not * declare at least one offer component and at least one consideration * component. */ error OfferAndConsiderationRequiredOnFulfillment(); /** * @dev Revert with an error when the initial offer item named by a * fulfillment component does not match the type, token, identifier, * or conduit preference of the initial consideration item. * * @param fulfillmentIndex The index of the fulfillment component that * does not match the initial offer item. */ error MismatchedFulfillmentOfferAndConsiderationComponents( uint256 fulfillmentIndex ); /** * @dev Revert with an error when an order or item index are out of range * or a fulfillment component does not match the type, token, * identifier, or conduit preference of the initial consideration item. */ error InvalidFulfillmentComponentData(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { BasicOrderRouteType, BasicOrderType, ItemType, OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { AdditionalRecipient, BasicOrderParameters, ConsiderationItem, OfferItem, ReceivedItem, SpentItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { AccumulatorStruct, BasicFulfillmentHashes, FulfillmentItemTypes } from "./ReferenceConsiderationStructs.sol"; import { ReferenceOrderValidator } from "./ReferenceOrderValidator.sol"; /** * @title BasicOrderFulfiller * @author 0age * @notice BasicOrderFulfiller contains functionality for fulfilling "basic" * orders. */ contract ReferenceBasicOrderFulfiller is ReferenceOrderValidator { // Map BasicOrderType to BasicOrderRouteType mapping(BasicOrderType => BasicOrderRouteType) internal _OrderToRouteType; // Map BasicOrderType to OrderType mapping(BasicOrderType => OrderType) internal _BasicOrderToOrderType; /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceOrderValidator(conduitController) { createMappings(); } /** * @dev Creates a mapping of BasicOrderType Enums to BasicOrderRouteType * Enums and BasicOrderType Enums to OrderType Enums. Note that this * is wildly inefficient, but makes the logic easier to follow when * performing the fulfillment. */ function createMappings() internal { // BasicOrderType to BasicOrderRouteType // ETH TO ERC 721 _OrderToRouteType[ BasicOrderType.ETH_TO_ERC721_FULL_OPEN ] = BasicOrderRouteType.ETH_TO_ERC721; _OrderToRouteType[ BasicOrderType.ETH_TO_ERC721_PARTIAL_OPEN ] = BasicOrderRouteType.ETH_TO_ERC721; _OrderToRouteType[ BasicOrderType.ETH_TO_ERC721_FULL_RESTRICTED ] = BasicOrderRouteType.ETH_TO_ERC721; _OrderToRouteType[ BasicOrderType.ETH_TO_ERC721_PARTIAL_RESTRICTED ] = BasicOrderRouteType.ETH_TO_ERC721; // ETH TO ERC 1155 _OrderToRouteType[ BasicOrderType.ETH_TO_ERC1155_FULL_OPEN ] = BasicOrderRouteType.ETH_TO_ERC1155; _OrderToRouteType[ BasicOrderType.ETH_TO_ERC1155_PARTIAL_OPEN ] = BasicOrderRouteType.ETH_TO_ERC1155; _OrderToRouteType[ BasicOrderType.ETH_TO_ERC1155_FULL_RESTRICTED ] = BasicOrderRouteType.ETH_TO_ERC1155; _OrderToRouteType[ BasicOrderType.ETH_TO_ERC1155_PARTIAL_RESTRICTED ] = BasicOrderRouteType.ETH_TO_ERC1155; // ERC 20 TO ERC 721 _OrderToRouteType[ BasicOrderType.ERC20_TO_ERC721_FULL_OPEN ] = BasicOrderRouteType.ERC20_TO_ERC721; _OrderToRouteType[ BasicOrderType.ERC20_TO_ERC721_PARTIAL_OPEN ] = BasicOrderRouteType.ERC20_TO_ERC721; _OrderToRouteType[ BasicOrderType.ERC20_TO_ERC721_FULL_RESTRICTED ] = BasicOrderRouteType.ERC20_TO_ERC721; _OrderToRouteType[ BasicOrderType.ERC20_TO_ERC721_PARTIAL_RESTRICTED ] = BasicOrderRouteType.ERC20_TO_ERC721; // ERC 20 TO ERC 1155 _OrderToRouteType[ BasicOrderType.ERC20_TO_ERC1155_FULL_OPEN ] = BasicOrderRouteType.ERC20_TO_ERC1155; _OrderToRouteType[ BasicOrderType.ERC20_TO_ERC1155_PARTIAL_OPEN ] = BasicOrderRouteType.ERC20_TO_ERC1155; _OrderToRouteType[ BasicOrderType.ERC20_TO_ERC1155_FULL_RESTRICTED ] = BasicOrderRouteType.ERC20_TO_ERC1155; _OrderToRouteType[ BasicOrderType.ERC20_TO_ERC1155_PARTIAL_RESTRICTED ] = BasicOrderRouteType.ERC20_TO_ERC1155; // ERC 721 TO ERC 20 _OrderToRouteType[ BasicOrderType.ERC721_TO_ERC20_FULL_OPEN ] = BasicOrderRouteType.ERC721_TO_ERC20; _OrderToRouteType[ BasicOrderType.ERC721_TO_ERC20_PARTIAL_OPEN ] = BasicOrderRouteType.ERC721_TO_ERC20; _OrderToRouteType[ BasicOrderType.ERC721_TO_ERC20_FULL_RESTRICTED ] = BasicOrderRouteType.ERC721_TO_ERC20; _OrderToRouteType[ BasicOrderType.ERC721_TO_ERC20_PARTIAL_RESTRICTED ] = BasicOrderRouteType.ERC721_TO_ERC20; // ERC 1155 TO ERC 20 _OrderToRouteType[ BasicOrderType.ERC1155_TO_ERC20_FULL_OPEN ] = BasicOrderRouteType.ERC1155_TO_ERC20; _OrderToRouteType[ BasicOrderType.ERC1155_TO_ERC20_PARTIAL_OPEN ] = BasicOrderRouteType.ERC1155_TO_ERC20; _OrderToRouteType[ BasicOrderType.ERC1155_TO_ERC20_FULL_RESTRICTED ] = BasicOrderRouteType.ERC1155_TO_ERC20; _OrderToRouteType[ BasicOrderType.ERC1155_TO_ERC20_PARTIAL_RESTRICTED ] = BasicOrderRouteType.ERC1155_TO_ERC20; // Basic OrderType to OrderType // FULL OPEN _BasicOrderToOrderType[ BasicOrderType.ETH_TO_ERC721_FULL_OPEN ] = OrderType.FULL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ETH_TO_ERC1155_FULL_OPEN ] = OrderType.FULL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ERC20_TO_ERC721_FULL_OPEN ] = OrderType.FULL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ERC20_TO_ERC1155_FULL_OPEN ] = OrderType.FULL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ERC721_TO_ERC20_FULL_OPEN ] = OrderType.FULL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ERC1155_TO_ERC20_FULL_OPEN ] = OrderType.FULL_OPEN; // PARTIAL OPEN _BasicOrderToOrderType[ BasicOrderType.ETH_TO_ERC721_PARTIAL_OPEN ] = OrderType.PARTIAL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ETH_TO_ERC1155_PARTIAL_OPEN ] = OrderType.PARTIAL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ERC20_TO_ERC721_PARTIAL_OPEN ] = OrderType.PARTIAL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ERC20_TO_ERC1155_PARTIAL_OPEN ] = OrderType.PARTIAL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ERC721_TO_ERC20_PARTIAL_OPEN ] = OrderType.PARTIAL_OPEN; _BasicOrderToOrderType[ BasicOrderType.ERC1155_TO_ERC20_PARTIAL_OPEN ] = OrderType.PARTIAL_OPEN; // FULL RESTRICTED _BasicOrderToOrderType[ BasicOrderType.ETH_TO_ERC721_FULL_RESTRICTED ] = OrderType.FULL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ETH_TO_ERC1155_FULL_RESTRICTED ] = OrderType.FULL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ERC20_TO_ERC721_FULL_RESTRICTED ] = OrderType.FULL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ERC20_TO_ERC1155_FULL_RESTRICTED ] = OrderType.FULL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ERC721_TO_ERC20_FULL_RESTRICTED ] = OrderType.FULL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ERC1155_TO_ERC20_FULL_RESTRICTED ] = OrderType.FULL_RESTRICTED; // PARTIAL RESTRICTED _BasicOrderToOrderType[ BasicOrderType.ETH_TO_ERC721_PARTIAL_RESTRICTED ] = OrderType.PARTIAL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ETH_TO_ERC1155_PARTIAL_RESTRICTED ] = OrderType.PARTIAL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ERC20_TO_ERC721_PARTIAL_RESTRICTED ] = OrderType.PARTIAL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ERC20_TO_ERC1155_PARTIAL_RESTRICTED ] = OrderType.PARTIAL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ERC721_TO_ERC20_PARTIAL_RESTRICTED ] = OrderType.PARTIAL_RESTRICTED; _BasicOrderToOrderType[ BasicOrderType.ERC1155_TO_ERC20_PARTIAL_RESTRICTED ] = OrderType.PARTIAL_RESTRICTED; } /** * @dev Internal function to fulfill an order offering an ERC20, ERC721, or * ERC1155 item by supplying Ether (or other native tokens), ERC20 * tokens, an ERC721 item, or an ERC1155 item as consideration. Six * permutations are supported: Native token to ERC721, Native token to * ERC1155, ERC20 to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and * ERC1155 to ERC20 (with native tokens supplied as msg.value). For an * order to be eligible for fulfillment via this method, it must * contain a single offer item (though that item may have a greater * amount if the item is not an ERC721). An arbitrary number of * "additional recipients" may also be supplied which will each receive * native tokens or ERC20 items from the fulfiller as consideration. * Refer to the documentation for a more comprehensive summary of how * to utilize with this method and what orders are compatible with it. * * @param parameters Additional information on the fulfilled order. Note * that the offerer and the fulfiller must first approve * this contract (or their chosen conduit if indicated) * before any tokens can be transferred. Also note that * contract recipients of ERC1155 consideration items must * implement `onERC1155Received` in order to receive those * items. * * @return A boolean indicating whether the order has been fulfilled. */ function _validateAndFulfillBasicOrder( BasicOrderParameters calldata parameters ) internal returns (bool) { // Determine the basic order route type from the basic order type. BasicOrderRouteType route; { BasicOrderType basicType = parameters.basicOrderType; route = _OrderToRouteType[basicType]; } // Determine the order type from the basic order type. OrderType orderType; { BasicOrderType basicType = parameters.basicOrderType; orderType = _BasicOrderToOrderType[basicType]; } // Declare additional recipient item type to derive from the route type. ItemType additionalRecipientsItemType; if ( route == BasicOrderRouteType.ETH_TO_ERC721 || route == BasicOrderRouteType.ETH_TO_ERC1155 ) { additionalRecipientsItemType = ItemType.NATIVE; } else { additionalRecipientsItemType = ItemType.ERC20; } // Revert if msg.value was not supplied as part of a payable route. if (msg.value == 0 && additionalRecipientsItemType == ItemType.NATIVE) { revert InvalidMsgValue(msg.value); } // Revert if msg.value was supplied as part of a non-payable route. if (msg.value != 0 && additionalRecipientsItemType == ItemType.ERC20) { revert InvalidMsgValue(msg.value); } // Determine the token that additional recipients should have set. address additionalRecipientsToken; if ( route == BasicOrderRouteType.ERC721_TO_ERC20 || route == BasicOrderRouteType.ERC1155_TO_ERC20 ) { additionalRecipientsToken = parameters.offerToken; } else { additionalRecipientsToken = parameters.considerationToken; } // Determine the item type for received items. ItemType receivedItemType; if ( route == BasicOrderRouteType.ETH_TO_ERC721 || route == BasicOrderRouteType.ETH_TO_ERC1155 ) { receivedItemType = ItemType.NATIVE; } else if ( route == BasicOrderRouteType.ERC20_TO_ERC721 || route == BasicOrderRouteType.ERC20_TO_ERC1155 ) { receivedItemType = ItemType.ERC20; } else if (route == BasicOrderRouteType.ERC721_TO_ERC20) { receivedItemType = ItemType.ERC721; } else { receivedItemType = ItemType.ERC1155; } // Determine the item type for the offered item. ItemType offeredItemType; if ( route == BasicOrderRouteType.ERC721_TO_ERC20 || route == BasicOrderRouteType.ERC1155_TO_ERC20 ) { offeredItemType = ItemType.ERC20; } else if ( route == BasicOrderRouteType.ETH_TO_ERC721 || route == BasicOrderRouteType.ERC20_TO_ERC721 ) { offeredItemType = ItemType.ERC721; } else { offeredItemType = ItemType.ERC1155; } // Derive & validate order using parameters and update order status. bytes32 orderHash = _prepareBasicFulfillment( parameters, orderType, receivedItemType, additionalRecipientsItemType, additionalRecipientsToken, offeredItemType ); // Determine conduitKey argument used by transfer functions. bytes32 conduitKey; if ( route == BasicOrderRouteType.ERC721_TO_ERC20 || route == BasicOrderRouteType.ERC1155_TO_ERC20 ) { conduitKey = parameters.fulfillerConduitKey; } else { conduitKey = parameters.offererConduitKey; } // Check for dirtied unused parameters. if ( ((route == BasicOrderRouteType.ETH_TO_ERC721 || route == BasicOrderRouteType.ETH_TO_ERC1155) && (uint160(parameters.considerationToken) | parameters.considerationIdentifier) != 0) || ((route == BasicOrderRouteType.ERC20_TO_ERC721 || route == BasicOrderRouteType.ERC20_TO_ERC1155) && parameters.considerationIdentifier != 0) || ((route == BasicOrderRouteType.ERC721_TO_ERC20 || route == BasicOrderRouteType.ERC1155_TO_ERC20) && parameters.offerIdentifier != 0) ) { revert UnusedItemParameters(); } // Declare transfer accumulator that will collect transfers that can be // bundled into a single call to their associated conduit. AccumulatorStruct memory accumulatorStruct; // Transfer tokens based on the route. if (route == BasicOrderRouteType.ETH_TO_ERC721) { // Transfer ERC721 to caller using offerer's conduit if applicable. _transferERC721( parameters.offerToken, parameters.offerer, msg.sender, parameters.offerIdentifier, parameters.offerAmount, conduitKey, accumulatorStruct ); // Transfer native to recipients, return excess to caller & wrap up. _transferEthAndFinalize(parameters.considerationAmount, parameters); } else if (route == BasicOrderRouteType.ETH_TO_ERC1155) { // Transfer ERC1155 to caller using offerer's conduit if applicable. _transferERC1155( parameters.offerToken, parameters.offerer, msg.sender, parameters.offerIdentifier, parameters.offerAmount, conduitKey, accumulatorStruct ); // Transfer native to recipients, return excess to caller & wrap up. _transferEthAndFinalize(parameters.considerationAmount, parameters); } else if (route == BasicOrderRouteType.ERC20_TO_ERC721) { // Transfer ERC721 to caller using offerer's conduit if applicable. _transferERC721( parameters.offerToken, parameters.offerer, msg.sender, parameters.offerIdentifier, parameters.offerAmount, conduitKey, accumulatorStruct ); // Transfer ERC20 tokens to all recipients and wrap up. _transferERC20AndFinalize( msg.sender, parameters.offerer, parameters.considerationToken, parameters.considerationAmount, parameters, false, // Send full amount indicated by all consideration items. accumulatorStruct ); } else if (route == BasicOrderRouteType.ERC20_TO_ERC1155) { // Transfer ERC1155 to caller using offerer's conduit if applicable. _transferERC1155( parameters.offerToken, parameters.offerer, msg.sender, parameters.offerIdentifier, parameters.offerAmount, conduitKey, accumulatorStruct ); // Transfer ERC20 tokens to all recipients and wrap up. _transferERC20AndFinalize( msg.sender, parameters.offerer, parameters.considerationToken, parameters.considerationAmount, parameters, false, // Send full amount indicated by all consideration items. accumulatorStruct ); } else if (route == BasicOrderRouteType.ERC721_TO_ERC20) { // Transfer ERC721 to offerer using caller's conduit if applicable. _transferERC721( parameters.considerationToken, msg.sender, parameters.offerer, parameters.considerationIdentifier, parameters.considerationAmount, conduitKey, accumulatorStruct ); // Transfer ERC20 tokens to all recipients and wrap up. _transferERC20AndFinalize( parameters.offerer, msg.sender, parameters.offerToken, parameters.offerAmount, parameters, true, // Reduce amount sent to fulfiller by additional amounts. accumulatorStruct ); } else { // route == BasicOrderRouteType.ERC1155_TO_ERC20 // Transfer ERC1155 to offerer using caller's conduit if applicable. _transferERC1155( parameters.considerationToken, msg.sender, parameters.offerer, parameters.considerationIdentifier, parameters.considerationAmount, conduitKey, accumulatorStruct ); // Transfer ERC20 tokens to all recipients and wrap up. _transferERC20AndFinalize( parameters.offerer, msg.sender, parameters.offerToken, parameters.offerAmount, parameters, true, // Reduce amount sent to fulfiller by additional amounts. accumulatorStruct ); } // Trigger any remaining accumulated transfers via call to the conduit. _triggerIfArmed(accumulatorStruct); // Determine whether order is restricted and, if so, that it is valid. _assertRestrictedBasicOrderValidity( orderHash, orderType, parameters, offeredItemType, receivedItemType ); return true; } /** * @dev Internal function to calculate the order hash. * * @param hashes The array of offerItems and receivedItems * hashes. * @param parameters The parameters of the basic order. * @param fulfillmentItemTypes The fulfillment's item type. * * @return orderHash The order hash. */ function _hashOrder( BasicFulfillmentHashes memory hashes, BasicOrderParameters calldata parameters, FulfillmentItemTypes memory fulfillmentItemTypes ) internal view returns (bytes32 orderHash) { // Read offerer's current counter from storage and place on the stack. uint256 counter = _getCounter(parameters.offerer); // Hash the contents to get the orderHash orderHash = keccak256( abi.encode( hashes.typeHash, parameters.offerer, parameters.zone, hashes.offerItemsHash, hashes.receivedItemsHash, fulfillmentItemTypes.orderType, parameters.startTime, parameters.endTime, parameters.zoneHash, parameters.salt, parameters.offererConduitKey, counter ) ); } /** * @dev Internal function to prepare fulfillment of a basic order. This * calculates the order hash, emits an OrderFulfilled event, and * asserts basic order validity. * * @param parameters The parameters of the basic order. * @param orderType The order type. * @param receivedItemType The item type of the initial * consideration item on the order. * @param additionalRecipientsItemType The item type of any additional * consideration item on the order. * @param additionalRecipientsToken The ERC20 token contract address (if * applicable) for any additional * consideration item on the order. * @param offeredItemType The item type of the offered item on * the order. * * @return orderHash The calculated order hash. */ function _prepareBasicFulfillment( BasicOrderParameters calldata parameters, OrderType orderType, ItemType receivedItemType, ItemType additionalRecipientsItemType, address additionalRecipientsToken, ItemType offeredItemType ) internal returns (bytes32 orderHash) { // Ensure current timestamp falls between order start time and end time. _verifyTime(parameters.startTime, parameters.endTime, true); // Verify that calldata offsets for all dynamic types were produced by // default encoding. This is only required on the optimized contract, // but is included here to maintain parity. _assertValidBasicOrderParameters(); // Ensure supplied consideration array length is not less than original. _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength( parameters.additionalRecipients.length, parameters.totalOriginalAdditionalRecipients ); // Memory to store hashes. BasicFulfillmentHashes memory hashes; // Store ItemType/Token parameters in a struct in memory to avoid stack // issues. FulfillmentItemTypes memory fulfillmentItemTypes = FulfillmentItemTypes( orderType, receivedItemType, additionalRecipientsItemType, additionalRecipientsToken, offeredItemType ); // Array of Received Items for use with OrderFulfilled event. ReceivedItem[] memory consideration = new ReceivedItem[]( parameters.additionalRecipients.length + 1 ); { // Load consideration item typehash from runtime and place on stack. hashes.typeHash = _CONSIDERATION_ITEM_TYPEHASH; // Create Consideration item. ConsiderationItem memory primaryConsiderationItem = ( ConsiderationItem( fulfillmentItemTypes.receivedItemType, parameters.considerationToken, parameters.considerationIdentifier, parameters.considerationAmount, parameters.considerationAmount, parameters.offerer ) ); // Array of all consideration item hashes. hashes.considerationHashes = new bytes32[]( parameters.totalOriginalAdditionalRecipients + 1 ); // Hash contents. hashes.considerationHashes[0] = keccak256( abi.encode( hashes.typeHash, primaryConsiderationItem.itemType, primaryConsiderationItem.token, primaryConsiderationItem.identifierOrCriteria, primaryConsiderationItem.startAmount, primaryConsiderationItem.endAmount, primaryConsiderationItem.recipient ) ); // Declare memory for additionalReceivedItem and // additionalRecipientItem. ReceivedItem memory additionalReceivedItem; ConsiderationItem memory additionalRecipientItem; // Create Received item. ReceivedItem memory primaryReceivedItem = ReceivedItem( fulfillmentItemTypes.receivedItemType, primaryConsiderationItem.token, primaryConsiderationItem.identifierOrCriteria, primaryConsiderationItem.endAmount, primaryConsiderationItem.recipient ); // Add the Received item to the // OrderFulfilled ReceivedItem[]. consideration[0] = primaryReceivedItem; /** Loop through all additionalRecipients, to generate * ReceivedItems for OrderFulfilled Event and * ConsiderationItems for hashing. */ for ( uint256 recipientCount = 0; recipientCount < parameters.totalOriginalAdditionalRecipients; ++recipientCount ) { // Get the next additionalRecipient. AdditionalRecipient memory additionalRecipient = ( parameters.additionalRecipients[recipientCount] ); // Create a Received item for each additional recipients. additionalReceivedItem = ReceivedItem( fulfillmentItemTypes.additionalRecipientsItemType, fulfillmentItemTypes.additionalRecipientsToken, 0, additionalRecipient.amount, additionalRecipient.recipient ); // Add additional Received items to the // OrderFulfilled ReceivedItem[]. consideration[recipientCount + 1] = additionalReceivedItem; // Create a new consideration item for each additional // recipient. additionalRecipientItem = ConsiderationItem( fulfillmentItemTypes.additionalRecipientsItemType, fulfillmentItemTypes.additionalRecipientsToken, 0, additionalRecipient.amount, additionalRecipient.amount, additionalRecipient.recipient ); // Calculate the EIP712 ConsiderationItem hash for // each additional recipients. hashes.considerationHashes[recipientCount + 1] = keccak256( abi.encode( hashes.typeHash, additionalRecipientItem.itemType, additionalRecipientItem.token, additionalRecipientItem.identifierOrCriteria, additionalRecipientItem.startAmount, additionalRecipientItem.endAmount, additionalRecipientItem.recipient ) ); } /** * The considerationHashes array now contains * all consideration Item hashes. * * The consideration array now contains all received * items excluding tips for OrderFulfilled Event. */ // Get hash of all consideration items. hashes.receivedItemsHash = keccak256( abi.encodePacked(hashes.considerationHashes) ); // Get remainder of additionalRecipients for tips. for ( uint256 additionalTips = parameters .totalOriginalAdditionalRecipients; additionalTips < parameters.additionalRecipients.length; ++additionalTips ) { // Get the next additionalRecipient. AdditionalRecipient memory additionalRecipient = ( parameters.additionalRecipients[additionalTips] ); // Create the ReceivedItem. additionalReceivedItem = ReceivedItem( fulfillmentItemTypes.additionalRecipientsItemType, fulfillmentItemTypes.additionalRecipientsToken, 0, additionalRecipient.amount, additionalRecipient.recipient ); // Add additional received items to the // OrderFulfilled ReceivedItem[]. consideration[additionalTips + 1] = additionalReceivedItem; } } // Now let's handle the offer side. // Write the offer to the Event SpentItem array. SpentItem[] memory offer = new SpentItem[](1); { // Place offer item typehash on the stack. hashes.typeHash = _OFFER_ITEM_TYPEHASH; // Create Spent item. SpentItem memory offerItem = SpentItem( fulfillmentItemTypes.offeredItemType, parameters.offerToken, parameters.offerIdentifier, parameters.offerAmount ); // Add the offer item to the SpentItem array. offer[0] = offerItem; // Get the hash of the Spent item, treated as an Offer item. bytes32[1] memory offerItemHashes = [ keccak256( abi.encode( hashes.typeHash, offerItem.itemType, offerItem.token, offerItem.identifier, offerItem.amount, // Assembly uses OfferItem instead of SpentItem. offerItem.amount ) ) ]; // Get hash of all Spent items. hashes.offerItemsHash = keccak256( abi.encodePacked(offerItemHashes) ); } { // Create the OrderComponent in order to derive // the orderHash. // Load order typehash from runtime code and place on stack. hashes.typeHash = _ORDER_TYPEHASH; // Derive the order hash. hashes.orderHash = _hashOrder( hashes, parameters, fulfillmentItemTypes ); // Emit an event signifying that the order has been fulfilled. emit OrderFulfilled( hashes.orderHash, parameters.offerer, parameters.zone, msg.sender, offer, consideration ); } // Determine whether order is restricted and, if so, that it is valid. _assertRestrictedBasicOrderAuthorization( hashes.orderHash, orderType, parameters, offeredItemType, receivedItemType ); // Verify and update the status of the derived order. _validateBasicOrderAndUpdateStatus( hashes.orderHash, parameters.offerer, parameters.signature ); // Return the derived order hash. return hashes.orderHash; } /** * @dev Internal function to transfer Ether (or other native tokens) to a * given recipient as part of basic order fulfillment. Note that * proxies are not utilized for native tokens as the transferred amount * must be provided as msg.value. * * @param amount The amount to transfer. * @param parameters The parameters of the basic order in question. */ function _transferEthAndFinalize( uint256 amount, BasicOrderParameters calldata parameters ) internal { // Put native token value supplied by the caller on the stack. uint256 nativeTokensRemaining = msg.value; // Iterate over each additional recipient. for (uint256 i = 0; i < parameters.additionalRecipients.length; ++i) { // Retrieve the additional recipient. AdditionalRecipient calldata additionalRecipient = ( parameters.additionalRecipients[i] ); // Read native token amount to transfer to recipient & put on stack. uint256 additionalRecipientAmount = additionalRecipient.amount; // Ensure that sufficient native tokens are available. if (additionalRecipientAmount > nativeTokensRemaining) { revert InsufficientNativeTokensSupplied(); } // Transfer native token to the additional recipient. _transferNativeTokens( additionalRecipient.recipient, additionalRecipientAmount ); // Reduce native token value available. nativeTokensRemaining -= additionalRecipientAmount; } // Ensure that sufficient native token is still available. if (amount > nativeTokensRemaining) { revert InsufficientNativeTokensSupplied(); } // Transfer native token to the offerer. _transferNativeTokens(parameters.offerer, amount); // If any native token remains after transfers, return it to the caller. if (nativeTokensRemaining > amount) { // Transfer remaining native token to the caller. _transferNativeTokens( payable(msg.sender), nativeTokensRemaining - amount ); } } /** * @dev Internal function to transfer ERC20 tokens to a given recipient as * part of basic order fulfillment. Note that proxies are not utilized * for ERC20 tokens. * * @param from The originator of the ERC20 token transfer. * @param to The recipient of the ERC20 token transfer. * @param erc20Token The ERC20 token to transfer. * @param amount The amount of ERC20 tokens to transfer. * @param parameters The parameters of the order. * @param fromOfferer Whether to decrement amount from the * offered amount. * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. */ function _transferERC20AndFinalize( address from, address to, address erc20Token, uint256 amount, BasicOrderParameters calldata parameters, bool fromOfferer, AccumulatorStruct memory accumulatorStruct ) internal { // Determine the appropriate conduit to utilize. bytes32 conduitKey; if (fromOfferer) { conduitKey = parameters.offererConduitKey; } else { conduitKey = parameters.fulfillerConduitKey; } // Iterate over each additional recipient. for (uint256 i = 0; i < parameters.additionalRecipients.length; ++i) { // Retrieve the additional recipient. AdditionalRecipient calldata additionalRecipient = ( parameters.additionalRecipients[i] ); // Decrement the amount to transfer to fulfiller if indicated. if (fromOfferer) { amount -= additionalRecipient.amount; } // Transfer ERC20 tokens to additional recipient given approval. _transferERC20( erc20Token, from, additionalRecipient.recipient, additionalRecipient.amount, conduitKey, accumulatorStruct ); } // Transfer ERC20 token amount (from account must have proper approval). _transferERC20( erc20Token, from, to, amount, conduitKey, accumulatorStruct ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title TokenTransferrerErrors */ interface TokenTransferrerErrors { /** * @dev Revert with an error when an ERC721 transfer with amount other than * one is attempted. * * @param amount The amount of the ERC721 tokens to transfer. */ error InvalidERC721TransferAmount(uint256 amount); /** * @dev Revert with an error when attempting to fulfill an order where an * item has an amount of zero. */ error MissingItemAmount(); /** * @dev Revert with an error when attempting to fulfill an order where an * item has unused parameters. This includes both the token and the * identifier parameters for native transfers as well as the identifier * parameter for ERC20 transfers. Note that the conduit does not * perform this check, leaving it up to the calling channel to enforce * when desired. */ error UnusedItemParameters(); /** * @dev Revert with an error when an ERC20, ERC721, or ERC1155 token * transfer reverts. * * @param token The token for which the transfer was attempted. * @param from The source of the attempted transfer. * @param to The recipient of the attempted transfer. * @param identifier The identifier for the attempted transfer. * @param amount The amount for the attempted transfer. */ error TokenTransferGenericFailure( address token, address from, address to, uint256 identifier, uint256 amount ); /** * @dev Revert with an error when a batch ERC1155 token transfer reverts. * * @param token The token for which the transfer was attempted. * @param from The source of the attempted transfer. * @param to The recipient of the attempted transfer. * @param identifiers The identifiers for the attempted transfer. * @param amounts The amounts for the attempted transfer. */ error ERC1155BatchTransferGenericFailure( address token, address from, address to, uint256[] identifiers, uint256[] amounts ); /** * @dev Revert with an error when an ERC20 token transfer returns a falsey * value. * * @param token The token for which the ERC20 transfer was attempted. * @param from The source of the attempted ERC20 transfer. * @param to The recipient of the attempted ERC20 transfer. * @param amount The amount for the attempted ERC20 transfer. */ error BadReturnValueFromERC20OnTransfer( address token, address from, address to, uint256 amount ); /** * @dev Revert with an error when an account being called as an assumed * contract does not have code and returns no data. * * @param account The account that should contain code. */ error NoContract(address account); /** * @dev Revert with an error when attempting to execute an 1155 batch * transfer using calldata not produced by default ABI encoding or with * different lengths for ids and amounts arrays. */ error Invalid1155BatchTransferEncoding(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ItemType, OrderType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { AdvancedOrder, ConsiderationItem, CriteriaResolver, OfferItem, OrderParameters, ReceivedItem, SpentItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { OrderToExecute } from "./ReferenceConsiderationStructs.sol"; import { CriteriaResolutionErrors } from "seaport-types/src/interfaces/CriteriaResolutionErrors.sol"; /** * @title CriteriaResolution * @author 0age * @notice CriteriaResolution contains a collection of pure functions related to * resolving criteria-based items. */ contract ReferenceCriteriaResolution is CriteriaResolutionErrors { /** * @dev Internal pure function to apply criteria resolvers containing * specific token identifiers and associated proofs to order items. * * @param ordersToExecute The orders to apply criteria resolvers to. * @param criteriaResolvers An array where each element contains a * reference to a specific order as well as that * order's offer or consideration, a token * identifier, and a proof that the supplied token * identifier is contained in the order's merkle * root. Note that a root of zero indicates that * any transferable token identifier is valid and * that no proof needs to be supplied. */ function _applyCriteriaResolvers( AdvancedOrder[] memory advancedOrders, OrderToExecute[] memory ordersToExecute, CriteriaResolver[] memory criteriaResolvers ) internal pure { // Retrieve length of criteria resolvers array and place on stack. uint256 arraySize = criteriaResolvers.length; // Iterate over each criteria resolver. for (uint256 i = 0; i < arraySize; ++i) { // Retrieve the criteria resolver. CriteriaResolver memory criteriaResolver = (criteriaResolvers[i]); // Read the order index from memory and place it on the stack. uint256 orderIndex = criteriaResolver.orderIndex; // Ensure that the order index is in range. if (orderIndex >= ordersToExecute.length) { revert OrderCriteriaResolverOutOfRange(criteriaResolver.side); } // Skip criteria resolution for order if not fulfilled. if (ordersToExecute[orderIndex].numerator == 0) { continue; } // Read component index from memory and place it on the stack. uint256 componentIndex = criteriaResolver.index; // Declare values for item's type and criteria. ItemType itemType; uint256 identifierOrCriteria; // If the criteria resolver refers to an offer item... if (criteriaResolver.side == Side.OFFER) { SpentItem[] memory spentItems = ordersToExecute[orderIndex] .spentItems; // Ensure that the component index is in range. if (componentIndex >= spentItems.length) { revert OfferCriteriaResolverOutOfRange(); } // Retrieve relevant item using component index. SpentItem memory offer = (spentItems[componentIndex]); // Read item type and criteria from memory & place on stack. itemType = offer.itemType; identifierOrCriteria = offer.identifier; // Optimistically update item type to remove criteria usage. if (itemType == ItemType.ERC721_WITH_CRITERIA) { offer.itemType = ItemType.ERC721; } else { offer.itemType = ItemType.ERC1155; } // Optimistically update identifier w/ supplied identifier. offer.identifier = criteriaResolver.identifier; } else { // Otherwise, the resolver refers to a consideration item. // Retrieve relevant item using order index. ReceivedItem[] memory receivedItems = ordersToExecute[ orderIndex ].receivedItems; // Ensure that the component index is in range. if (componentIndex >= receivedItems.length) { revert ConsiderationCriteriaResolverOutOfRange(); } // Retrieve relevant item using component index. ReceivedItem memory consideration = ( receivedItems[componentIndex] ); // Read item type and criteria from memory & place on stack. itemType = consideration.itemType; identifierOrCriteria = consideration.identifier; // Optimistically update item type to remove criteria usage. if (itemType == ItemType.ERC721_WITH_CRITERIA) { consideration.itemType = ItemType.ERC721; } else { consideration.itemType = ItemType.ERC1155; } // Optimistically update identifier w/ supplied identifier. consideration.identifier = (criteriaResolver.identifier); } // Ensure the specified item type indicates criteria usage. if (!_isItemWithCriteria(itemType)) { revert CriteriaNotEnabledForItem(); } // If criteria is not 0 (i.e. a collection-wide criteria item)... if (identifierOrCriteria != uint256(0)) { // Verify identifier inclusion in criteria root using proof. _verifyProof( criteriaResolver.identifier, identifierOrCriteria, criteriaResolver.criteriaProof ); } else if (criteriaResolver.criteriaProof.length != 0) { // Revert if a proof is supplied for a collection-wide item. revert InvalidProof(); } } // Retrieve length of orders array and place on stack. arraySize = ordersToExecute.length; // Iterate over each order to execute. for (uint256 i = 0; i < arraySize; ++i) { // Retrieve the order to execute. OrderToExecute memory orderToExecute = ordersToExecute[i]; // Read offer length from memory and place on stack. uint256 totalItems = orderToExecute.spentItems.length; // Skip criteria resolution for order if not fulfilled. if (orderToExecute.numerator == 0) { continue; } // Iterate over each offer item on the order. for (uint256 j = 0; j < totalItems; ++j) { // Ensure item type no longer indicates criteria usage. if ( _isItemWithCriteria(orderToExecute.spentItems[j].itemType) ) { if ( advancedOrders[i].parameters.orderType != OrderType.CONTRACT || orderToExecute.spentItems[j].identifier != 0 ) { revert UnresolvedOfferCriteria(i, j); } } } // Read consideration length from memory and place on stack. totalItems = (orderToExecute.receivedItems.length); // Iterate over each consideration item on the order. for (uint256 j = 0; j < totalItems; ++j) { // Ensure item type no longer indicates criteria usage. if ( _isItemWithCriteria( orderToExecute.receivedItems[j].itemType ) ) { if ( advancedOrders[i].parameters.orderType != OrderType.CONTRACT || orderToExecute.receivedItems[j].identifier != 0 ) { revert UnresolvedConsiderationCriteria(i, j); } } } } } /** * @dev Internal pure function to apply criteria resolvers containing * specific token identifiers and associated proofs to order items. * * @param advancedOrder The order to apply criteria resolvers to. * @param criteriaResolvers An array where each element contains a * reference to a specific order as well as that * order's offer or consideration, a token * identifier, and a proof that the supplied token * identifier is contained in the order's merkle * root. Note that a root of zero indicates that * any transferable token identifier is valid and * that no proof needs to be supplied. */ function _applyCriteriaResolversAdvanced( AdvancedOrder memory advancedOrder, CriteriaResolver[] memory criteriaResolvers ) internal pure { // Retrieve length of criteria resolvers array and place on stack. uint256 arraySize = criteriaResolvers.length; // Retrieve the parameters for the order. OrderParameters memory orderParameters = (advancedOrder.parameters); // Iterate over each criteria resolver. for (uint256 i = 0; i < arraySize; ++i) { // Retrieve the criteria resolver. CriteriaResolver memory criteriaResolver = (criteriaResolvers[i]); // Read the order index from memory and place it on the stack. uint256 orderIndex = criteriaResolver.orderIndex; if (orderIndex != 0) { revert OrderCriteriaResolverOutOfRange(criteriaResolver.side); } // Read component index from memory and place it on the stack. uint256 componentIndex = criteriaResolver.index; // Declare values for item's type and criteria. ItemType itemType; uint256 identifierOrCriteria; // If the criteria resolver refers to an offer item... if (criteriaResolver.side == Side.OFFER) { // Ensure that the component index is in range. if (componentIndex >= orderParameters.offer.length) { revert OfferCriteriaResolverOutOfRange(); } // Retrieve relevant item using order and component index. OfferItem memory offer = ( orderParameters.offer[componentIndex] ); // Read item type and criteria from memory & place on stack. itemType = offer.itemType; identifierOrCriteria = offer.identifierOrCriteria; // Optimistically update item type to remove criteria usage. if (itemType == ItemType.ERC721_WITH_CRITERIA) { offer.itemType = ItemType.ERC721; } else { offer.itemType = ItemType.ERC1155; } // Optimistically update identifier w/ supplied identifier. offer.identifierOrCriteria = criteriaResolver.identifier; } else { // Otherwise, the resolver refers to a consideration item. // Ensure that the component index is in range. if (componentIndex >= orderParameters.consideration.length) { revert ConsiderationCriteriaResolverOutOfRange(); } // Retrieve relevant item using order and component index. ConsiderationItem memory consideration = ( orderParameters.consideration[componentIndex] ); // Read item type and criteria from memory & place on stack. itemType = consideration.itemType; identifierOrCriteria = consideration.identifierOrCriteria; // Optimistically update item type to remove criteria usage. if (itemType == ItemType.ERC721_WITH_CRITERIA) { consideration.itemType = ItemType.ERC721; } else { consideration.itemType = ItemType.ERC1155; } // Optimistically update identifier w/ supplied identifier. consideration.identifierOrCriteria = ( criteriaResolver.identifier ); } // Ensure the specified item type indicates criteria usage. if (!_isItemWithCriteria(itemType)) { revert CriteriaNotEnabledForItem(); } // If criteria is not 0 (i.e. a collection-wide offer)... if (identifierOrCriteria != uint256(0)) { // Verify identifier inclusion in criteria root using proof. _verifyProof( criteriaResolver.identifier, identifierOrCriteria, criteriaResolver.criteriaProof ); } else if (criteriaResolver.criteriaProof.length != 0) { // Revert if a proof is supplied for a collection-wide item. revert InvalidProof(); } } // Validate Criteria on order has been resolved // Read consideration length from memory and place on stack. uint256 totalItems = (advancedOrder.parameters.consideration.length); // Iterate over each consideration item on the order. for (uint256 i = 0; i < totalItems; ++i) { // Ensure item type no longer indicates criteria usage. if ( _isItemWithCriteria( advancedOrder.parameters.consideration[i].itemType ) ) { if ( advancedOrder.parameters.orderType != OrderType.CONTRACT || advancedOrder .parameters .consideration[i] .identifierOrCriteria != 0 ) { revert UnresolvedConsiderationCriteria(0, i); } } } // Read offer length from memory and place on stack. totalItems = advancedOrder.parameters.offer.length; // Iterate over each offer item on the order. for (uint256 i = 0; i < totalItems; ++i) { // Ensure item type no longer indicates criteria usage. if ( _isItemWithCriteria(advancedOrder.parameters.offer[i].itemType) ) { if ( advancedOrder.parameters.orderType != OrderType.CONTRACT || advancedOrder.parameters.offer[i].identifierOrCriteria != 0 ) { revert UnresolvedOfferCriteria(0, i); } } } } /** * @dev Internal pure function to check whether a given item type represents * a criteria-based ERC721 or ERC1155 item (e.g. an item that can be * resolved to one of a number of different identifiers at the time of * order fulfillment). * * @param itemType The item type in question. * * @return withCriteria A boolean indicating that the item type in question * represents a criteria-based item. */ function _isItemWithCriteria( ItemType itemType ) internal pure returns (bool withCriteria) { // ERC721WithCriteria is item type 4. ERC1155WithCriteria is item type // 5. withCriteria = uint256(itemType) > 3; } /** * @dev Internal pure function to ensure that a given element is contained * in a merkle root via a supplied proof. * * @param leaf The element for which to prove inclusion. * @param root The merkle root that inclusion will be proved against. * @param proof The merkle proof. */ function _verifyProof( uint256 leaf, uint256 root, bytes32[] memory proof ) internal pure { // Hash the supplied leaf to use as the initial proof element. bytes32 computedHash = keccak256(abi.encodePacked(leaf)); // Iterate over each proof element. for (uint256 i = 0; i < proof.length; ++i) { // Retrieve the proof element. bytes32 proofElement = proof[i]; // Sort and hash proof elements and update the computed hash. if (computedHash <= proofElement) { // Hash(current computed hash + current element of proof) computedHash = keccak256( abi.encodePacked(computedHash, proofElement) ); } else { // Hash(current element of proof + current computed hash) computedHash = keccak256( abi.encodePacked(proofElement, computedHash) ); } } // Ensure that the final derived hash matches the expected root. if (computedHash != bytes32(root)) { revert InvalidProof(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; enum ConduitItemType { NATIVE, // unused ERC20, ERC721, ERC1155 }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title AmountDerivationErrors * @author 0age * @notice AmountDerivationErrors contains errors related to amount derivation. */ interface AmountDerivationErrors { /** * @dev Revert with an error when attempting to apply a fraction as part of * a partial fill that does not divide the target amount cleanly. */ error InexactFraction(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { Side } from "../lib/ConsiderationEnums.sol"; /** * @title CriteriaResolutionErrors * @author 0age * @notice CriteriaResolutionErrors contains all errors related to criteria * resolution. */ interface CriteriaResolutionErrors { /** * @dev Revert with an error when providing a criteria resolver that refers * to an order that has not been supplied. * * @param side The side of the order that was not supplied. */ error OrderCriteriaResolverOutOfRange(Side side); /** * @dev Revert with an error if an offer item still has unresolved criteria * after applying all criteria resolvers. * * @param orderIndex The index of the order that contains the offer item. * @param offerIndex The index of the offer item that still has unresolved * criteria. */ error UnresolvedOfferCriteria(uint256 orderIndex, uint256 offerIndex); /** * @dev Revert with an error if a consideration item still has unresolved * criteria after applying all criteria resolvers. * * @param orderIndex The index of the order that contains the * consideration item. * @param considerationIndex The index of the consideration item that still * has unresolved criteria. */ error UnresolvedConsiderationCriteria( uint256 orderIndex, uint256 considerationIndex ); /** * @dev Revert with an error when providing a criteria resolver that refers * to an order with an offer item that has not been supplied. */ error OfferCriteriaResolverOutOfRange(); /** * @dev Revert with an error when providing a criteria resolver that refers * to an order with a consideration item that has not been supplied. */ error ConsiderationCriteriaResolverOutOfRange(); /** * @dev Revert with an error when providing a criteria resolver that refers * to an order with an item that does not expect a criteria to be * resolved. */ error CriteriaNotEnabledForItem(); /** * @dev Revert with an error when providing a criteria resolver that * contains an invalid proof with respect to the given item and * chosen identifier. */ error InvalidProof(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { OrderType, ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { AdvancedOrder, ConsiderationItem, OfferItem, Order, OrderComponents, OrderParameters, OrderStatus, ReceivedItem, SpentItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { ReferenceExecutor } from "./ReferenceExecutor.sol"; import { ReferenceZoneInteraction } from "./ReferenceZoneInteraction.sol"; import { ContractOffererInterface } from "seaport-types/src/interfaces/ContractOffererInterface.sol"; import { ReferenceGenerateOrderReturndataDecoder } from "./ReferenceGenerateOrderReturndataDecoder.sol"; import { OrderToExecute, OrderValidation } from "./ReferenceConsiderationStructs.sol"; /** * @title OrderValidator * @author 0age * @notice OrderValidator contains functionality related to validating orders * and updating their status. */ contract ReferenceOrderValidator is ReferenceExecutor, ReferenceZoneInteraction { // Track status of each order (validated, cancelled, and fraction filled). mapping(bytes32 => OrderStatus) private _orderStatus; // Track nonces for contract offerers. mapping(address => uint256) internal _contractNonces; /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceExecutor(conduitController) {} /** * @dev Internal function to verify and update the status of a basic order. * * @param orderHash The hash of the order. * @param offerer The offerer of the order. * @param signature A signature from the offerer indicating that the order * has been approved. */ function _validateBasicOrderAndUpdateStatus( bytes32 orderHash, address offerer, bytes memory signature ) internal { // Retrieve the order status for the given order hash. OrderStatus storage orderStatus = _orderStatus[orderHash]; // Ensure order is fillable and is not cancelled. _verifyOrderStatus( orderHash, orderStatus, true, // Only allow unused orders when fulfilling basic orders. true // Signifies to revert if the order is invalid. ); // If the order is not already validated, verify the supplied signature. if (!orderStatus.isValidated) { _verifySignature(offerer, orderHash, signature); } // Update order status as fully filled, packing struct values. orderStatus.isValidated = true; orderStatus.isCancelled = false; orderStatus.numerator = 1; orderStatus.denominator = 1; } /** * @dev Internal function to validate an order and determine what portion to * fill. The desired fill amount is supplied as a fraction, as is the * returned amount to fill. * * @param advancedOrder The order to fulfill as well as the fraction to * fill. Note that all offer and consideration * amounts must divide with no remainder in order for * a partial fill to be valid. * @param revertOnInvalid A boolean indicating whether to revert if the * order is invalid due to the time or order status. * * @return orderValidation The order validation details, including the fill * amount. */ function _validateOrder( AdvancedOrder memory advancedOrder, bool revertOnInvalid ) internal view returns (OrderValidation memory orderValidation) { // Retrieve the parameters for the order. OrderParameters memory orderParameters = advancedOrder.parameters; // Ensure current timestamp falls between order start time and end time. if ( !_verifyTime( orderParameters.startTime, orderParameters.endTime, revertOnInvalid ) ) { // Assuming an invalid time and no revert, return zeroed out values. return OrderValidation( bytes32(0), 0, 0, _convertAdvancedToOrder(orderParameters, 0) ); } // Read numerator and denominator from memory and place on the stack. uint256 numerator = uint256(advancedOrder.numerator); uint256 denominator = uint256(advancedOrder.denominator); // If the order is a contract order, return the generated order. if (orderParameters.orderType == OrderType.CONTRACT) { // Ensure that numerator and denominator are both equal to 1. if (numerator != 1 || denominator != 1) { revert BadFraction(); } return OrderValidation( bytes32(uint256(1)), 1, 1, _convertAdvancedToOrder(orderParameters, 1) ); } // Ensure that the supplied numerator and denominator are valid. The // numerator should not exceed denominator and should not be zero. if (numerator > denominator || numerator == 0) { revert BadFraction(); } // If attempting partial fill (n < d) check order type & ensure support. if ( numerator < denominator && _doesNotSupportPartialFills(orderParameters.orderType) ) { // Revert if partial fill was attempted on an unsupported order. revert PartialFillsNotEnabledForOrder(); } // Retrieve current counter and use it w/ parameters to get order hash. orderValidation.orderHash = ( _assertConsiderationLengthAndGetOrderHash(orderParameters) ); // Retrieve the order status using the derived order hash. OrderStatus storage orderStatus = ( _orderStatus[orderValidation.orderHash] ); // Ensure order is fillable and is not cancelled. if ( // Allow partially used orders to be filled. !_verifyOrderStatus( orderValidation.orderHash, orderStatus, false, revertOnInvalid ) ) { // Assuming an invalid order status and no revert, return zero fill. return OrderValidation( orderValidation.orderHash, 0, 0, _convertAdvancedToOrder(orderParameters, 0) ); } // If the order is not already validated, verify the supplied signature. if (!orderStatus.isValidated) { _verifySignature( orderParameters.offerer, orderValidation.orderHash, advancedOrder.signature ); } // Read filled amount as numerator and denominator and put on the stack. uint256 filledNumerator = uint256(orderStatus.numerator); uint256 filledDenominator = uint256(orderStatus.denominator); // If order currently has a non-zero denominator it is partially filled. if (filledDenominator != 0) { // If denominator of 1 supplied, fill all remaining amount on order. if (denominator == 1) { // Scale numerator & denominator to match current denominator. numerator = filledDenominator; denominator = filledDenominator; } // Otherwise, if supplied denominator differs from current one... else if (filledDenominator != denominator) { // scale current numerator by the supplied denominator, then... filledNumerator *= denominator; // the supplied numerator & denominator by current denominator. numerator *= filledDenominator; denominator *= filledDenominator; } // Once adjusted, if current+supplied numerator exceeds denominator: if (filledNumerator + numerator > denominator) { // Reduce current numerator so it + supplied = denominator. numerator = denominator - filledNumerator; } // Increment the filled numerator by the new numerator. filledNumerator += numerator; // Ensure fractional amounts are below max uint120. if ( filledNumerator > type(uint120).max || denominator > type(uint120).max ) { // Derive greatest common divisor using euclidean algorithm. uint256 scaleDown = _greatestCommonDivisor( numerator, _greatestCommonDivisor(filledNumerator, denominator) ); // Scale all fractional values down by gcd. numerator = numerator / scaleDown; filledNumerator = filledNumerator / scaleDown; denominator = denominator / scaleDown; // Perform the overflow check a second time. uint256 maxOverhead = type(uint256).max - type(uint120).max; ((filledNumerator + maxOverhead) & (denominator + maxOverhead)); } } // Return order hash, new numerator and denominator. return OrderValidation( orderValidation.orderHash, uint120(numerator), uint120(denominator), _convertAdvancedToOrder(orderParameters, uint120(numerator)) ); } /** * @dev Internal function to update an order's status. * * @param orderHash The hash of the order. * @param numerator The numerator of the fraction to fill. * @param denominator The denominator of the fraction to fill. * @param revertOnInvalid Whether to revert on invalid input. * * @return valid A boolean indicating whether the order is valid. */ function _updateStatus( bytes32 orderHash, uint256 numerator, uint256 denominator, bool revertOnInvalid ) internal returns (bool valid) { if (numerator == 0) { return false; } // Retrieve the order status using the provided order hash. OrderStatus storage orderStatus = _orderStatus[orderHash]; // Read filled amount as numerator and denominator and put on the stack. uint256 filledNumerator = uint256(orderStatus.numerator); uint256 filledDenominator = uint256(orderStatus.denominator); // If order currently has a non-zero denominator it is partially filled. if (filledDenominator != 0) { // if supplied denominator differs from current one... if (filledDenominator != denominator) { // scale current numerator by the supplied denominator, then... filledNumerator *= denominator; // the supplied numerator & denominator by current denominator. numerator *= filledDenominator; denominator *= filledDenominator; } // Once adjusted, if current+supplied numerator exceeds // denominator... if (filledNumerator + numerator > denominator) { // Revert or return false, which indicates that the order is // invalid. if (revertOnInvalid) { revert OrderAlreadyFilled(orderHash); } else { return false; } } // Increment the filled numerator by the new numerator. filledNumerator += numerator; // Ensure fractional amounts are below max uint120. if ( filledNumerator > type(uint120).max || denominator > type(uint120).max ) { // Derive greatest common divisor using euclidean algorithm. uint256 scaleDown = _greatestCommonDivisor( filledNumerator, denominator ); // Scale new filled fractional values down by gcd. filledNumerator = filledNumerator / scaleDown; denominator = denominator / scaleDown; // Perform the overflow check a second time. uint256 maxOverhead = type(uint256).max - type(uint120).max; ((filledNumerator + maxOverhead) & (denominator + maxOverhead)); } // Update order status and fill amount, packing struct values. orderStatus.isValidated = true; orderStatus.isCancelled = false; orderStatus.numerator = uint120(filledNumerator); orderStatus.denominator = uint120(denominator); } else { // If the order currently has a zero denominator, it is not // partially filled. Update the order status and fill amount, // packing struct values. orderStatus.isValidated = true; orderStatus.isCancelled = false; orderStatus.numerator = uint120(numerator); orderStatus.denominator = uint120(denominator); } return true; } function _callGenerateOrder( OrderParameters memory orderParameters, bytes memory context, SpentItem[] memory originalOfferItems, SpentItem[] memory originalConsiderationItems ) internal returns (bool success, bytes memory returnData) { return orderParameters.offerer.call( abi.encodeWithSelector( ContractOffererInterface.generateOrder.selector, msg.sender, originalOfferItems, originalConsiderationItems, context ) ); } /** * @dev Internal function to generate a contract order. When a * collection-wide criteria-based item (criteria = 0) is provided as an * input to a contract order, the contract offerer has full latitude to * choose any identifier it wants mid-flight, which differs from the * usual behavior. For regular criteria-based orders with * identifierOrCriteria = 0, the fulfiller can pick which identifier to * receive by providing a CriteriaResolver. For contract offers with * identifierOrCriteria = 0, Seaport does not expect a corresponding * CriteriaResolver, and will revert if one is provided. * * @param orderToExecute The order to execute. * @param orderParameters The parameters for the order. * @param context The context for generating the order. * @param revertOnInvalid Whether to revert on invalid input. * * @return orderHash The order hash. */ function _getGeneratedOrder( OrderToExecute memory orderToExecute, OrderParameters memory orderParameters, bytes memory context, bool revertOnInvalid ) internal returns (bytes32 orderHash) { // Ensure that consideration array length is equal to the total original // consideration items value. if ( orderParameters.consideration.length != orderParameters.totalOriginalConsiderationItems ) { revert ConsiderationLengthNotEqualToTotalOriginal(); } // Convert offer and consideration to spent and received items. SpentItem[] memory originalOfferItems = orderToExecute.spentItems; SpentItem[] memory originalConsiderationItems = _convertToSpent( orderToExecute.receivedItems ); // Create arrays for returned offer and consideration items. SpentItem[] memory offer; ReceivedItem[] memory consideration; { // Do a low-level call to get success status and any return data. (bool success, bytes memory returnData) = _callGenerateOrder( orderParameters, context, originalOfferItems, originalConsiderationItems ); { // Increment contract nonce and use it to derive order hash. // Note: nonce will be incremented even for skipped orders, and // even if generateOrder's return data doesn't meet constraints. uint256 contractNonce = ( _contractNonces[orderParameters.offerer]++ ); // Derive order hash from contract nonce and offerer address. orderHash = bytes32( contractNonce ^ (uint256(uint160(orderParameters.offerer)) << 96) ); } // If call succeeds, try to decode offer and consideration items. if (success) { // Try to decode offer and consideration items from returndata. try (new ReferenceGenerateOrderReturndataDecoder()).decode( returnData ) returns ( SpentItem[] memory _offer, ReceivedItem[] memory _consideration ) { offer = _offer; consideration = _consideration; } catch { // If decoding fails, revert. revert InvalidContractOrder(orderHash); } } else { // If the call fails, revert or return empty. (orderHash, orderToExecute) = _revertOrReturnEmpty( revertOnInvalid, orderHash ); return orderHash; } } { // Designate lengths. uint256 originalOfferLength = orderParameters.offer.length; uint256 newOfferLength = offer.length; // Explicitly specified offer items cannot be removed. if (originalOfferLength > newOfferLength) { revert InvalidContractOrder(orderHash); } // Loop through each new offer and ensure the new amounts are at // least as much as the respective original amounts. for (uint256 i = 0; i < originalOfferLength; ++i) { // Designate original and new offer items. SpentItem memory originalOffer = orderToExecute.spentItems[i]; SpentItem memory newOffer = offer[i]; // Set returned identifier for criteria-based items with // criteria = 0. Note that this reset means that a contract // offerer has full latitude to choose any identifier it wants // mid-flight, in contrast to the normal behavior, where the // fulfiller can pick which identifier to receive by providing a // CriteriaResolver. if ( uint256(originalOffer.itemType) > 3 && originalOffer.identifier == 0 ) { originalOffer.itemType = ItemType( uint256(originalOffer.itemType) - 2 ); originalOffer.identifier = newOffer.identifier; } // Ensure the original and generated items are compatible. if ( originalOffer.amount > newOffer.amount || originalOffer.itemType != newOffer.itemType || originalOffer.token != newOffer.token || originalOffer.identifier != newOffer.identifier ) { revert InvalidContractOrder(orderHash); } } orderToExecute.spentItems = offer; orderToExecute.spentItemOriginalAmounts = new uint256[]( offer.length ); // Add new offer items if there are more than original. for (uint256 i = 0; i < offer.length; ++i) { orderToExecute.spentItemOriginalAmounts[i] = offer[i].amount; } } { // Designate lengths & memory locations. ReceivedItem[] memory originalConsiderationArray = ( orderToExecute.receivedItems ); uint256 newConsiderationLength = consideration.length; // New consideration items cannot be created. if (newConsiderationLength > originalConsiderationArray.length) { revert InvalidContractOrder(orderHash); } // Loop through and check consideration. for (uint256 i = 0; i < newConsiderationLength; ++i) { ReceivedItem memory newConsideration = consideration[i]; ReceivedItem memory originalConsideration = ( originalConsiderationArray[i] ); if ( uint256(originalConsideration.itemType) > 3 && originalConsideration.identifier == 0 ) { originalConsideration.itemType = ItemType( uint256(originalConsideration.itemType) - 2 ); originalConsideration.identifier = ( newConsideration.identifier ); } // All fields must match the originally supplied fields except // for the amount (which may be reduced by the contract offerer) // and the recipient if some non-zero address has been provided. if ( newConsideration.amount > originalConsideration.amount || originalConsideration.itemType != newConsideration.itemType || originalConsideration.token != newConsideration.token || originalConsideration.identifier != newConsideration.identifier || (originalConsideration.recipient != address(0) && originalConsideration.recipient != (newConsideration.recipient)) ) { revert InvalidContractOrder(orderHash); } } orderToExecute.receivedItems = consideration; orderToExecute.receivedItemOriginalAmounts = new uint256[]( consideration.length ); // Iterate over original consideration array and copy to new. for (uint256 i = 0; i < consideration.length; ++i) { orderToExecute.receivedItemOriginalAmounts[i] = ( consideration[i].amount ); } } // Return the order hash. return orderHash; } /** * @dev Internal function to cancel an arbitrary number of orders. Note that * only the offerer or the zone of a given order may cancel it. Callers * should ensure that the intended order was cancelled by calling * `getOrderStatus` and confirming that `isCancelled` returns `true`. * Also note that contract orders are not cancellable. * * @param orders The orders to cancel. * * @return A boolean indicating whether the supplied orders were * successfully cancelled. */ function _cancel( OrderComponents[] calldata orders ) internal returns (bool) { // Declare variables outside of the loop. OrderStatus storage orderStatus; address offerer; address zone; // Read length of the orders array from memory and place on stack. uint256 totalOrders = orders.length; // Iterate over each order. for (uint256 i = 0; i < totalOrders; ++i) { // Retrieve the order. OrderComponents calldata order = orders[i]; offerer = order.offerer; zone = order.zone; // Ensure caller is either offerer or zone of the order and that the // order is not a contract order. if ( order.orderType == OrderType.CONTRACT || (msg.sender != offerer && msg.sender != zone) ) { revert CannotCancelOrder(); } // Derive order hash using the order parameters and the counter. bytes32 orderHash = _deriveOrderHash( OrderParameters( offerer, zone, order.offer, order.consideration, order.orderType, order.startTime, order.endTime, order.zoneHash, order.salt, order.conduitKey, order.consideration.length ), order.counter ); // Retrieve the order status using the derived order hash. orderStatus = _orderStatus[orderHash]; // Update the order status as not valid and cancelled. orderStatus.isValidated = false; orderStatus.isCancelled = true; // Emit an event signifying that the order has been cancelled. emit OrderCancelled(orderHash, offerer, zone); } return true; } /** * @dev Internal function to validate an arbitrary number of orders, thereby * registering them as valid and allowing the fulfiller to skip * verification. Note that anyone can validate a signed order but only * the offerer can validate an order without supplying a signature. * * @param orders The orders to validate. * * @return A boolean indicating whether the supplied orders were * successfully validated. */ function _validate(Order[] calldata orders) internal returns (bool) { // Declare variables outside of the loop. OrderStatus storage orderStatus; bytes32 orderHash; address offerer; // Read length of the orders array from memory and place on stack. uint256 totalOrders = orders.length; // Iterate over each order. for (uint256 i = 0; i < totalOrders; ++i) { // Retrieve the order. Order calldata order = orders[i]; // Retrieve the order parameters. OrderParameters calldata orderParameters = order.parameters; // Skip contract orders. if (orderParameters.orderType == OrderType.CONTRACT) { continue; } // Move offerer from memory to the stack. offerer = orderParameters.offerer; // Get current counter and use it w/ params to derive order hash. orderHash = _assertConsiderationLengthAndGetOrderHash( orderParameters ); // Retrieve the order status using the derived order hash. orderStatus = _orderStatus[orderHash]; // Ensure order is fillable and retrieve the filled amount. _verifyOrderStatus( orderHash, orderStatus, false, // Signifies that partially filled orders are valid. true // Signifies to revert if the order is invalid. ); // If the order has not already been validated... if (!orderStatus.isValidated) { // Ensure that consideration array length is equal to the total // original consideration items value. if ( orderParameters.consideration.length != orderParameters.totalOriginalConsiderationItems ) { revert ConsiderationLengthNotEqualToTotalOriginal(); } // Verify the supplied signature. _verifySignature(offerer, orderHash, order.signature); // Update order status to mark the order as valid. orderStatus.isValidated = true; // Emit an event signifying the order has been validated. emit OrderValidated(orderHash, orderParameters); } } return true; } /** * @dev Internal view function to retrieve the status of a given order by * hash, including whether the order has been cancelled or validated * and the fraction of the order that has been filled. * * @param orderHash The order hash in question. * * @return isValidated A boolean indicating whether the order in question * has been validated (i.e. previously approved or * partially filled). * @return isCancelled A boolean indicating whether the order in question * has been cancelled. * @return totalFilled The total portion of the order that has been filled * (i.e. the "numerator"). * @return totalSize The total size of the order that is either filled or * unfilled (i.e. the "denominator"). */ function _getOrderStatus( bytes32 orderHash ) internal view returns ( bool isValidated, bool isCancelled, uint256 totalFilled, uint256 totalSize ) { // Retrieve the order status using the order hash. OrderStatus storage orderStatus = _orderStatus[orderHash]; // Return the fields on the order status. return ( orderStatus.isValidated, orderStatus.isCancelled, orderStatus.numerator, orderStatus.denominator ); } /** * @dev Internal pure function to either revert or return an empty tuple * depending on the value of `revertOnInvalid`. * * @param revertOnInvalid Whether to revert on invalid input. * @param contractOrderHash The contract order hash. * * @return orderHash The order hash. */ function _revertOrReturnEmpty( bool revertOnInvalid, bytes32 contractOrderHash ) internal pure returns (bytes32 orderHash, OrderToExecute memory emptyOrder) { // If invalid input should not revert... if (!revertOnInvalid) { // Return no contract order hash and zero values for the numerator // and denominator. return (bytes32(0), emptyOrder); } // Otherwise, revert. revert InvalidContractOrder(contractOrderHash); } /** * @dev Internal pure function to convert received items to spent items. * * @param consideration The consideration items to convert. * * @return receivedItems The converted received items. */ function _convertToSpent( ReceivedItem[] memory consideration ) internal pure returns (SpentItem[] memory receivedItems) { // Create an array of received items equal to the consideration length. receivedItems = new SpentItem[](consideration.length); // Iterate over each received item on the order. for (uint256 i = 0; i < consideration.length; ++i) { // Retrieve the consideration item. ReceivedItem memory considerationItem = (consideration[i]); // Create spent item for event based on the consideration item. SpentItem memory receivedItem = SpentItem( considerationItem.itemType, considerationItem.token, considerationItem.identifier, considerationItem.amount ); // Add to array of received items. receivedItems[i] = receivedItem; } } /** * @dev Internal function to derive the greatest common divisor of two * values using the classical euclidian algorithm. * * @param a The first value. * @param b The second value. * * @return greatestCommonDivisor The greatest common divisor. */ function _greatestCommonDivisor( uint256 a, uint256 b ) internal pure returns (uint256 greatestCommonDivisor) { while (b > 0) { uint256 c = b; b = a % c; a = c; } greatestCommonDivisor = a; } /** * @dev Internal pure function to check whether a given order type indicates * that partial fills are not supported (e.g. only "full fills" are * allowed for the order in question). * * @param orderType The order type in question. * * @return isFullOrder A boolean indicating whether the order type only * supports full fills. */ function _doesNotSupportPartialFills( OrderType orderType ) internal pure returns (bool isFullOrder) { // The "full" order types are even, while "partial" order types are odd. isFullOrder = uint256(orderType) & 1 == 0; } /** * @dev Internal pure function to convert an advanced order to an order * to execute. * * @param orderParameters The order to convert. * * @return orderToExecute The new order to execute. */ function _convertAdvancedToOrder( OrderParameters memory orderParameters, uint120 numerator ) internal pure returns (OrderToExecute memory orderToExecute) { // Retrieve the advanced orders offers. OfferItem[] memory offer = orderParameters.offer; // Create an array of spent items equal to the offer length. SpentItem[] memory spentItems = new SpentItem[](offer.length); uint256[] memory spentItemOriginalAmounts = new uint256[](offer.length); // Iterate over each offer item on the order. for (uint256 i = 0; i < offer.length; ++i) { // Retrieve the offer item. OfferItem memory offerItem = offer[i]; // Create spent item for event based on the offer item. SpentItem memory spentItem = SpentItem( offerItem.itemType, offerItem.token, offerItem.identifierOrCriteria, offerItem.startAmount ); // Add to array of spent items. spentItems[i] = spentItem; spentItemOriginalAmounts[i] = offerItem.startAmount; } // Retrieve the consideration array from the advanced order. ConsiderationItem[] memory consideration = orderParameters .consideration; // Create an array of received items equal to the consideration length. ReceivedItem[] memory receivedItems = new ReceivedItem[]( consideration.length ); // Create an array of uint256 values equal in length to the // consideration length containing the amounts of each item. uint256[] memory receivedItemOriginalAmounts = new uint256[]( consideration.length ); // Iterate over each consideration item on the order. for (uint256 i = 0; i < consideration.length; ++i) { // Retrieve the consideration item. ConsiderationItem memory considerationItem = (consideration[i]); // Create received item for event based on the consideration item. ReceivedItem memory receivedItem = ReceivedItem( considerationItem.itemType, considerationItem.token, considerationItem.identifierOrCriteria, considerationItem.startAmount, considerationItem.recipient ); // Add to array of received items. receivedItems[i] = receivedItem; // Add to array of received item amounts. receivedItemOriginalAmounts[i] = considerationItem.startAmount; } // Create the order to execute from the advanced order data. orderToExecute = OrderToExecute( orderParameters.offerer, spentItems, receivedItems, orderParameters.conduitKey, numerator, spentItemOriginalAmounts, receivedItemOriginalAmounts ); // Return the order. return orderToExecute; } /** * @dev Internal pure function to convert an array of advanced orders to * an array of orders to execute. * * @param advancedOrders The advanced orders to convert. * * @return ordersToExecute The new array of orders. */ function _convertAdvancedToOrdersToExecute( AdvancedOrder[] memory advancedOrders ) internal pure returns (OrderToExecute[] memory ordersToExecute) { // Read the number of orders from memory and place on the stack. uint256 totalOrders = advancedOrders.length; // Allocate new empty array for each advanced order in memory. ordersToExecute = new OrderToExecute[](totalOrders); // Iterate over the given orders. for (uint256 i = 0; i < totalOrders; ++i) { // Convert and update array. ordersToExecute[i] = _convertAdvancedToOrder( advancedOrders[i].parameters, advancedOrders[i].numerator ); } // Return the array of orders to execute return ordersToExecute; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ReceivedItem, Schema, SpentItem } from "../lib/ConsiderationStructs.sol"; import { IERC165 } from "../interfaces/IERC165.sol"; /** * @title ContractOffererInterface * @notice Contains the minimum interfaces needed to interact with a contract * offerer. */ interface ContractOffererInterface is IERC165 { /** * @dev Generates an order with the specified minimum and maximum spent * items, and optional context (supplied as extraData). * * @param fulfiller The address of the fulfiller. * @param minimumReceived The minimum items that the caller is willing to * receive. * @param maximumSpent The maximum items the caller is willing to spend. * @param context Additional context of the order. * * @return offer A tuple containing the offer items. * @return consideration A tuple containing the consideration items. */ function generateOrder( address fulfiller, SpentItem[] calldata minimumReceived, SpentItem[] calldata maximumSpent, bytes calldata context // encoded based on the schemaID ) external returns (SpentItem[] memory offer, ReceivedItem[] memory consideration); /** * @dev Ratifies an order with the specified offer, consideration, and * optional context (supplied as extraData). * * @param offer The offer items. * @param consideration The consideration items. * @param context Additional context of the order. * @param orderHashes The hashes to ratify. * @param contractNonce The nonce of the contract. * * @return ratifyOrderMagicValue The magic value returned by the contract * offerer. */ function ratifyOrder( SpentItem[] calldata offer, ReceivedItem[] calldata consideration, bytes calldata context, // encoded based on the schemaID bytes32[] calldata orderHashes, uint256 contractNonce ) external returns (bytes4 ratifyOrderMagicValue); /** * @dev View function to preview an order generated in response to a minimum * set of received items, maximum set of spent items, and context * (supplied as extraData). * * @param caller The address of the caller (e.g. Seaport). * @param fulfiller The address of the fulfiller (e.g. the account * calling Seaport). * @param minimumReceived The minimum items that the caller is willing to * receive. * @param maximumSpent The maximum items the caller is willing to spend. * @param context Additional context of the order. * * @return offer A tuple containing the offer items. * @return consideration A tuple containing the consideration items. */ function previewOrder( address caller, address fulfiller, SpentItem[] calldata minimumReceived, SpentItem[] calldata maximumSpent, bytes calldata context // encoded based on the schemaID ) external view returns (SpentItem[] memory offer, ReceivedItem[] memory consideration); /** * @dev Gets the metadata for this contract offerer. * * @return name The name of the contract offerer. * @return schemas The schemas supported by the contract offerer. */ function getSeaportMetadata() external view returns (string memory name, Schema[] memory schemas); // map to SIP IDs function supportsInterface( bytes4 interfaceId ) external view override returns (bool); // Additional functions and/or events based on implemented schemaIDs }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ConduitItemType } from "seaport-types/src/conduit/lib/ConduitEnums.sol"; import { ConduitInterface } from "seaport-types/src/interfaces/ConduitInterface.sol"; import { ConduitTransfer } from "seaport-types/src/conduit/lib/ConduitStructs.sol"; import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { ReceivedItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { ReferenceVerifiers } from "./ReferenceVerifiers.sol"; import { ReferenceTokenTransferrer } from "./ReferenceTokenTransferrer.sol"; import { AccumulatorStruct } from "./ReferenceConsiderationStructs.sol"; /** * @title Executor * @author 0age * @notice Executor contains functions related to processing executions (i.e. * transferring items, either directly or via conduits). */ contract ReferenceExecutor is ReferenceVerifiers, ReferenceTokenTransferrer { /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceVerifiers(conduitController) {} /** * @dev Internal function to transfer a given item. * * @param item The item to transfer including an amount * and recipient. * @param offerer The account offering the item, i.e. the * from address. * @param conduitKey A bytes32 value indicating what * corresponding conduit, if any, to source * token approvals from. The zero hash * signifies that no conduit should be used * (and direct approvals set on Consideration) * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. */ function _transfer( ReceivedItem memory item, address offerer, bytes32 conduitKey, AccumulatorStruct memory accumulatorStruct ) internal { // If the item type indicates Ether or a native token... if (item.itemType == ItemType.NATIVE) { // Ensure neither the token nor the identifier parameters are set. if ((uint160(item.token) | item.identifier) != 0) { revert UnusedItemParameters(); } // Transfer the native tokens to the recipient. _transferNativeTokens(item.recipient, item.amount); } else if (item.itemType == ItemType.ERC20) { // Ensure that no identifier is supplied. if (item.identifier != 0) { revert UnusedItemParameters(); } // Transfer ERC20 tokens from the offerer to the recipient. _transferERC20( item.token, offerer, item.recipient, item.amount, conduitKey, accumulatorStruct ); } else if (item.itemType == ItemType.ERC721) { // Transfer ERC721 token from the offerer to the recipient. _transferERC721( item.token, offerer, item.recipient, item.identifier, item.amount, conduitKey, accumulatorStruct ); } else { // Transfer ERC1155 token from the offerer to the recipient. _transferERC1155( item.token, offerer, item.recipient, item.identifier, item.amount, conduitKey, accumulatorStruct ); } } /** * @dev Internal function to transfer Ether or other native tokens to a * given recipient. Note that this reference implementation deviates * from the primary contract, which "bubbles up" revert data when * present (the reference contract always throws a generic error). * * @param to The recipient of the transfer. * @param amount The amount to transfer. */ function _transferNativeTokens( address payable to, uint256 amount ) internal { // Ensure that the supplied amount is non-zero. _assertNonZeroAmount(amount); // Declare a variable indicating whether the call was successful or not. (bool success, ) = to.call{ value: amount }(""); // If the call fails... if (!success) { // Revert with a generic error message. revert NativeTokenTransferGenericFailure(to, amount); } } /** * @dev Internal function to transfer ERC20 tokens from a given originator * to a given recipient using a given conduit if applicable. Sufficient * approvals must be set on this contract, the conduit. * * @param token The ERC20 token to transfer. * @param from The originator of the transfer. * @param to The recipient of the transfer. * @param amount The amount to transfer. * @param conduitKey A bytes32 value indicating what * corresponding conduit, if any, to source * token approvals from. The zero hash * signifies that no conduit should be used * (and direct approvals set on Consideration) * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. */ function _transferERC20( address token, address from, address to, uint256 amount, bytes32 conduitKey, AccumulatorStruct memory accumulatorStruct ) internal { // Ensure that the supplied amount is non-zero. _assertNonZeroAmount(amount); // Trigger accumulated transfers if the conduits differ. _triggerIfArmedAndNotAccumulatable(accumulatorStruct, conduitKey); // If no conduit has been specified... if (conduitKey == bytes32(0)) { // Perform the token transfer directly. _performERC20Transfer(token, from, to, amount); } else { // Insert the call to the conduit into the accumulator. _insert( conduitKey, accumulatorStruct, ConduitItemType.ERC20, token, from, to, uint256(0), amount ); } } /** * @dev Internal function to transfer a single ERC721 token from a given * originator to a given recipient. Sufficient approvals must be set, * either on the respective conduit or on this contract itself. * * @param token The ERC721 token to transfer. * @param from The originator of the transfer. * @param to The recipient of the transfer. * @param identifier The tokenId to transfer. * @param amount The "amount" (this value must be equal * to one). * @param conduitKey A bytes32 value indicating what * corresponding conduit, if any, to source * token approvals from. The zero hash * signifies that no conduit should be used * (and direct approvals set on Consideration) * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. */ function _transferERC721( address token, address from, address to, uint256 identifier, uint256 amount, bytes32 conduitKey, AccumulatorStruct memory accumulatorStruct ) internal { // Trigger accumulated transfers if the conduits differ. _triggerIfArmedAndNotAccumulatable(accumulatorStruct, conduitKey); // If no conduit has been specified... if (conduitKey == bytes32(0)) { // Ensure that exactly one 721 item is being transferred. if (amount != 1) { revert InvalidERC721TransferAmount(amount); } // Perform transfer via the token contract directly. _performERC721Transfer(token, from, to, identifier); } else { // Insert the call to the conduit into the accumulator. _insert( conduitKey, accumulatorStruct, ConduitItemType.ERC721, token, from, to, identifier, amount ); } } /** * @dev Internal function to transfer ERC1155 tokens from a given originator * to a given recipient. Sufficient approvals must be set, either on * the respective conduit or on this contract itself. * * @param token The ERC1155 token to transfer. * @param from The originator of the transfer. * @param to The recipient of the transfer. * @param identifier The tokenId to transfer. * @param amount The amount to transfer. * @param conduitKey A bytes32 value indicating what * corresponding conduit, if any, to source * token approvals from. The zero hash * signifies that no conduit should be used * (and direct approvals set on Consideration) * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. */ function _transferERC1155( address token, address from, address to, uint256 identifier, uint256 amount, bytes32 conduitKey, AccumulatorStruct memory accumulatorStruct ) internal { // Ensure that the supplied amount is non-zero. _assertNonZeroAmount(amount); // Trigger accumulated transfers if the conduits differ. _triggerIfArmedAndNotAccumulatable(accumulatorStruct, conduitKey); // If no conduit has been specified... if (conduitKey == bytes32(0)) { // Perform transfer via the token contract directly. _performERC1155Transfer(token, from, to, identifier, amount); } else { // Insert the call to the conduit into the accumulator. _insert( conduitKey, accumulatorStruct, ConduitItemType.ERC1155, token, from, to, identifier, amount ); } } /** * @dev Internal function to trigger a call to the conduit currently held by * the accumulator if the accumulator contains item transfers (i.e. it * is "armed") and the supplied conduit key does not match the key held * by the accumulator. * * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. * @param conduitKey A bytes32 value indicating what corresponding * conduit, if any, to source token approvals * from. The zero hash signifies that no conduit * should be used (and direct approvals set on * Consideration) */ function _triggerIfArmedAndNotAccumulatable( AccumulatorStruct memory accumulatorStruct, bytes32 conduitKey ) internal { // Perform conduit call if the set key does not match the supplied key. if (accumulatorStruct.conduitKey != conduitKey) { _triggerIfArmed(accumulatorStruct); } } /** * @dev Internal function to trigger a call to the conduit currently held by * the accumulator if the accumulator contains item transfers (i.e. it * is "armed"). * * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. */ function _triggerIfArmed( AccumulatorStruct memory accumulatorStruct ) internal { // Exit if the accumulator is not "armed". if (accumulatorStruct.transfers.length == 0) { return; } // Perform conduit call. _trigger(accumulatorStruct); } /** * @dev Internal function to trigger a call to the conduit corresponding to * a given conduit key, supplying all accumulated item transfers. The * accumulator will be "disarmed" and reset in the process. * * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. */ function _trigger(AccumulatorStruct memory accumulatorStruct) internal { // Call the conduit with all the accumulated transfers. ConduitInterface(_getConduit(accumulatorStruct.conduitKey)).execute( accumulatorStruct.transfers ); // Reset accumulator length to signal that it is now "disarmed". delete accumulatorStruct.transfers; } /** * @dev Internal pure function to place an item transfer into an accumulator * that collects a series of transfers to execute against a given * conduit in a single call. * * @param conduitKey A bytes32 value indicating what * corresponding conduit, if any, to source * token approvals from. The zero hash * signifies that no conduit should be used * (and direct approvals set on Consideration) * @param accumulatorStruct A struct containing conduit transfer data * and its corresponding conduitKey. * @param itemType The type of the item to transfer. * @param token The token to transfer. * @param from The originator of the transfer. * @param to The recipient of the transfer. * @param identifier The tokenId to transfer. * @param amount The amount to transfer. */ function _insert( bytes32 conduitKey, AccumulatorStruct memory accumulatorStruct, ConduitItemType itemType, address token, address from, address to, uint256 identifier, uint256 amount ) internal pure { /** * The following is highly inefficient, but written this way to * simply demonstrate what is performed by the optimized contract. */ // Get the current length of the accumulator's transfers. uint256 currentTransferLength = accumulatorStruct.transfers.length; // Create a new array to "insert" the new transfer. ConduitTransfer[] memory newTransfers = ( new ConduitTransfer[](currentTransferLength + 1) ); // Fill new array with old transfers. for (uint256 i = 0; i < currentTransferLength; ++i) { // Get the old transfer. ConduitTransfer memory oldTransfer = accumulatorStruct.transfers[i]; // Add the old transfer into the new array. newTransfers[i] = ConduitTransfer( oldTransfer.itemType, oldTransfer.token, oldTransfer.from, oldTransfer.to, oldTransfer.identifier, oldTransfer.amount ); } // Insert new transfer into array. newTransfers[currentTransferLength] = ConduitTransfer( itemType, token, from, to, identifier, amount ); // Set accumulator struct transfers to new transfers. accumulatorStruct.transfers = newTransfers; // Set the conduitkey of the current transfers. accumulatorStruct.conduitKey = conduitKey; } /** * @dev Internal function get the conduit derived by the provided * conduit key. * * @param conduitKey A bytes32 value indicating what corresponding conduit, * if any, to source token approvals from. This value is * the "salt" parameter supplied by the deployer (i.e. the * conduit controller) when deploying the given conduit. * * @return conduit The address of the conduit associated with the given * conduit key. */ function _getConduit( bytes32 conduitKey ) internal view returns (address conduit) { // Derive the address of the conduit using the conduit key. conduit = _deriveConduit(conduitKey); // If the conduit does not have runtime code (i.e. is not deployed)... if (conduit.code.length == 0) { // Revert with an error indicating an invalid conduit. revert InvalidConduit(conduitKey, conduit); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol"; import { ContractOffererInterface } from "seaport-types/src/interfaces/ContractOffererInterface.sol"; import { ItemType, OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol"; import { AdditionalRecipient, AdvancedOrder, BasicOrderParameters, ReceivedItem, SpentItem, ZoneParameters } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { OrderToExecute } from "./ReferenceConsiderationStructs.sol"; import { ZoneInteractionErrors } from "seaport-types/src/interfaces/ZoneInteractionErrors.sol"; /** * @title ZoneInteraction * @author 0age * @notice ZoneInteraction contains logic related to interacting with zones. */ contract ReferenceZoneInteraction is ZoneInteractionErrors { function _assertRestrictedBasicOrderAuthorization( bytes32 orderHash, OrderType orderType, BasicOrderParameters calldata basicOrderParameters, ItemType offeredItemType, ItemType receivedItemType ) internal { // Create a new array for the hash. bytes32[] memory orderHashes = new bytes32[](0); // Convert the order params and types to spent and received items. ( SpentItem[] memory offer, ReceivedItem[] memory consideration ) = _convertToSpentAndReceivedItems( basicOrderParameters, offeredItemType, receivedItemType ); // Order types 2-3 require zone or offerer be caller or zone to approve. // Note that in cases where fulfiller == zone, the restricted order // validation will be skipped. if ( (orderType == OrderType.FULL_RESTRICTED || orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != basicOrderParameters.zone ) { // Validate the order with the zone. if ( ZoneInterface(basicOrderParameters.zone).authorizeOrder( ZoneParameters({ orderHash: orderHash, fulfiller: msg.sender, offerer: basicOrderParameters.offerer, offer: offer, consideration: consideration, extraData: "", orderHashes: orderHashes, startTime: basicOrderParameters.startTime, endTime: basicOrderParameters.endTime, zoneHash: basicOrderParameters.zoneHash }) ) != ZoneInterface.authorizeOrder.selector ) { revert InvalidRestrictedOrder(orderHash); } } } /** * @dev Internal view function to determine if an order has a restricted * order type and, if so, to ensure that either the offerer or the zone * are the fulfiller or that a staticcall to `isValidOrder` on the zone * returns a magic value indicating that the order is currently valid. * * @param orderHash The hash of the order. * @param basicOrderParameters The original basic order parameters. * @param offeredItemType The type of the order. * @param receivedItemType The offerer in question. */ function _assertRestrictedBasicOrderValidity( bytes32 orderHash, OrderType orderType, BasicOrderParameters calldata basicOrderParameters, ItemType offeredItemType, ItemType receivedItemType ) internal { // Create a new array for the hash. bytes32[] memory orderHashes = new bytes32[](1); orderHashes[0] = orderHash; // Convert the order params and types to spent and received items. ( SpentItem[] memory offer, ReceivedItem[] memory consideration ) = _convertToSpentAndReceivedItems( basicOrderParameters, offeredItemType, receivedItemType ); // Order types 2-3 require zone or offerer be caller or zone to approve. // Note that in cases where fulfiller == zone, the restricted order // validation will be skipped. if ( (orderType == OrderType.FULL_RESTRICTED || orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != basicOrderParameters.zone ) { // Validate the order with the zone. if ( ZoneInterface(basicOrderParameters.zone).validateOrder( ZoneParameters({ orderHash: orderHash, fulfiller: msg.sender, offerer: basicOrderParameters.offerer, offer: offer, consideration: consideration, extraData: "", orderHashes: orderHashes, startTime: basicOrderParameters.startTime, endTime: basicOrderParameters.endTime, zoneHash: basicOrderParameters.zoneHash }) ) != ZoneInterface.validateOrder.selector ) { revert InvalidRestrictedOrder(orderHash); } } } /** * @dev Internal function to check if a restricted advanced order is * authorized by its zone or offerer, in cases where the caller is not * the zone or offerer. * * @param advancedOrder The advanced order in question. * @param orderToExecute The order to execute. * @param orderHashes The order hashes of each order supplied * alongside the current order as part of a "match" or "fulfill available" variety of order fulfillment. * @param orderHash The hash of the order to execute. * @param revertOnUnauthorized A boolean indicating whether the function * should revert if the order is invalid. * * @return authorized A boolean indicating whether the order is * authorized by the zone or offerer. * @return checked A boolean indicating whether the order has * been checked for authorization. */ function _checkRestrictedAdvancedOrderAuthorization( AdvancedOrder memory advancedOrder, OrderToExecute memory orderToExecute, bytes32[] memory orderHashes, bytes32 orderHash, bool revertOnUnauthorized ) internal returns (bool authorized, bool checked) { // Order types 2-3 require zone or offerer be caller or zone to approve. if ( (advancedOrder.parameters.orderType == OrderType.FULL_RESTRICTED || advancedOrder.parameters.orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != advancedOrder.parameters.zone ) { // Authorize the order. try ZoneInterface(advancedOrder.parameters.zone).authorizeOrder( ZoneParameters({ orderHash: orderHash, fulfiller: msg.sender, offerer: advancedOrder.parameters.offerer, offer: orderToExecute.spentItems, consideration: orderToExecute.receivedItems, extraData: advancedOrder.extraData, orderHashes: orderHashes, startTime: advancedOrder.parameters.startTime, endTime: advancedOrder.parameters.endTime, zoneHash: advancedOrder.parameters.zoneHash }) ) returns (bytes4 selector) { if (selector != ZoneInterface.authorizeOrder.selector) { revert InvalidRestrictedOrder(orderHash); } return (true, true); } catch { if (revertOnUnauthorized) { revert InvalidRestrictedOrder(orderHash); } return (false, false); } } else { return (true, false); } } /** * @dev Internal function to validate that a restricted advanced order is * authorized by its zone or offerer, in cases where the caller is not * the zone or offerer. * * @param advancedOrder The advanced order in question. * @param orderToExecute The order to execute. * @param orderHashes The order hashes of each order supplied * alongside the current order as part of a "match" or "fulfill available" variety of order fulfillment. * @param orderHash The hash of the order to execute. * @param zoneHash The hash to provide upon calling the zone. * @param orderType The type of the order. * @param offerer The offerer in question. * @param zone The zone in question. */ function _assertRestrictedAdvancedOrderAuthorization( AdvancedOrder memory advancedOrder, OrderToExecute memory orderToExecute, bytes32[] memory orderHashes, bytes32 orderHash, bytes32 zoneHash, OrderType orderType, address offerer, address zone ) internal { // Order types 2-3 require zone or offerer be caller or zone to approve. if ( (orderType == OrderType.FULL_RESTRICTED || orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != zone ) { // Authorize the order. if ( ZoneInterface(zone).authorizeOrder( ZoneParameters({ orderHash: orderHash, fulfiller: msg.sender, offerer: offerer, offer: orderToExecute.spentItems, consideration: orderToExecute.receivedItems, extraData: advancedOrder.extraData, orderHashes: orderHashes, startTime: advancedOrder.parameters.startTime, endTime: advancedOrder.parameters.endTime, zoneHash: zoneHash }) ) != ZoneInterface.authorizeOrder.selector ) { revert InvalidRestrictedOrder(orderHash); } } } /** * @dev Internal view function to determine if a proxy should be utilized * for a given order and to ensure that the submitter is allowed by the * order type. * * @param advancedOrder The order in question. * @param orderHashes The order hashes of each order supplied alongside * the current order as part of a "match" or "fulfill * available" variety of order fulfillment. * @param orderHash The hash of the order. * @param zoneHash The hash to provide upon calling the zone. * @param orderType The type of the order. * @param offerer The offerer in question. * @param zone The zone in question. */ function _assertRestrictedAdvancedOrderValidity( AdvancedOrder memory advancedOrder, OrderToExecute memory orderToExecute, bytes32[] memory orderHashes, bytes32 orderHash, bytes32 zoneHash, OrderType orderType, address offerer, address zone ) internal { // Order types 2-3 require zone or offerer be caller or zone to approve. if ( (orderType == OrderType.FULL_RESTRICTED || orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != zone ) { // Validate the order. if ( ZoneInterface(zone).validateOrder( ZoneParameters({ orderHash: orderHash, fulfiller: msg.sender, offerer: offerer, offer: orderToExecute.spentItems, consideration: orderToExecute.receivedItems, extraData: advancedOrder.extraData, orderHashes: orderHashes, startTime: advancedOrder.parameters.startTime, endTime: advancedOrder.parameters.endTime, zoneHash: zoneHash }) ) != ZoneInterface.validateOrder.selector ) { revert InvalidRestrictedOrder(orderHash); } } else if (orderType == OrderType.CONTRACT) { // Ratify the contract order. if ( ContractOffererInterface(offerer).ratifyOrder( orderToExecute.spentItems, orderToExecute.receivedItems, advancedOrder.extraData, orderHashes, uint256(orderHash) ^ (uint256(uint160(offerer)) << 96) ) != ContractOffererInterface.ratifyOrder.selector ) { revert InvalidContractOrder(orderHash); } } } /** * @dev Converts the offer and consideration parameters from a * BasicOrderParameters object into an array of SpentItem and * ReceivedItem objects. * * @param parameters The BasicOrderParameters object containing * the offer and consideration parameters to be * converted. * @param offerItemType The item type of the offer. * @param considerationItemType The item type of the consideration. * * @return spentItems The converted offer parameters as an array * of SpentItem objects. * @return receivedItems The converted consideration parameters as an * array of ReceivedItem objects. */ function _convertToSpentAndReceivedItems( BasicOrderParameters calldata parameters, ItemType offerItemType, ItemType considerationItemType ) internal pure returns (SpentItem[] memory, ReceivedItem[] memory) { // Create the spent item. SpentItem[] memory spentItems = new SpentItem[](1); spentItems[0] = SpentItem({ itemType: offerItemType, token: parameters.offerToken, amount: parameters.offerAmount, identifier: parameters.offerIdentifier }); // Create the received item. ReceivedItem[] memory receivedItems = new ReceivedItem[]( 1 + parameters.additionalRecipients.length ); address token = parameters.considerationToken; uint256 amount = parameters.considerationAmount; uint256 identifier = parameters.considerationIdentifier; receivedItems[0] = ReceivedItem({ itemType: considerationItemType, token: token, amount: amount, identifier: identifier, recipient: parameters.offerer }); // Iterate through the additional recipients and create the received // items. for (uint256 i = 0; i < parameters.additionalRecipients.length; i++) { AdditionalRecipient calldata additionalRecipient = parameters .additionalRecipients[i]; amount = additionalRecipient.amount; receivedItems[i + 1] = ReceivedItem({ itemType: offerItemType == ItemType.ERC20 ? ItemType.ERC20 : considerationItemType, token: offerItemType == ItemType.ERC20 ? parameters.offerToken : token, amount: amount, identifier: offerItemType == ItemType.ERC20 ? 0 : identifier, recipient: additionalRecipient.recipient }); } // Return the spent and received items. return (spentItems, receivedItems); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ReceivedItem, SpentItem } from "seaport-types/src/lib/ConsiderationStructs.sol"; contract ReferenceGenerateOrderReturndataDecoder { function decode( bytes calldata returnedBytes ) external pure returns (SpentItem[] memory, ReceivedItem[] memory) { return abi.decode(returnedBytes, (SpentItem[], ReceivedItem[])); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.7; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ConduitBatch1155Transfer, ConduitTransfer } from "../conduit/lib/ConduitStructs.sol"; /** * @title ConduitInterface * @author 0age * @notice ConduitInterface contains all external function interfaces, events, * and errors for conduit contracts. */ interface ConduitInterface { /** * @dev Revert with an error when attempting to execute transfers using a * caller that does not have an open channel. */ error ChannelClosed(address channel); /** * @dev Revert with an error when attempting to update a channel to the * current status of that channel. */ error ChannelStatusAlreadySet(address channel, bool isOpen); /** * @dev Revert with an error when attempting to execute a transfer for an * item that does not have an ERC20/721/1155 item type. */ error InvalidItemType(); /** * @dev Revert with an error when attempting to update the status of a * channel from a caller that is not the conduit controller. */ error InvalidController(); /** * @dev Emit an event whenever a channel is opened or closed. * * @param channel The channel that has been updated. * @param open A boolean indicating whether the conduit is open or not. */ event ChannelUpdated(address indexed channel, bool open); /** * @notice Execute a sequence of ERC20/721/1155 transfers. Only a caller * with an open channel can call this function. * * @param transfers The ERC20/721/1155 transfers to perform. * * @return magicValue A magic value indicating that the transfers were * performed successfully. */ function execute( ConduitTransfer[] calldata transfers ) external returns (bytes4 magicValue); /** * @notice Execute a sequence of batch 1155 transfers. Only a caller with an * open channel can call this function. * * @param batch1155Transfers The 1155 batch transfers to perform. * * @return magicValue A magic value indicating that the transfers were * performed successfully. */ function executeBatch1155( ConduitBatch1155Transfer[] calldata batch1155Transfers ) external returns (bytes4 magicValue); /** * @notice Execute a sequence of transfers, both single and batch 1155. Only * a caller with an open channel can call this function. * * @param standardTransfers The ERC20/721/1155 transfers to perform. * @param batch1155Transfers The 1155 batch transfers to perform. * * @return magicValue A magic value indicating that the transfers were * performed successfully. */ function executeWithBatch1155( ConduitTransfer[] calldata standardTransfers, ConduitBatch1155Transfer[] calldata batch1155Transfers ) external returns (bytes4 magicValue); /** * @notice Open or close a given channel. Only callable by the controller. * * @param channel The channel to open or close. * @param isOpen The status of the channel (either open or closed). */ function updateChannel(address channel, bool isOpen) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ZoneParameters, Schema } from "../lib/ConsiderationStructs.sol"; import { IERC165 } from "./IERC165.sol"; /** * @title ZoneInterface * @notice Contains functions exposed by a zone. */ interface ZoneInterface is IERC165 { /** * @dev Authorizes an order before any token fulfillments from any order * have been executed by Seaport. * * @param zoneParameters The context about the order fulfillment and any * supplied extraData. * * @return authorizedOrderMagicValue The magic value that indicates a valid * order. */ function authorizeOrder( ZoneParameters calldata zoneParameters ) external returns (bytes4 authorizedOrderMagicValue); /** * @dev Validates an order after all token fulfillments for all orders have * been executed by Seaport. * * @param zoneParameters The context about the order fulfillment and any * supplied extraData. * * @return validOrderMagicValue The magic value that indicates a valid * order. */ function validateOrder( ZoneParameters calldata zoneParameters ) external returns (bytes4 validOrderMagicValue); /** * @dev Returns the metadata for this zone. * * @return name The name of the zone. * @return schemas The schemas that the zone implements. */ function getSeaportMetadata() external view returns (string memory name, Schema[] memory schemas); // map to SIP IDs /** * @dev Returns a boolean indicating if a given interface is supported in * accordance with ERC-165. * * @param interfaceId the ERC-165 interface ID. * * @return a boolean indicating whether the interface is supported. */ function supportsInterface( bytes4 interfaceId ) external view override returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title ZoneInteractionErrors * @author 0age * @notice ZoneInteractionErrors contains errors related to zone interaction. */ interface ZoneInteractionErrors { /** * @dev Revert with an error when attempting to fill an order that specifies * a restricted submitter as its order type when not submitted by * either the offerer or the order's zone or approved as valid by the * zone in question via a call to `isValidOrder`. * * @param orderHash The order hash for the invalid restricted order. */ error InvalidRestrictedOrder(bytes32 orderHash); /** * @dev Revert with an error when attempting to fill a contract order that * fails to generate an order successfully, that does not adhere to the * requirements for minimum spent or maximum received supplied by the * fulfiller, or that fails the post-execution `ratifyOrder` check.. * * @param orderHash The order hash for the invalid contract order. */ error InvalidContractOrder(bytes32 orderHash); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { OrderStatus } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { ReferenceAssertions } from "./ReferenceAssertions.sol"; import { ReferenceSignatureVerification } from "./ReferenceSignatureVerification.sol"; /** * @title Verifiers * @author 0age * @notice Verifiers contains functions for performing verifications. */ contract ReferenceVerifiers is ReferenceAssertions, ReferenceSignatureVerification { /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceAssertions(conduitController) {} /** * @dev Internal view function to ensure that the current time falls within * an order's valid timespan. * * @param startTime The time at which the order becomes active. * @param endTime The time at which the order becomes inactive. * @param revertOnInvalid A boolean indicating whether to revert if the * order is not active. * * @return valid A boolean indicating whether the order is active. */ function _verifyTime( uint256 startTime, uint256 endTime, bool revertOnInvalid ) internal view returns (bool valid) { // Revert if order's timespan hasn't started yet or has already ended. if (startTime > block.timestamp || endTime <= block.timestamp) { // Only revert if revertOnInvalid has been supplied as true. if (revertOnInvalid) { revert InvalidTime(startTime, endTime); } // Return false as the order is invalid. return false; } // Return true as the order time is valid. valid = true; } /** * @dev Internal view function to verify the signature of an order. An * ERC-1271 fallback will be attempted if either the signature length * is not 64 or 65 bytes or if the recovered signer does not match the * supplied offerer. Note that in cases where a 64 or 65 byte signature * is supplied, only standard ECDSA signatures that recover to a * non-zero address are supported. * * @param offerer The offerer for the order. * @param orderHash The order hash. * @param signature A signature from the offerer indicating that the order * has been approved. */ function _verifySignature( address offerer, bytes32 orderHash, bytes memory signature ) internal view { // Skip signature verification if the offerer is the caller. if (offerer == msg.sender) { return; } bytes32 domainSeparator = _domainSeparator(); // Derive original EIP-712 digest using domain separator and order hash. bytes32 originalDigest = _deriveEIP712Digest( domainSeparator, orderHash ); bytes32 digest; bytes memory extractedSignature; if (_isValidBulkOrderSize(signature)) { // Rederive order hash and digest using bulk order proof. (orderHash, extractedSignature) = _computeBulkOrderProof( signature, orderHash ); digest = _deriveEIP712Digest(domainSeparator, orderHash); } else { digest = originalDigest; extractedSignature = signature; } // Ensure that the signature for the digest is valid for the offerer. _assertValidSignature( offerer, digest, originalDigest, signature, extractedSignature ); } /** * @dev Determines whether the specified bulk order size is valid. * * @param signature The signature of the bulk order to check. * * @return validLength True if bulk order size is valid, false otherwise. */ function _isValidBulkOrderSize( bytes memory signature ) internal pure returns (bool validLength) { validLength = signature.length < 837 && signature.length > 98 && ((signature.length - 67) % 32) < 2; } /** * @dev Computes the bulk order hash for the specified proof and leaf. Note * that if an index that exceeds the number of orders in the bulk order * payload will instead "wrap around" and refer to an earlier index. * * @param proofAndSignature The proof and signature of the bulk order. * @param leaf The leaf of the bulk order tree. * * @return bulkOrderHash The bulk order hash. * @return signature The signature of the bulk order. */ function _computeBulkOrderProof( bytes memory proofAndSignature, bytes32 leaf ) internal view returns (bytes32 bulkOrderHash, bytes memory signature) { bytes32 root = leaf; // proofAndSignature with odd length is a compact signature (64 bytes). uint256 length = proofAndSignature.length % 2 == 0 ? 65 : 64; // Create a new array of bytes equal to the length of the signature. signature = new bytes(length); // Iterate over each byte in the signature. for (uint256 i = 0; i < length; ++i) { // Assign the byte from the proofAndSignature to the signature. signature[i] = proofAndSignature[i]; } // Compute the key by extracting the next three bytes from the // proofAndSignature. uint256 key = (((uint256(uint8(proofAndSignature[length])) << 16) | ((uint256(uint8(proofAndSignature[length + 1]))) << 8)) | (uint256(uint8(proofAndSignature[length + 2])))); uint256 height = (proofAndSignature.length - length) / 32; // Create an array of bytes32 to hold the proof elements. bytes32[] memory proofElements = new bytes32[](height); // Iterate over each proof element. for (uint256 elementIndex = 0; elementIndex < height; ++elementIndex) { // Compute the starting index for the current proof element. uint256 start = (length + 3) + (elementIndex * 32); // Create a new array of bytes to hold the current proof element. bytes memory buffer = new bytes(32); // Iterate over each byte in the proof element. for (uint256 i = 0; i < 32; ++i) { // Assign the byte from the proofAndSignature to the buffer. buffer[i] = proofAndSignature[start + i]; } // Decode the current proof element from the buffer and assign it to // the proofElements array. proofElements[elementIndex] = abi.decode(buffer, (bytes32)); } // Iterate over each proof element. for (uint256 i = 0; i < proofElements.length; ++i) { // Retrieve the proof element. bytes32 proofElement = proofElements[i]; // Check if the current bit of the key is set. if ((key >> i) % 2 == 0) { // If the current bit is not set, then concatenate the root and // the proof element, and compute the keccak256 hash of the // concatenation to assign it to the root. root = keccak256(abi.encodePacked(root, proofElement)); } else { // If the current bit is set, then concatenate the proof element // and the root, and compute the keccak256 hash of the // concatenation to assign it to the root. root = keccak256(abi.encodePacked(proofElement, root)); } } // Compute the bulk order hash and return it. bulkOrderHash = keccak256( abi.encodePacked(_bulkOrderTypehashes[height], root) ); // Return the signature. return (bulkOrderHash, signature); } /** * @dev Internal view function to validate that a given order is fillable * and not cancelled based on the order status. * * @param orderHash The order hash. * @param orderStatus The status of the order, including whether it has * been cancelled and the fraction filled. * @param onlyAllowUnused A boolean flag indicating whether partial fills * are supported by the calling function. * @param revertOnInvalid A boolean indicating whether to revert if the * order has been cancelled or filled beyond the * allowable amount. * * @return valid A boolean indicating whether the order is valid. */ function _verifyOrderStatus( bytes32 orderHash, OrderStatus storage orderStatus, bool onlyAllowUnused, bool revertOnInvalid ) internal view returns (bool valid) { // Ensure that the order has not been cancelled. if (orderStatus.isCancelled) { // Only revert if revertOnInvalid has been supplied as true. if (revertOnInvalid) { revert OrderIsCancelled(orderHash); } // Return false as the order status is invalid. return false; } // Read order status numerator from storage and place on stack. uint256 orderStatusNumerator = orderStatus.numerator; // If the order is not entirely unused... if (orderStatusNumerator != 0) { // ensure the order has not been partially filled when not allowed. if (onlyAllowUnused) { // Always revert on partial fills when onlyAllowUnused is true. revert OrderPartiallyFilled(orderHash); // Otherwise, ensure that order has not been entirely filled. } else if (orderStatusNumerator >= orderStatus.denominator) { // Only revert if revertOnInvalid has been supplied as true. if (revertOnInvalid) { revert OrderAlreadyFilled(orderHash); } // Return false as the order status is invalid. return false; } } // Return true as the order status is valid. valid = true; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ERC20Interface, ERC721Interface, ERC1155Interface } from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol"; import { TokenTransferrerErrors } from "seaport-types/src/interfaces/TokenTransferrerErrors.sol"; contract ReferenceTokenTransferrer is TokenTransferrerErrors { /** * @dev Internal function to transfer ERC20 tokens from a given originator * to a given recipient. Sufficient approvals must be set on the * contract performing the transfer. * * @param token The ERC20 token to transfer. * @param from The originator of the transfer. * @param to The recipient of the transfer. * @param amount The amount to transfer. */ function _performERC20Transfer( address token, address from, address to, uint256 amount ) internal { // If the provided token is not a contract, revert. if (token.code.length == 0) { revert NoContract(token); } // Attempt to transfer the tokens. (bool ok, bytes memory data) = token.call( abi.encodeWithSelector( ERC20Interface.transferFrom.selector, from, to, amount ) ); // NOTE: revert reasons are not "bubbled up" at the moment if (!ok) { revert TokenTransferGenericFailure(token, from, to, 0, amount); } // If the token does not return a boolean, revert. if (data.length != 0 && data.length >= 32) { if (!abi.decode(data, (bool))) { revert BadReturnValueFromERC20OnTransfer( token, from, to, amount ); } } } /** * @dev Internal function to transfer an ERC721 token from a given * originator to a given recipient. Sufficient approvals must be set on * the contract performing the transfer. * * @param token The ERC721 token to transfer. * @param from The originator of the transfer. * @param to The recipient of the transfer. * @param identifier The tokenId to transfer. */ function _performERC721Transfer( address token, address from, address to, uint256 identifier ) internal { // If the provided token is not a contract, revert. if (token.code.length == 0) { revert NoContract(token); } ERC721Interface(token).transferFrom(from, to, identifier); } /** * @dev Internal function to transfer ERC1155 tokens from a given * originator to a given recipient. Sufficient approvals must be set on * the contract performing the transfer and contract recipients must * implement onReceived to indicate that they are willing to accept the * transfer. * * @param token The ERC1155 token to transfer. * @param from The originator of the transfer. * @param to The recipient of the transfer. * @param identifier The id to transfer. * @param amount The amount to transfer. */ function _performERC1155Transfer( address token, address from, address to, uint256 identifier, uint256 amount ) internal { // If the provided token is not a contract, revert. if (token.code.length == 0) { revert NoContract(token); } ERC1155Interface(token).safeTransferFrom( from, to, identifier, amount, "" ); } /** * @dev Internal function to transfer ERC1155 tokens from a given * originator to a given recipient. Sufficient approvals must be set on * the contract performing the transfer and contract recipients must * implement onReceived to indicate that they are willing to accept the * transfer. * * @param token The ERC1155 token to transfer in batch. * @param from The originator of the transfer batch. * @param to The recipient of the transfer batch. * @param identifiers The ids to transfer. * @param amounts The amounts to transfer. */ function _performERC1155BatchTransfer( address token, address from, address to, uint256[] memory identifiers, uint256[] memory amounts ) internal { // If the provided token is not a contract, revert. if (token.code.length == 0) { revert NoContract(token); } ERC1155Interface(token).safeBatchTransferFrom( from, to, identifiers, amounts, "" ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { OrderParameters } from "seaport-types/src/lib/ConsiderationStructs.sol"; import { ReferenceGettersAndDerivers } from "./ReferenceGettersAndDerivers.sol"; import { TokenTransferrerErrors } from "seaport-types/src/interfaces/TokenTransferrerErrors.sol"; import { ReferenceCounterManager } from "./ReferenceCounterManager.sol"; /** * @title Assertions * @author 0age * @notice Assertions contains logic for making various assertions that do not * fit neatly within a dedicated semantic scope. */ contract ReferenceAssertions is ReferenceGettersAndDerivers, ReferenceCounterManager, TokenTransferrerErrors { /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceGettersAndDerivers(conduitController) {} /** * @dev Internal view function to ensure that the supplied consideration * array length on a given set of order parameters is not less than the * original consideration array length for that order and to retrieve * the current counter for a given order's offerer and zone and use it * to derive the order hash. * * @param orderParameters The parameters of the order to hash. * * @return orderHash The order hash. */ function _assertConsiderationLengthAndGetOrderHash( OrderParameters memory orderParameters ) internal view returns (bytes32 orderHash) { // Ensure supplied consideration array length is not less than original. _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength( orderParameters.consideration.length, orderParameters.totalOriginalConsiderationItems ); // Derive and return order hash using current counter for the offerer. orderHash = _deriveOrderHash( orderParameters, _getCounter(orderParameters.offerer) ); } /** * @dev Internal pure function to ensure that the supplied consideration * array length for an order to be fulfilled is not less than the * original consideration array length for that order. * * @param suppliedConsiderationItemTotal The number of consideration items * supplied when fulfilling the order. * @param originalConsiderationItemTotal The number of consideration items * supplied on initial order creation. */ function _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength( uint256 suppliedConsiderationItemTotal, uint256 originalConsiderationItemTotal ) internal pure { // Ensure supplied consideration array length is not less than original. if (suppliedConsiderationItemTotal < originalConsiderationItemTotal) { revert MissingOriginalConsiderationItems(); } } /** * @dev Internal pure function to ensure that a given item amount in not * zero. * * @param amount The amount to check. */ function _assertNonZeroAmount(uint256 amount) internal pure { if (amount == 0) { revert MissingItemAmount(); } } /** * @dev Internal pure function to validate calldata offsets for dynamic * types in BasicOrderParameters and other parameters. This ensures * that functions using the calldata object normally will be using the * same data as the assembly functions and that values that are bound * to a given range are within that range. Note that no parameters are * supplied as all basic order functions use the same calldata * encoding. */ function _assertValidBasicOrderParameters() internal pure { /* * Checks: * 1. Order parameters struct offset == 0x20 * 2. Additional recipients arr offset == 0x200 * 3. Signature offset == 0x240 + (recipients.length * 0x40) * 4. BasicOrderType between 0 and 23 (i.e. < 24) */ // Declare a boolean designating basic order parameter offset validity. bool validOffsets = (abi.decode(msg.data[4:36], (uint256)) == 32 && abi.decode(msg.data[548:580], (uint256)) == 576 && abi.decode(msg.data[580:612], (uint256)) == 608 + 64 * abi.decode(msg.data[612:644], (uint256))) && abi.decode(msg.data[292:324], (uint256)) < 24; // Revert with an error if basic order parameter offsets are invalid. if (!validOffsets) { revert InvalidBasicOrderParameterEncoding(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { EIP1271Interface } from "seaport-types/src/interfaces/EIP1271Interface.sol"; import { SignatureVerificationErrors } from "seaport-types/src/interfaces/SignatureVerificationErrors.sol"; import { EIP2098_allButHighestBitMask } from "seaport-types/src/lib/ConsiderationConstants.sol"; /** * @title SignatureVerification * @author 0age * @notice SignatureVerification contains logic for verifying signatures. */ contract ReferenceSignatureVerification is SignatureVerificationErrors { /** * @dev Internal view function to verify the signature of an order. An * ERC-1271 fallback will be attempted if either the signature length * is not 64 or 65 bytes or if the recovered signer does not match the * supplied signer. Note that in cases where a 64 or 65 byte signature * is supplied, only standard ECDSA signatures that recover to a * non-zero address are supported. * * @param signer The signer for the order. * @param digest The digest to verify signature against. * @param originalDigest The original digest to verify signature against. * @param originalSignature The original signature. * @param signature A signature from the signer indicating that the * order has been approved. */ function _assertValidSignature( address signer, bytes32 digest, bytes32 originalDigest, bytes memory originalSignature, bytes memory signature ) internal view { // Declare r, s, and v signature parameters. bytes32 r; bytes32 s; uint8 v; if (signer.code.length > 0) { // If signer is a contract, try verification via EIP-1271. _assertValidEIP1271Signature( signer, originalDigest, originalSignature ); // Return early if the ERC-1271 signature check succeeded. return; } else if (signature.length == 64) { // If signature contains 64 bytes, parse as EIP-2098 sig. (r+s&v) // Declare temporary vs that will be decomposed into s and v. bytes32 vs; // Decode signature into r, vs. (r, vs) = abi.decode(signature, (bytes32, bytes32)); // Decompose vs into s and v. s = vs & EIP2098_allButHighestBitMask; // If the highest bit is set, v = 28, otherwise v = 27. v = uint8(uint256(vs >> 255)) + 27; } else if (signature.length == 65) { (r, s) = abi.decode(signature, (bytes32, bytes32)); v = uint8(signature[64]); // Ensure v value is properly formatted. if (v != 27 && v != 28) { revert BadSignatureV(v); } } else { revert InvalidSignature(); } // Attempt to recover signer using the digest and signature parameters. address recoveredSigner = ecrecover(digest, v, r, s); // Disallow invalid signers. if (recoveredSigner == address(0) || recoveredSigner != signer) { revert InvalidSigner(); // Should a signer be recovered, but it doesn't match the signer... } } /** * @dev Internal view function to verify the signature of an order using * ERC-1271 (i.e. contract signatures via `isValidSignature`). * * @param signer The signer for the order. * @param digest The signature digest, derived from the domain separator * and the order hash. * @param signature A signature (or other data) used to validate the digest. */ function _assertValidEIP1271Signature( address signer, bytes32 digest, bytes memory signature ) internal view { if ( EIP1271Interface(signer).isValidSignature(digest, signature) != EIP1271Interface.isValidSignature.selector ) { revert BadContractSignature(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title ERC20Interface * @notice Contains the minimum interfaces needed to interact with ERC20s. */ interface ERC20Interface { /** * @dev Allows an operator to transfer tokens on behalf of an owner. * * @param from The address of the owner. * @param to The address of the recipient. * @param value The amount of tokens to transfer. * * @return success True if the transfer was successful. */ function transferFrom( address from, address to, uint256 value ) external returns (bool success); /** * @dev Allows an operator to approve a spender to transfer tokens on behalf * of a user. * * @param spender The address of the spender. * @param value The amount of tokens to approve. * * @return success True if the approval was successful. */ function approve( address spender, uint256 value ) external returns (bool success); /** * @dev Returns the balance of a user. * * @param account The address of the user. * * @return balance The balance of the user. */ function balanceOf(address account) external view returns (uint256); /** * @dev Returns the amount which spender is still allowed to withdraw * from owner. * * @param owner The address of the owner. * @param spender The address of the spender. * * @return remaining The amount of tokens that the spender is allowed to * transfer on behalf of the owner. */ function allowance( address owner, address spender ) external view returns (uint256 remaining); } /** * @title ERC721Interface * @notice Contains the minimum interfaces needed to interact with ERC721s. */ interface ERC721Interface { /** * @dev Allows an operator to transfer tokens on behalf of an owner. * * @param from The address of the owner. * @param to The address of the recipient. * @param tokenId The ID of the token to transfer. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Allows an owner to approve an operator to transfer all tokens on a * contract on behalf of the owner. * * @param to The address of the operator. * @param approved Whether the operator is approved. */ function setApprovalForAll(address to, bool approved) external; /** * @dev Returns the account approved for tokenId token * * @param tokenId The tokenId to query the approval of. * * @return operator The approved account of the tokenId. */ function getApproved( uint256 tokenId ) external view returns (address operator); /** * @dev Returns whether an operator is allowed to manage all of * the assets of owner. * * @param owner The address of the owner. * @param operator The address of the operator. * * @return approved True if the operator is approved by the owner. */ function isApprovedForAll( address owner, address operator ) external view returns (bool); /** * @dev Returns the owner of a given token ID. * * @param tokenId The token ID. * * @return owner The owner of the token. */ function ownerOf(uint256 tokenId) external view returns (address owner); } /** * @title ERC1155Interface * @notice Contains the minimum interfaces needed to interact with ERC1155s. */ interface ERC1155Interface { /** * @dev Allows an operator to transfer tokens on behalf of an owner. * * @param from The address of the owner. * @param to The address of the recipient. * @param id The ID of the token(s) to transfer. * @param amount The amount of tokens to transfer. * @param data Additional data. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev Allows an operator to transfer tokens on behalf of an owner. * * @param from The address of the owner. * @param to The address of the recipient. * @param ids The IDs of the token(s) to transfer. * @param amounts The amounts of tokens to transfer. * @param data Additional data. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; /** * @dev Allows an owner to approve an operator to transfer all tokens on a * contract on behalf of the owner. * * @param to The address of the operator. * @param approved Whether the operator is approved. */ function setApprovalForAll(address to, bool approved) external; /** * @dev Returns the amount of token type id owned by account. * * @param account The address of the account. * @param id The id of the token. * * @return balance The amount of tokens of type id owned by account. */ function balanceOf( address account, uint256 id ) external view returns (uint256); /** * @dev Returns true if operator is approved to transfer account's tokens. * * @param account The address of the account. * @param operator The address of the operator. * * @return approved True if the operator is approved to transfer account's * tokens. */ function isApprovedForAll( address account, address operator ) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {ConsiderationItem, OfferItem, OrderParameters} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {ReferenceConsiderationBase} from "./ReferenceConsiderationBase.sol"; /** * @title GettersAndDerivers * @author 0age * @notice ConsiderationInternal contains pure and internal view functions * related to getting or deriving various values. */ contract ReferenceGettersAndDerivers is ReferenceConsiderationBase { /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or proxies * that may optionally be used to transfer approved * ERC20/721/1155 tokens. */ constructor( address conduitController ) ReferenceConsiderationBase(conduitController) {} /** * @dev Internal view function to derive the EIP-712 hash for an offer item. * * @param offerItem The offered item to hash. * * @return The hash. */ function _hashOfferItem( OfferItem memory offerItem ) internal view returns (bytes32) { return keccak256( abi.encode( _OFFER_ITEM_TYPEHASH, offerItem.itemType, offerItem.token, offerItem.identifierOrCriteria, offerItem.startAmount, offerItem.endAmount ) ); } /** * @dev Internal view function to derive the EIP-712 hash for a * consideration item. * * @param considerationItem The consideration item to hash. * * @return The hash. */ function _hashConsiderationItem( ConsiderationItem memory considerationItem ) internal view returns (bytes32) { return keccak256( abi.encode( _CONSIDERATION_ITEM_TYPEHASH, considerationItem.itemType, considerationItem.token, considerationItem.identifierOrCriteria, considerationItem.startAmount, considerationItem.endAmount, considerationItem.recipient ) ); } /** * @dev Internal view function to derive the order hash for a given order. * Note that only the original consideration items are included in the * order hash, as additional consideration items may be supplied by the * caller. * * @param orderParameters The parameters of the order to hash. * @param counter The counter of the order to hash. * * @return orderHash The hash. */ function _deriveOrderHash( OrderParameters memory orderParameters, uint256 counter ) internal view returns (bytes32 orderHash) { // Designate new memory regions for offer and consideration item hashes. bytes32[] memory offerHashes = new bytes32[]( orderParameters.offer.length ); bytes32[] memory considerationHashes = new bytes32[]( orderParameters.totalOriginalConsiderationItems ); // Iterate over each offer on the order. for (uint256 i = 0; i < orderParameters.offer.length; ++i) { // Hash the offer and place the result into memory. offerHashes[i] = _hashOfferItem(orderParameters.offer[i]); } // Iterate over each consideration on the order. for ( uint256 i = 0; i < orderParameters.totalOriginalConsiderationItems; ++i ) { // Hash the consideration and place the result into memory. considerationHashes[i] = _hashConsiderationItem( orderParameters.consideration[i] ); } // Derive and return the order hash as specified by EIP-712. return keccak256( abi.encode( _ORDER_TYPEHASH, orderParameters.offerer, orderParameters.zone, keccak256(abi.encodePacked(offerHashes)), keccak256(abi.encodePacked(considerationHashes)), orderParameters.orderType, orderParameters.startTime, orderParameters.endTime, orderParameters.zoneHash, orderParameters.salt, orderParameters.conduitKey, counter ) ); } /** * @dev Internal pure function to efficiently derive an digest to sign for * an order in accordance with EIP-712. * * @param domainSeparator The domain separator. * @param orderHash The order hash. * * @return value The hash. */ function _deriveEIP712Digest( bytes32 domainSeparator, bytes32 orderHash ) internal pure returns (bytes32 value) { value = keccak256( abi.encodePacked(uint16(0x1901), domainSeparator, orderHash) ); } /** * @dev Internal view function to derive the address of a given conduit * using a corresponding conduit key. * * @param conduitKey A bytes32 value indicating what corresponding conduit, * if any, to source token approvals from. This value is * the "salt" parameter supplied by the deployer (i.e. the * conduit controller) when deploying the given conduit. * * @return conduit The address of the conduit associated with the given * conduit key. */ function _deriveConduit( bytes32 conduitKey ) internal view returns (address conduit) { // Derive the conduit address bytes32 hash = keccak256( bytes.concat( keccak256("zksyncCreate2"), bytes32(uint256(uint160(address(_CONDUIT_CONTROLLER)))), conduitKey, _CONDUIT_RUNTIME_CODE_HASH, keccak256("") ) ); conduit = address(uint160(uint256(hash))); } /** * @dev Internal view function to get the EIP-712 domain separator. If the * chainId matches the chainId set on deployment, the cached domain * separator will be returned; otherwise, it will be derived from * scratch. */ function _domainSeparator() internal view returns (bytes32) { return block.chainid == _CHAIN_ID ? _DOMAIN_SEPARATOR : _deriveDomainSeparator( _EIP_712_DOMAIN_TYPEHASH, _NAME_HASH, _VERSION_HASH ); } /** * @notice Retrieve configuration information for this contract. * * @return version The contract version. * @return domainSeparator The domain separator for this contract. * @return conduitController The conduit Controller set for this contract. */ function _information() internal view returns ( string memory version, bytes32 domainSeparator, address conduitController ) { version = _VERSION; domainSeparator = _domainSeparator(); conduitController = address(_CONDUIT_CONTROLLER); } /** * @notice Retrieve the name of this contract. * * @return The name of this contract. */ function _name() internal pure returns (string memory) { // Return the name of the contract. return _NAME; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ConsiderationEventsAndErrors } from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol"; import { ReferenceReentrancyGuard } from "./ReferenceReentrancyGuard.sol"; /** * @title CounterManager * @author 0age * @notice CounterManager contains a storage mapping and related functionality * for retrieving and incrementing a per-offerer counter. */ contract ReferenceCounterManager is ConsiderationEventsAndErrors, ReferenceReentrancyGuard { // Only orders signed using an offerer's current counter are fulfillable. mapping(address => uint256) private _counters; /** * @dev Internal function to cancel all orders from a given offerer in bulk * by incrementing a counter. Note that only the offerer may increment * the counter. Note that the counter is incremented by a large, * quasi-random interval, which makes it infeasible to "activate" * signed orders by incrementing the counter. This activation * functionality can be achieved instead with restricted orders or * contract orders. * * @return newCounter The new counter. */ function _incrementCounter() internal returns (uint256 newCounter) { // Use second half of the previous block hash as a quasi-random number. uint256 quasiRandomNumber = uint256(blockhash(block.number - 1)) >> 128; // Retrieve the original counter value. uint256 originalCounter = _counters[msg.sender]; // Increment current counter for the supplied offerer. newCounter = quasiRandomNumber + originalCounter; // Update the counter with the new value. _counters[msg.sender] = newCounter; // Emit an event containing the new counter. emit CounterIncremented(newCounter, msg.sender); } /** * @dev Internal view function to retrieve the current counter for a given * offerer. * * @param offerer The offerer in question. * * @return currentCounter The current counter. */ function _getCounter( address offerer ) internal view returns (uint256 currentCounter) { // Return the counter for the supplied offerer. currentCounter = _counters[offerer]; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title SignatureVerificationErrors * @author 0age * @notice SignatureVerificationErrors contains all errors related to signature * verification. */ interface SignatureVerificationErrors { /** * @dev Revert with an error when a signature that does not contain a v * value of 27 or 28 has been supplied. * * @param v The invalid v value. */ error BadSignatureV(uint8 v); /** * @dev Revert with an error when the signer recovered by the supplied * signature does not match the offerer or an allowed EIP-1271 signer * as specified by the offerer in the event they are a contract. */ error InvalidSigner(); /** * @dev Revert with an error when a signer cannot be recovered from the * supplied signature. */ error InvalidSignature(); /** * @dev Revert with an error when an EIP-1271 call to an account fails. */ error BadContractSignature(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title EIP1271Interface * @notice Interface for the EIP-1271 standard signature validation method for * contracts. */ interface EIP1271Interface { /** * @dev Validates a smart contract signature * * @param digest bytes32 The digest of the data to be signed. * @param signature bytes The signature of the data to be validated. * * @return bytes4 The magic value, if the signature is valid. */ function isValidSignature( bytes32 digest, bytes calldata signature ) external view returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /* * -------------------------- Disambiguation & Other Notes --------------------- * - The term "head" is used as it is in the documentation for ABI encoding, * but only in reference to dynamic types, i.e. it always refers to the * offset or pointer to the body of a dynamic type. In calldata, the head * is always an offset (relative to the parent object), while in memory, * the head is always the pointer to the body. More information found here: * https://docs.soliditylang.org/en/v0.8.17/abi-spec.html#argument-encoding * - Note that the length of an array is separate from and precedes the * head of the array. * * - The term "body" is used in place of the term "head" used in the ABI * documentation. It refers to the start of the data for a dynamic type, * e.g. the first word of a struct or the first word of the first element * in an array. * * - The term "pointer" is used to describe the absolute position of a value * and never an offset relative to another value. * - The suffix "_ptr" refers to a memory pointer. * - The suffix "_cdPtr" refers to a calldata pointer. * * - The term "offset" is used to describe the position of a value relative * to some parent value. For example, OrderParameters_conduit_offset is the * offset to the "conduit" value in the OrderParameters struct relative to * the start of the body. * - Note: Offsets are used to derive pointers. * * - Some structs have pointers defined for all of their fields in this file. * Lines which are commented out are fields that are not used in the * codebase but have been left in for readability. */ // Declare constants for name, version, and reentrancy sentinel values. // Name is right padded, so it touches the length which is left padded. This // enables writing both values at once. Length goes at byte 95 in memory, and // name fills bytes 96-109, so both values can be written left-padded to 77. uint256 constant NameLengthPtr = 0x4D; uint256 constant NameWithLength = 0x0d436F6E73696465726174696F6E; uint256 constant information_version_offset = 0; uint256 constant information_version_cd_offset = 0x60; uint256 constant information_domainSeparator_offset = 0x20; uint256 constant information_conduitController_offset = 0x40; uint256 constant information_versionLengthPtr = 0x63; uint256 constant information_versionWithLength = 0x03312e36; // 1.6 uint256 constant information_length = 0xa0; // uint256(uint32(bytes4(keccak256("_REENTRANCY_GUARD_SLOT")))) uint256 constant _REENTRANCY_GUARD_SLOT = 0x929eee14; /* * * --------------------------------------------------------------------------+ * Opcode | Mnemonic | Stack | Memory | * --------------------------------------------------------------------------| * 60 0x02 | PUSH1 0x02 | 0x02 | | * 60 0x1e | PUSH1 0x1e | 0x1e 0x02 | | * 61 0x3d5c | PUSH2 0x3d5c | 0x3d5c 0x1e 0x02 | | * 3d | RETURNDATASIZE | 0 0x3d5c 0x1e 0x02 | | * | * ::: store deployed bytecode in memory: (3d) RETURNDATASIZE (5c) TLOAD ::: | * 52 | MSTORE | 0x1e 0x02 | [0..0x20): 0x3d5c | * f3 | RETURN | | [0..0x20): 0x3d5c | * --------------------------------------------------------------------------+ */ uint256 constant _TLOAD_TEST_PAYLOAD = 0x6002_601e_613d5c_3d_52_f3; uint256 constant _TLOAD_TEST_PAYLOAD_LENGTH = 0x0a; uint256 constant _TLOAD_TEST_PAYLOAD_OFFSET = 0x16; uint256 constant _NOT_ENTERED_TSTORE = 0; uint256 constant _ENTERED_TSTORE = 1; uint256 constant _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_TSTORE = 2; uint256 constant _TSTORE_ENABLED_SSTORE = 0; uint256 constant _NOT_ENTERED_SSTORE = 1; uint256 constant _ENTERED_SSTORE = 2; uint256 constant _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE = 3; uint256 constant Offset_fulfillAdvancedOrder_criteriaResolvers = 0x20; uint256 constant Offset_fulfillAvailableOrders_offerFulfillments = 0x20; uint256 constant Offset_fulfillAvailableOrders_considerationFulfillments = 0x40; uint256 constant Offset_fulfillAvailableAdvancedOrders_criteriaResolvers = 0x20; uint256 constant Offset_fulfillAvailableAdvancedOrders_offerFulfillments = 0x40; uint256 constant Offset_fulfillAvailableAdvancedOrders_cnsdrationFlflmnts = (0x60); uint256 constant Offset_matchOrders_fulfillments = 0x20; uint256 constant Offset_matchAdvancedOrders_criteriaResolvers = 0x20; uint256 constant Offset_matchAdvancedOrders_fulfillments = 0x40; // Common Offsets // Offsets for identically positioned fields shared by: // OfferItem, ConsiderationItem, SpentItem, ReceivedItem uint256 constant Selector_length = 0x4; uint256 constant Common_token_offset = 0x20; uint256 constant Common_identifier_offset = 0x40; uint256 constant Common_amount_offset = 0x60; uint256 constant Common_endAmount_offset = 0x80; uint256 constant SpentItem_size = 0x80; uint256 constant SpentItem_size_shift = 0x7; uint256 constant OfferItem_size = 0xa0; uint256 constant OfferItem_size_with_head_pointer = 0xc0; uint256 constant ReceivedItem_size_excluding_recipient = 0x80; uint256 constant ReceivedItem_size = 0xa0; uint256 constant ReceivedItem_amount_offset = 0x60; uint256 constant ReceivedItem_recipient_offset = 0x80; uint256 constant ReceivedItem_CommonParams_size = 0x60; uint256 constant ConsiderationItem_size = 0xc0; uint256 constant ConsiderationItem_size_with_head_pointer = 0xe0; uint256 constant ConsiderationItem_recipient_offset = 0xa0; // Store the same constant in an abbreviated format for a line length fix. uint256 constant ConsiderItem_recipient_offset = 0xa0; uint256 constant Execution_offerer_offset = 0x20; uint256 constant Execution_conduit_offset = 0x40; // uint256 constant OrderParameters_offerer_offset = 0x00; uint256 constant OrderParameters_zone_offset = 0x20; uint256 constant OrderParameters_offer_head_offset = 0x40; uint256 constant OrderParameters_consideration_head_offset = 0x60; // uint256 constant OrderParameters_orderType_offset = 0x80; uint256 constant OrderParameters_startTime_offset = 0xa0; uint256 constant OrderParameters_endTime_offset = 0xc0; uint256 constant OrderParameters_zoneHash_offset = 0xe0; uint256 constant OrderParameters_salt_offset = 0x100; uint256 constant OrderParameters_conduit_offset = 0x120; uint256 constant OrderParameters_counter_offset = 0x140; uint256 constant Fulfillment_itemIndex_offset = 0x20; uint256 constant AdvancedOrder_head_size = 0xa0; uint256 constant AdvancedOrder_numerator_offset = 0x20; uint256 constant AdvancedOrder_denominator_offset = 0x40; uint256 constant AdvancedOrder_signature_offset = 0x60; uint256 constant AdvancedOrder_extraData_offset = 0x80; uint256 constant OrderStatus_ValidatedAndNotCancelled = 1; uint256 constant OrderStatus_filledNumerator_offset = 0x10; uint256 constant OrderStatus_filledDenominator_offset = 0x88; uint256 constant OrderStatus_ValidatedAndNotCancelledAndFullyFilled = ( 0x0000000000000000000000000000010000000000000000000000000000010001 ); uint256 constant ThirtyOneBytes = 0x1f; uint256 constant OneWord = 0x20; uint256 constant TwoWords = 0x40; uint256 constant ThreeWords = 0x60; uint256 constant FourWords = 0x80; uint256 constant FiveWords = 0xa0; uint256 constant OneWordShift = 0x5; uint256 constant TwoWordsShift = 0x6; uint256 constant SixtyThreeBytes = 0x3f; uint256 constant OnlyFullWordMask = 0xffffffe0; uint256 constant FreeMemoryPointerSlot = 0x40; uint256 constant ZeroSlot = 0x60; uint256 constant DefaultFreeMemoryPointer = 0x80; uint256 constant Slot0x80 = 0x80; uint256 constant Slot0xA0 = 0xa0; uint256 constant BasicOrder_common_params_size = 0xa0; uint256 constant BasicOrder_considerationHashesArray_ptr = 0x160; uint256 constant BasicOrder_receivedItemByteMap = (0x0000010102030000000000000000000000000000000000000000000000000000); uint256 constant BasicOrder_offeredItemByteMap = (0x0203020301010000000000000000000000000000000000000000000000000000); uint256 constant BasicOrder_consideration_offset_from_offer = 0xa0; bytes32 constant OrdersMatchedTopic0 = (0x4b9f2d36e1b4c93de62cc077b00b1a91d84b6c31b4a14e012718dcca230689e7); uint256 constant EIP712_Order_size = 0x180; uint256 constant EIP712_OfferItem_size = 0xc0; uint256 constant EIP712_ConsiderationItem_size = 0xe0; uint256 constant AdditionalRecipient_size = 0x40; uint256 constant AdditionalRecipient_size_shift = 0x6; uint256 constant EIP712_DomainSeparator_offset = 0x02; uint256 constant EIP712_OrderHash_offset = 0x22; uint256 constant EIP712_DigestPayload_size = 0x42; uint256 constant EIP712_domainData_nameHash_offset = 0x20; uint256 constant EIP712_domainData_versionHash_offset = 0x40; uint256 constant EIP712_domainData_chainId_offset = 0x60; uint256 constant EIP712_domainData_verifyingContract_offset = 0x80; uint256 constant EIP712_domainData_size = 0xa0; // Minimum BulkOrder proof size: 64 bytes for signature + 3 for key + 32 for 1 // sibling. Maximum BulkOrder proof size: 65 bytes for signature + 3 for key + // 768 for 24 siblings. uint256 constant BulkOrderProof_minSize = 0x63; uint256 constant BulkOrderProof_rangeSize = 0x2e2; uint256 constant BulkOrderProof_lengthAdjustmentBeforeMask = 0x1d; uint256 constant BulkOrderProof_lengthRangeAfterMask = 0x2; uint256 constant BulkOrderProof_keyShift = 0xe8; uint256 constant BulkOrderProof_keySize = 0x3; uint256 constant BulkOrder_Typehash_Height_One = (0x3ca2711d29384747a8f61d60aad3c450405f7aaff5613541dee28df2d6986d32); uint256 constant BulkOrder_Typehash_Height_Two = (0xbf8e29b89f29ed9b529c154a63038ffca562f8d7cd1e2545dda53a1b582dde30); uint256 constant BulkOrder_Typehash_Height_Three = (0x53c6f6856e13104584dd0797ca2b2779202dc2597c6066a42e0d8fe990b0024d); uint256 constant BulkOrder_Typehash_Height_Four = (0xa02eb7ff164c884e5e2c336dc85f81c6a93329d8e9adf214b32729b894de2af1); uint256 constant BulkOrder_Typehash_Height_Five = (0x39c9d33c18e050dda0aeb9a8086fb16fc12d5d64536780e1da7405a800b0b9f6); uint256 constant BulkOrder_Typehash_Height_Six = (0x1c19f71958cdd8f081b4c31f7caf5c010b29d12950be2fa1c95070dc47e30b55); uint256 constant BulkOrder_Typehash_Height_Seven = (0xca74fab2fece9a1d58234a274220ad05ca096a92ef6a1ca1750b9d90c948955c); uint256 constant BulkOrder_Typehash_Height_Eight = (0x7ff98d9d4e55d876c5cfac10b43c04039522f3ddfb0ea9bfe70c68cfb5c7cc14); uint256 constant BulkOrder_Typehash_Height_Nine = (0xbed7be92d41c56f9e59ac7a6272185299b815ddfabc3f25deb51fe55fe2f9e8a); uint256 constant BulkOrder_Typehash_Height_Ten = (0xd1d97d1ef5eaa37a4ee5fbf234e6f6d64eb511eb562221cd7edfbdde0848da05); uint256 constant BulkOrder_Typehash_Height_Eleven = (0x896c3f349c4da741c19b37fec49ed2e44d738e775a21d9c9860a69d67a3dae53); uint256 constant BulkOrder_Typehash_Height_Twelve = (0xbb98d87cc12922b83759626c5f07d72266da9702d19ffad6a514c73a89002f5f); uint256 constant BulkOrder_Typehash_Height_Thirteen = (0xe6ae19322608dd1f8a8d56aab48ed9c28be489b689f4b6c91268563efc85f20e); uint256 constant BulkOrder_Typehash_Height_Fourteen = (0x6b5b04cbae4fcb1a9d78e7b2dfc51a36933d023cf6e347e03d517b472a852590); uint256 constant BulkOrder_Typehash_Height_Fifteen = (0xd1eb68309202b7106b891e109739dbbd334a1817fe5d6202c939e75cf5e35ca9); uint256 constant BulkOrder_Typehash_Height_Sixteen = (0x1da3eed3ecef6ebaa6e5023c057ec2c75150693fd0dac5c90f4a142f9879fde8); uint256 constant BulkOrder_Typehash_Height_Seventeen = (0xeee9a1392aa395c7002308119a58f2582777a75e54e0c1d5d5437bd2e8bf6222); uint256 constant BulkOrder_Typehash_Height_Eighteen = (0xc3939feff011e53ab8c35ca3370aad54c5df1fc2938cd62543174fa6e7d85877); uint256 constant BulkOrder_Typehash_Height_Nineteen = (0x0efca7572ac20f5ae84db0e2940674f7eca0a4726fa1060ffc2d18cef54b203d); uint256 constant BulkOrder_Typehash_Height_Twenty = (0x5a4f867d3d458dabecad65f6201ceeaba0096df2d0c491cc32e6ea4e64350017); uint256 constant BulkOrder_Typehash_Height_TwentyOne = (0x80987079d291feebf21c2230e69add0f283cee0b8be492ca8050b4185a2ff719); uint256 constant BulkOrder_Typehash_Height_TwentyTwo = (0x3bd8cff538aba49a9c374c806d277181e9651624b3e31111bc0624574f8bca1d); uint256 constant BulkOrder_Typehash_Height_TwentyThree = (0x5d6a3f098a0bc373f808c619b1bb4028208721b3c4f8d6bc8a874d659814eb76); uint256 constant BulkOrder_Typehash_Height_TwentyFour = (0x1d51df90cba8de7637ca3e8fe1e3511d1dc2f23487d05dbdecb781860c21ac1c); uint256 constant receivedItemsHash_ptr = 0x60; /* * Memory layout in _prepareBasicFulfillmentFromCalldata of * data for OrderFulfilled * * event OrderFulfilled( * bytes32 orderHash, * address indexed offerer, * address indexed zone, * address fulfiller, * SpentItem[] offer, * > (itemType, token, id, amount) * ReceivedItem[] consideration * > (itemType, token, id, amount, recipient) * ) * * - 0x00: orderHash * - 0x20: fulfiller * - 0x40: offer offset (0x80) * - 0x60: consideration offset (0x120) * - 0x80: offer.length (1) * - 0xa0: offerItemType * - 0xc0: offerToken * - 0xe0: offerIdentifier * - 0x100: offerAmount * - 0x120: consideration.length (1 + additionalRecipients.length) * - 0x140: considerationItemType * - 0x160: considerationToken * - 0x180: considerationIdentifier * - 0x1a0: considerationAmount * - 0x1c0: considerationRecipient * - ... */ // Minimum length of the OrderFulfilled event data. // Must be added to the size of the ReceivedItem array for additionalRecipients // (0xa0 * additionalRecipients.length) to calculate full size of the buffer. uint256 constant OrderFulfilled_baseSize = 0x1e0; uint256 constant OrderFulfilled_selector = (0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31); // Minimum offset in memory to OrderFulfilled event data. // Must be added to the size of the EIP712 hash array for additionalRecipients // (32 * additionalRecipients.length) to calculate the pointer to event data. uint256 constant OrderFulfilled_baseOffset = 0x180; uint256 constant OrderFulfilled_consideration_length_baseOffset = 0x2a0; uint256 constant OrderFulfilled_offer_length_baseOffset = 0x200; uint256 constant OrderFulfilled_offer_length_offset_relativeTo_baseOffset = ( 0x80 ); uint256 constant OrderFulfilled_offer_itemType_offset_relativeTo_baseOffset = ( 0xa0 ); uint256 constant OrderFulfilled_offer_token_offset_relativeTo_baseOffset = 0xc0; // Related constants used for restricted order checks on basic orders. uint256 constant OrderFulfilled_baseDataSize = 0x160; // uint256 constant ValidateOrder_offerDataOffset = 0x184; // uint256 constant RatifyOrder_offerDataOffset = 0xc4; // uint256 constant OrderFulfilled_orderHash_offset = 0x00; uint256 constant OrderFulfilled_fulfiller_offset = 0x20; uint256 constant OrderFulfilled_offer_head_offset = 0x40; uint256 constant OrderFulfilled_offer_body_offset = 0x80; uint256 constant OrderFulfilled_consideration_head_offset = 0x60; uint256 constant OrderFulfilled_consideration_body_offset = 0x120; /* * 3 memory slots/words for `authorizeOrder` and `validateOrder` calldata * to be used for tails of extra data (length 0) and order hashes (length 1) */ uint256 constant OrderFulfilled_post_memory_region_reservedBytes = 0x60; /* * OrderFulfilled_offer_length_baseOffset - 12 * 0x20 * we back up 12 words from where the `OrderFulfilled`'s data * for spent items start to be rewritten for `authorizeOrder` * and `validateOrder`. Let the reference pointer be `ptr` * pointing to the `OrderFulfilled`'s spent item array's length memory * position then we would have: * * ptr - 0x0180 : zero-padded calldata selector * ptr - 0x0160 : ZoneParameter's struct head (0x20) * ptr - 0x0140 : order hash * ptr - 0x0120 : fulfiller (msg.sender) * ptr - 0x0100 : offerer * ptr - 0x00e0 : spent items' head * ptr - 0x00c0 : received items' head * ptr - 0x00a0 : extra data / context head * ptr - 0x0080 : order hashes head * ptr - 0x0060 : start time * ptr - 0x0040 : end time * ptr - 0x0020 : zone hash * ptr - 0x0000 : offer.length (1) * ... * * Note that the padded calldata selector will be at minimum at the * 0x80 memory slot. */ uint256 constant authorizeOrder_calldata_baseOffset = ( OrderFulfilled_offer_length_baseOffset - 0x180 ); // BasicOrderParameters uint256 constant BasicOrder_parameters_cdPtr = 0x04; uint256 constant BasicOrder_considerationToken_cdPtr = 0x24; uint256 constant BasicOrder_considerationIdentifier_cdPtr = 0x44; uint256 constant BasicOrder_considerationAmount_cdPtr = 0x64; uint256 constant BasicOrder_offerer_cdPtr = 0x84; uint256 constant BasicOrder_zone_cdPtr = 0xa4; uint256 constant BasicOrder_offerToken_cdPtr = 0xc4; uint256 constant BasicOrder_offerIdentifier_cdPtr = 0xe4; uint256 constant BasicOrder_offerAmount_cdPtr = 0x104; uint256 constant BasicOrder_basicOrderParameters_cd_offset = 0x24; uint256 constant BasicOrder_basicOrderType_cdPtr = 0x124; uint256 constant BasicOrder_startTime_cdPtr = 0x144; uint256 constant BasicOrder_endTime_cdPtr = 0x164; // uint256 constant BasicOrder_zoneHash_cdPtr = 0x184; // uint256 constant BasicOrder_salt_cdPtr = 0x1a4; uint256 constant BasicOrder_offererConduit_cdPtr = 0x1c4; uint256 constant BasicOrder_fulfillerConduit_cdPtr = 0x1e4; uint256 constant BasicOrder_totalOriginalAdditionalRecipients_cdPtr = 0x204; uint256 constant BasicOrder_additionalRecipients_head_cdPtr = 0x224; uint256 constant BasicOrder_signature_cdPtr = 0x244; uint256 constant BasicOrder_additionalRecipients_length_cdPtr = 0x264; uint256 constant BasicOrder_addlRecipients_length_cdPtr = 0x264; uint256 constant BasicOrder_additionalRecipients_data_cdPtr = 0x284; uint256 constant BasicOrder_parameters_ptr = 0x20; uint256 constant BasicOrder_basicOrderType_range = 0x18; // 24 values /* * Memory layout in _prepareBasicFulfillmentFromCalldata of * EIP712 data for ConsiderationItem * - 0x80: ConsiderationItem EIP-712 typehash (constant) * - 0xa0: itemType * - 0xc0: token * - 0xe0: identifier * - 0x100: startAmount * - 0x120: endAmount * - 0x140: recipient */ uint256 constant BasicOrder_considerationItem_typeHash_ptr = 0x80; // memoryPtr uint256 constant BasicOrder_considerationItem_itemType_ptr = 0xa0; uint256 constant BasicOrder_considerationItem_token_ptr = 0xc0; uint256 constant BasicOrder_considerationItem_identifier_ptr = 0xe0; uint256 constant BasicOrder_considerationItem_startAmount_ptr = 0x100; uint256 constant BasicOrder_considerationItem_endAmount_ptr = 0x120; // uint256 constant BasicOrder_considerationItem_recipient_ptr = 0x140; /* * Memory layout in _prepareBasicFulfillmentFromCalldata of * EIP712 data for OfferItem * - 0x80: OfferItem EIP-712 typehash (constant) * - 0xa0: itemType * - 0xc0: token * - 0xe0: identifier (reused for offeredItemsHash) * - 0x100: startAmount * - 0x120: endAmount */ uint256 constant BasicOrder_offerItem_typeHash_ptr = 0x80; uint256 constant BasicOrder_offerItem_itemType_ptr = 0xa0; uint256 constant BasicOrder_offerItem_token_ptr = 0xc0; // uint256 constant BasicOrder_offerItem_identifier_ptr = 0xe0; // uint256 constant BasicOrder_offerItem_startAmount_ptr = 0x100; uint256 constant BasicOrder_offerItem_endAmount_ptr = 0x120; /* * Memory layout in _prepareBasicFulfillmentFromCalldata of * EIP712 data for Order * - 0x80: Order EIP-712 typehash (constant) * - 0xa0: orderParameters.offerer * - 0xc0: orderParameters.zone * - 0xe0: keccak256(abi.encodePacked(offerHashes)) * - 0x100: keccak256(abi.encodePacked(considerationHashes)) * - 0x120: orderType * - 0x140: startTime * - 0x160: endTime * - 0x180: zoneHash * - 0x1a0: salt * - 0x1c0: conduit * - 0x1e0: _counters[orderParameters.offerer] (from storage) */ uint256 constant BasicOrder_order_typeHash_ptr = 0x80; uint256 constant BasicOrder_order_offerer_ptr = 0xa0; // uint256 constant BasicOrder_order_zone_ptr = 0xc0; uint256 constant BasicOrder_order_offerHashes_ptr = 0xe0; uint256 constant BasicOrder_order_considerationHashes_ptr = 0x100; uint256 constant BasicOrder_order_orderType_ptr = 0x120; uint256 constant BasicOrder_order_startTime_ptr = 0x140; // uint256 constant BasicOrder_order_endTime_ptr = 0x160; // uint256 constant BasicOrder_order_zoneHash_ptr = 0x180; // uint256 constant BasicOrder_order_salt_ptr = 0x1a0; // uint256 constant BasicOrder_order_conduitKey_ptr = 0x1c0; uint256 constant BasicOrder_order_counter_ptr = 0x1e0; uint256 constant BasicOrder_additionalRecipients_head_ptr = 0x240; uint256 constant BasicOrder_signature_ptr = 0x260; uint256 constant BasicOrder_startTimeThroughZoneHash_size = 0x60; uint256 constant ContractOrder_orderHash_offerer_shift = 0x60; uint256 constant Counter_blockhash_shift = 0x80; // Signature-related bytes32 constant EIP2098_allButHighestBitMask = (0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); bytes32 constant ECDSA_twentySeventhAndTwentyEighthBytesSet = (0x0000000000000000000000000000000000000000000000000000000101000000); uint256 constant ECDSA_MaxLength = 65; uint256 constant ECDSA_signature_s_offset = 0x40; uint256 constant ECDSA_signature_v_offset = 0x60; bytes32 constant EIP1271_isValidSignature_selector = (0x1626ba7e00000000000000000000000000000000000000000000000000000000); uint256 constant EIP1271_isValidSignature_digest_negativeOffset = 0x40; uint256 constant EIP1271_isValidSignature_selector_negativeOffset = 0x44; uint256 constant EIP1271_isValidSignature_calldata_baseLength = 0x64; uint256 constant EIP1271_isValidSignature_signature_head_offset = 0x40; uint256 constant EIP_712_PREFIX = (0x1901000000000000000000000000000000000000000000000000000000000000); uint256 constant ExtraGasBuffer = 0x20; uint256 constant CostPerWord = 0x3; uint256 constant MemoryExpansionCoefficientShift = 0x9; uint256 constant Create2AddressDerivation_ptr = 0x0b; uint256 constant Create2AddressDerivation_length = 0x55; uint256 constant MaskOverByteTwelve = (0x0000000000000000000000ff0000000000000000000000000000000000000000); uint256 constant MaskOverLastTwentyBytes = (0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff); uint256 constant AddressDirtyUpperBitThreshold = (0x0000000000000000000000010000000000000000000000000000000000000000); uint256 constant MaskOverFirstFourBytes = (0xffffffff00000000000000000000000000000000000000000000000000000000); uint256 constant Conduit_execute_signature = (0x4ce34aa200000000000000000000000000000000000000000000000000000000); uint256 constant MaxUint8 = 0xff; uint256 constant MaxUint120 = 0xffffffffffffffffffffffffffffff; uint256 constant Conduit_execute_ConduitTransfer_ptr = 0x20; uint256 constant Conduit_execute_ConduitTransfer_length = 0x01; uint256 constant Conduit_execute_ConduitTransfer_offset_ptr = 0x04; uint256 constant Conduit_execute_ConduitTransfer_length_ptr = 0x24; uint256 constant Conduit_execute_transferItemType_ptr = 0x44; uint256 constant Conduit_execute_transferToken_ptr = 0x64; uint256 constant Conduit_execute_transferFrom_ptr = 0x84; uint256 constant Conduit_execute_transferTo_ptr = 0xa4; uint256 constant Conduit_execute_transferIdentifier_ptr = 0xc4; uint256 constant Conduit_execute_transferAmount_ptr = 0xe4; uint256 constant OneConduitExecute_size = 0x104; // Sentinel value to indicate that the conduit accumulator is not armed. uint256 constant AccumulatorDisarmed = 0x20; uint256 constant AccumulatorArmed = 0x40; uint256 constant Accumulator_conduitKey_ptr = 0x20; uint256 constant Accumulator_selector_ptr = 0x40; uint256 constant Accumulator_array_offset_ptr = 0x44; uint256 constant Accumulator_array_length_ptr = 0x64; uint256 constant Accumulator_itemSizeOffsetDifference = 0x3c; uint256 constant Accumulator_array_offset = 0x20; uint256 constant Conduit_transferItem_size = 0xc0; uint256 constant Conduit_transferItem_token_ptr = 0x20; uint256 constant Conduit_transferItem_from_ptr = 0x40; uint256 constant Conduit_transferItem_to_ptr = 0x60; uint256 constant Conduit_transferItem_identifier_ptr = 0x80; uint256 constant Conduit_transferItem_amount_ptr = 0xa0; uint256 constant Ecrecover_precompile = 0x1; uint256 constant Ecrecover_args_size = 0x80; uint256 constant Signature_lower_v = 27; // Bitmask that only gives a non-zero value if masked with a non-match selector. uint256 constant NonMatchSelector_MagicMask = (0x4000000000000000000000000000000000000000000000000000000000); // First bit indicates that a NATIVE offer items has been used and the 231st bit // indicates that a non match selector has been called. uint256 constant NonMatchSelector_InvalidErrorValue = (0x4000000000000000000000000000000000000000000000000000000001); /** * @dev Selector and offsets for generateOrder * * function generateOrder( * address fulfiller, * SpentItem[] calldata minimumReceived, * SpentItem[] calldata maximumSpent, * bytes calldata context * ) */ uint256 constant generateOrder_selector = 0x98919765; uint256 constant generateOrder_selector_offset = 0x1c; uint256 constant generateOrder_head_offset = 0x04; uint256 constant generateOrder_minimumReceived_head_offset = 0x20; uint256 constant generateOrder_maximumSpent_head_offset = 0x40; uint256 constant generateOrder_context_head_offset = 0x60; uint256 constant generateOrder_base_tail_offset = 0x80; uint256 constant generateOrder_maximum_returned_array_length = 0xffff; uint256 constant ratifyOrder_selector = 0xf4dd92ce; uint256 constant ratifyOrder_selector_offset = 0x1c; uint256 constant ratifyOrder_head_offset = 0x04; // uint256 constant ratifyOrder_offer_head_offset = 0x00; uint256 constant ratifyOrder_consideration_head_offset = 0x20; uint256 constant ratifyOrder_context_head_offset = 0x40; uint256 constant ratifyOrder_orderHashes_head_offset = 0x60; uint256 constant ratifyOrder_contractNonce_offset = 0x80; uint256 constant ratifyOrder_base_tail_offset = 0xa0; uint256 constant validateOrder_selector = 0x17b1f942; uint256 constant validateOrder_selector_offset = 0x1c; uint256 constant validateOrder_head_offset = 0x04; uint256 constant validateOrder_zoneParameters_offset = 0x20; uint256 constant authorizeOrder_selector = 0x01e4d72a; uint256 constant authorizeOrder_selector_offset = 0x1c; uint256 constant authorizeOrder_head_offset = 0x04; uint256 constant authorizeOrder_zoneParameters_offset = 0x20; // uint256 constant ZoneParameters_orderHash_offset = 0x00; uint256 constant ZoneParameters_fulfiller_offset = 0x20; uint256 constant ZoneParameters_offerer_offset = 0x40; uint256 constant ZoneParameters_offer_head_offset = 0x60; uint256 constant ZoneParameters_consideration_head_offset = 0x80; uint256 constant ZoneParameters_extraData_head_offset = 0xa0; uint256 constant ZoneParameters_orderHashes_head_offset = 0xc0; uint256 constant ZoneParameters_startTime_offset = 0xe0; uint256 constant ZoneParameters_endTime_offset = 0x100; uint256 constant ZoneParameters_zoneHash_offset = 0x120; uint256 constant ZoneParameters_base_tail_offset = 0x140; uint256 constant ZoneParameters_selectorAndPointer_length = 0x24; uint256 constant ZoneParameters_basicOrderFixedElements_length = 0x44; // ConsiderationDecoder Constants uint256 constant OrderParameters_head_size = 0x0160; uint256 constant OrderParameters_totalOriginalConsiderationItems_offset = ( 0x0140 ); uint256 constant AdvancedOrderPlusOrderParameters_head_size = 0x0200; uint256 constant Order_signature_offset = 0x20; uint256 constant Order_head_size = 0x40; uint256 constant AdvancedOrder_fixed_segment_0 = 0x40; uint256 constant CriteriaResolver_head_size = 0xa0; uint256 constant CriteriaResolver_fixed_segment_0 = 0x80; uint256 constant CriteriaResolver_criteriaProof_offset = 0x80; uint256 constant FulfillmentComponent_mem_tail_size = 0x40; uint256 constant FulfillmentComponent_mem_tail_size_shift = 0x6; uint256 constant Fulfillment_head_size = 0x40; uint256 constant Fulfillment_considerationComponents_offset = 0x20; uint256 constant OrderComponents_OrderParameters_common_head_size = 0x0140;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { ConsiderationEventsAndErrors } from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol"; import { ReentrancyErrors } from "seaport-types/src/interfaces/ReentrancyErrors.sol"; import { _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE, _ENTERED_SSTORE, _NOT_ENTERED_SSTORE } from "seaport-types/src/lib/ConsiderationConstants.sol"; /** * @title ReentrancyGuard * @author 0age * @notice ReentrancyGuard contains a storage variable and related functionality * for protecting against reentrancy. */ contract ReferenceReentrancyGuard is ConsiderationEventsAndErrors, ReentrancyErrors { // Prevent reentrant calls on protected functions. uint256 private _reentrancyGuard; /** * @dev Initialize the reentrancy guard during deployment. */ constructor() { // Initialize the reentrancy guard in a cleared state. _reentrancyGuard = _NOT_ENTERED_SSTORE; } /** * @dev Modifier to check that the sentinel value for the reentrancy guard * is not currently set by a previous call. */ modifier notEntered() { if (_reentrancyGuard != _NOT_ENTERED_SSTORE) { revert NoReentrantCalls(); } _; } /** * @dev Modifier to set the reentrancy guard sentinel value for the duration * of the call and check if it is already set by a previous call. * * @param acceptNativeTokens A boolean indicating whether native tokens may * be received during execution or not. */ modifier nonReentrant(bool acceptNativeTokens) { if (_reentrancyGuard != _NOT_ENTERED_SSTORE) { revert NoReentrantCalls(); } if (acceptNativeTokens) { _reentrancyGuard = _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE; } else { _reentrancyGuard = _ENTERED_SSTORE; } _; _reentrancyGuard = _NOT_ENTERED_SSTORE; } /** * @dev Internal view function to ensure that the sentinel value indicating * native tokens may be received during execution is currently set. */ function _assertAcceptingNativeTokens() internal view { // Ensure that the reentrancy guard is not currently set. if (_reentrancyGuard != _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE) { revert InvalidMsgValue(msg.value); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {ConduitControllerInterface} from "seaport-types/src/interfaces/ConduitControllerInterface.sol"; import {ConsiderationEventsAndErrors} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol"; import {ReentrancyErrors} from "seaport-types/src/interfaces/ReentrancyErrors.sol"; /** * @title ConsiderationBase * @author 0age * @notice ConsiderationBase contains all storage, constants, and constructor * logic. */ contract ReferenceConsiderationBase is ConsiderationEventsAndErrors, ReentrancyErrors { // Declare constants for name, version, and reentrancy sentinel values. string internal constant _NAME = "Seaport"; string internal constant _VERSION = "1.6"; uint256 internal constant _NOT_ENTERED = 1; uint256 internal constant _ENTERED = 2; // Precompute hashes, original chainId, and domain separator on deployment. bytes32 internal immutable _NAME_HASH; bytes32 internal immutable _VERSION_HASH; bytes32 internal immutable _EIP_712_DOMAIN_TYPEHASH; bytes32 internal immutable _OFFER_ITEM_TYPEHASH; bytes32 internal immutable _CONSIDERATION_ITEM_TYPEHASH; bytes32 internal immutable _ORDER_TYPEHASH; bytes32 internal immutable _BULK_ORDER_TYPEHASH; uint256 internal immutable _CHAIN_ID; bytes32 internal immutable _DOMAIN_SEPARATOR; // Allow for interaction with the conduit controller. ConduitControllerInterface internal immutable _CONDUIT_CONTROLLER; // Cache the conduit code hashes used by the conduit controller. bytes32 internal immutable _CONDUIT_CREATION_CODE_HASH; bytes32 internal immutable _CONDUIT_RUNTIME_CODE_HASH; // Map bulk order tree height to its respective EIP-712 typehash. mapping(uint256 => bytes32) internal _bulkOrderTypehashes; /** * @dev Derive and set hashes, reference chainId, and associated domain * separator during deployment. * * @param conduitController A contract that deploys conduits, or * proxies that may optionally be used to * transfer approved ERC20+721+1155 * tokens. */ constructor(address conduitController) { // Derive name and version hashes alongside required EIP-712 typehashes. ( _NAME_HASH, _VERSION_HASH, _EIP_712_DOMAIN_TYPEHASH, _OFFER_ITEM_TYPEHASH, _CONSIDERATION_ITEM_TYPEHASH, _ORDER_TYPEHASH, _BULK_ORDER_TYPEHASH, _DOMAIN_SEPARATOR ) = _deriveTypehashes(); // Store the current chainId and derive the current domain separator. _CHAIN_ID = block.chainid; // Set supplied conduit controller to an in-memory controller interface. ConduitControllerInterface tempController = ConduitControllerInterface( conduitController ); // Assign the in-memory interface as an immutable. _CONDUIT_CONTROLLER = tempController; // Retrieve the conduit creation code hash from the supplied controller. (_CONDUIT_CREATION_CODE_HASH, _CONDUIT_RUNTIME_CODE_HASH) = ( tempController.getConduitCodeHashes() ); _bulkOrderTypehashes[1] = bytes32( 0x3ca2711d29384747a8f61d60aad3c450405f7aaff5613541dee28df2d6986d32 ); _bulkOrderTypehashes[2] = bytes32( 0xbf8e29b89f29ed9b529c154a63038ffca562f8d7cd1e2545dda53a1b582dde30 ); _bulkOrderTypehashes[3] = bytes32( 0x53c6f6856e13104584dd0797ca2b2779202dc2597c6066a42e0d8fe990b0024d ); _bulkOrderTypehashes[4] = bytes32( 0xa02eb7ff164c884e5e2c336dc85f81c6a93329d8e9adf214b32729b894de2af1 ); _bulkOrderTypehashes[5] = bytes32( 0x39c9d33c18e050dda0aeb9a8086fb16fc12d5d64536780e1da7405a800b0b9f6 ); _bulkOrderTypehashes[6] = bytes32( 0x1c19f71958cdd8f081b4c31f7caf5c010b29d12950be2fa1c95070dc47e30b55 ); _bulkOrderTypehashes[7] = bytes32( 0xca74fab2fece9a1d58234a274220ad05ca096a92ef6a1ca1750b9d90c948955c ); _bulkOrderTypehashes[8] = bytes32( 0x7ff98d9d4e55d876c5cfac10b43c04039522f3ddfb0ea9bfe70c68cfb5c7cc14 ); _bulkOrderTypehashes[9] = bytes32( 0xbed7be92d41c56f9e59ac7a6272185299b815ddfabc3f25deb51fe55fe2f9e8a ); _bulkOrderTypehashes[10] = bytes32( 0xd1d97d1ef5eaa37a4ee5fbf234e6f6d64eb511eb562221cd7edfbdde0848da05 ); _bulkOrderTypehashes[11] = bytes32( 0x896c3f349c4da741c19b37fec49ed2e44d738e775a21d9c9860a69d67a3dae53 ); _bulkOrderTypehashes[12] = bytes32( 0xbb98d87cc12922b83759626c5f07d72266da9702d19ffad6a514c73a89002f5f ); _bulkOrderTypehashes[13] = bytes32( 0xe6ae19322608dd1f8a8d56aab48ed9c28be489b689f4b6c91268563efc85f20e ); _bulkOrderTypehashes[14] = bytes32( 0x6b5b04cbae4fcb1a9d78e7b2dfc51a36933d023cf6e347e03d517b472a852590 ); _bulkOrderTypehashes[15] = bytes32( 0xd1eb68309202b7106b891e109739dbbd334a1817fe5d6202c939e75cf5e35ca9 ); _bulkOrderTypehashes[16] = bytes32( 0x1da3eed3ecef6ebaa6e5023c057ec2c75150693fd0dac5c90f4a142f9879fde8 ); _bulkOrderTypehashes[17] = bytes32( 0xeee9a1392aa395c7002308119a58f2582777a75e54e0c1d5d5437bd2e8bf6222 ); _bulkOrderTypehashes[18] = bytes32( 0xc3939feff011e53ab8c35ca3370aad54c5df1fc2938cd62543174fa6e7d85877 ); _bulkOrderTypehashes[19] = bytes32( 0x0efca7572ac20f5ae84db0e2940674f7eca0a4726fa1060ffc2d18cef54b203d ); _bulkOrderTypehashes[20] = bytes32( 0x5a4f867d3d458dabecad65f6201ceeaba0096df2d0c491cc32e6ea4e64350017 ); _bulkOrderTypehashes[21] = bytes32( 0x80987079d291feebf21c2230e69add0f283cee0b8be492ca8050b4185a2ff719 ); _bulkOrderTypehashes[22] = bytes32( 0x3bd8cff538aba49a9c374c806d277181e9651624b3e31111bc0624574f8bca1d ); _bulkOrderTypehashes[23] = bytes32( 0x5d6a3f098a0bc373f808c619b1bb4028208721b3c4f8d6bc8a874d659814eb76 ); _bulkOrderTypehashes[24] = bytes32( 0x1d51df90cba8de7637ca3e8fe1e3511d1dc2f23487d05dbdecb781860c21ac1c ); } /** * @dev Internal view function to derive the initial EIP-712 domain * separator. * * @param _eip712DomainTypeHash The primary EIP-712 domain typehash. * @param _nameHash The hash of the name of the contract. * @param _versionHash The hash of the version string of the * contract. * * @return domainSeparator The derived domain separator. */ function _deriveInitialDomainSeparator( bytes32 _eip712DomainTypeHash, bytes32 _nameHash, bytes32 _versionHash ) internal view virtual returns (bytes32 domainSeparator) { return _deriveDomainSeparator( _eip712DomainTypeHash, _nameHash, _versionHash ); } /** * @dev Internal view function to derive the EIP-712 domain separator. * * @return The derived domain separator. */ function _deriveDomainSeparator( bytes32 _eip712DomainTypeHash, bytes32 _nameHash, bytes32 _versionHash ) internal view virtual returns (bytes32) { return keccak256( abi.encode( _eip712DomainTypeHash, _nameHash, _versionHash, block.chainid, address(this) ) ); } /** * @dev Internal pure function to derive required EIP-712 typehashes and * other hashes during contract creation. * * @return nameHash The hash of the name of the contract. * @return versionHash The hash of the version string of the * contract. * @return eip712DomainTypehash The primary EIP-712 domain typehash. * @return offerItemTypehash The EIP-712 typehash for OfferItem * types. * @return considerationItemTypehash The EIP-712 typehash for * ConsiderationItem types. * @return orderTypehash The EIP-712 typehash for Order types. * @return bulkOrderTypeHash * @return domainSeparator The domain separator. */ function _deriveTypehashes() internal view returns ( bytes32 nameHash, bytes32 versionHash, bytes32 eip712DomainTypehash, bytes32 offerItemTypehash, bytes32 considerationItemTypehash, bytes32 orderTypehash, bytes32 bulkOrderTypeHash, bytes32 domainSeparator ) { // Derive hash of the name of the contract. nameHash = keccak256(bytes(_NAME)); // Derive hash of the version string of the contract. versionHash = keccak256(bytes(_VERSION)); // Construct the OfferItem type string. bytes memory offerItemTypeString = abi.encodePacked( "OfferItem(", "uint8 itemType,", "address token,", "uint256 identifierOrCriteria,", "uint256 startAmount,", "uint256 endAmount", ")" ); // Construct the ConsiderationItem type string. bytes memory considerationItemTypeString = abi.encodePacked( "ConsiderationItem(", "uint8 itemType,", "address token,", "uint256 identifierOrCriteria,", "uint256 startAmount,", "uint256 endAmount,", "address recipient", ")" ); // Construct the OrderComponents type string, not including the above. bytes memory orderComponentsPartialTypeString = abi.encodePacked( "OrderComponents(", "address offerer,", "address zone,", "OfferItem[] offer,", "ConsiderationItem[] consideration,", "uint8 orderType,", "uint256 startTime,", "uint256 endTime,", "bytes32 zoneHash,", "uint256 salt,", "bytes32 conduitKey,", "uint256 counter", ")" ); // Construct the primary EIP-712 domain type string. eip712DomainTypehash = keccak256( abi.encodePacked( "EIP712Domain(", "string name,", "string version,", "uint256 chainId,", "address verifyingContract", ")" ) ); // Derive the OfferItem type hash using the corresponding type string. offerItemTypehash = keccak256(offerItemTypeString); // Derive ConsiderationItem type hash using corresponding type string. considerationItemTypehash = keccak256(considerationItemTypeString); // Derive OrderItem type hash via combination of relevant type strings. orderTypehash = keccak256( abi.encodePacked( orderComponentsPartialTypeString, considerationItemTypeString, offerItemTypeString ) ); // Encode the type string for the BulkOrder struct. bytes memory bulkOrderPartialTypeString = abi.encodePacked( "BulkOrder(OrderComponents[2][2][2][2][2][2][2] tree)" ); // Generate the keccak256 hash of the concatenated type strings for the // BulkOrder, considerationItem, offerItem, and orderComponents. bulkOrderTypeHash = keccak256( abi.encodePacked( bulkOrderPartialTypeString, considerationItemTypeString, offerItemTypeString, orderComponentsPartialTypeString ) ); // Derive the initial domain separator using the domain typehash, the // name hash, and the version hash. domainSeparator = _deriveInitialDomainSeparator( eip712DomainTypehash, nameHash, versionHash ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title ReentrancyErrors * @author 0age * @notice ReentrancyErrors contains errors related to reentrancy. */ interface ReentrancyErrors { /** * @dev Revert with an error when a caller attempts to reenter a protected * function. */ error NoReentrantCalls(); /** * @dev Revert with an error when attempting to activate the TSTORE opcode * when it is already active. */ error TStoreAlreadyActivated(); /** * @dev Revert with an error when attempting to activate the TSTORE opcode * in an EVM environment that does not support it. */ error TStoreNotSupported(); /** * @dev Revert with an error when deployment of the contract for testing * TSTORE support fails. */ error TloadTestContractDeploymentFailed(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { OrderParameters, ReceivedItem, SpentItem } from "../lib/ConsiderationStructs.sol"; /** * @title ConsiderationEventsAndErrors * @author 0age * @notice ConsiderationEventsAndErrors contains all events and errors. */ interface ConsiderationEventsAndErrors { /** * @dev Emit an event whenever an order is successfully fulfilled. * * @param orderHash The hash of the fulfilled order. * @param offerer The offerer of the fulfilled order. * @param zone The zone of the fulfilled order. * @param recipient The recipient of each spent item on the fulfilled * order, or the null address if there is no specific * fulfiller (i.e. the order is part of a group of * orders). Defaults to the caller unless explicitly * specified otherwise by the fulfiller. * @param offer The offer items spent as part of the order. * @param consideration The consideration items received as part of the * order along with the recipients of each item. */ event OrderFulfilled( bytes32 orderHash, address indexed offerer, address indexed zone, address recipient, SpentItem[] offer, ReceivedItem[] consideration ); /** * @dev Emit an event whenever an order is successfully cancelled. * * @param orderHash The hash of the cancelled order. * @param offerer The offerer of the cancelled order. * @param zone The zone of the cancelled order. */ event OrderCancelled( bytes32 orderHash, address indexed offerer, address indexed zone ); /** * @dev Emit an event whenever an order is explicitly validated. Note that * this event will not be emitted on partial fills even though they do * validate the order as part of partial fulfillment. * * @param orderHash The hash of the validated order. * @param orderParameters The parameters of the validated order. */ event OrderValidated(bytes32 orderHash, OrderParameters orderParameters); /** * @dev Emit an event whenever one or more orders are matched using either * matchOrders or matchAdvancedOrders. * * @param orderHashes The order hashes of the matched orders. */ event OrdersMatched(bytes32[] orderHashes); /** * @dev Emit an event whenever a counter for a given offerer is incremented. * * @param newCounter The new counter for the offerer. * @param offerer The offerer in question. */ event CounterIncremented(uint256 newCounter, address indexed offerer); /** * @dev Revert with an error when attempting to fill an order that has * already been fully filled. * * @param orderHash The order hash on which a fill was attempted. */ error OrderAlreadyFilled(bytes32 orderHash); /** * @dev Revert with an error when attempting to fill an order outside the * specified start time and end time. * * @param startTime The time at which the order becomes active. * @param endTime The time at which the order becomes inactive. */ error InvalidTime(uint256 startTime, uint256 endTime); /** * @dev Revert with an error when attempting to fill an order referencing an * invalid conduit (i.e. one that has not been deployed). */ error InvalidConduit(bytes32 conduitKey, address conduit); /** * @dev Revert with an error when an order is supplied for fulfillment with * a consideration array that is shorter than the original array. */ error MissingOriginalConsiderationItems(); /** * @dev Revert with an error when an order is validated and the length of * the consideration array is not equal to the supplied total original * consideration items value. This error is also thrown when contract * orders supply a total original consideration items value that does * not match the supplied consideration array length. */ error ConsiderationLengthNotEqualToTotalOriginal(); /** * @dev Revert with an error when a call to a conduit fails with revert data * that is too expensive to return. */ error InvalidCallToConduit(address conduit); /** * @dev Revert with an error if a consideration amount has not been fully * zeroed out after applying all fulfillments. * * @param orderIndex The index of the order with the consideration * item with a shortfall. * @param considerationIndex The index of the consideration item on the * order. * @param shortfallAmount The unfulfilled consideration amount. */ error ConsiderationNotMet( uint256 orderIndex, uint256 considerationIndex, uint256 shortfallAmount ); /** * @dev Revert with an error when insufficient native tokens are supplied as * part of msg.value when fulfilling orders. */ error InsufficientNativeTokensSupplied(); /** * @dev Revert with an error when a native token transfer reverts. */ error NativeTokenTransferGenericFailure(address account, uint256 amount); /** * @dev Revert with an error when a partial fill is attempted on an order * that does not specify partial fill support in its order type. */ error PartialFillsNotEnabledForOrder(); /** * @dev Revert with an error when attempting to fill an order that has been * cancelled. * * @param orderHash The hash of the cancelled order. */ error OrderIsCancelled(bytes32 orderHash); /** * @dev Revert with an error when attempting to fill a basic order that has * been partially filled. * * @param orderHash The hash of the partially used order. */ error OrderPartiallyFilled(bytes32 orderHash); /** * @dev Revert with an error when attempting to cancel an order as a caller * other than the indicated offerer or zone or when attempting to * cancel a contract order. */ error CannotCancelOrder(); /** * @dev Revert with an error when supplying a fraction with a value of zero * for the numerator or denominator, or one where the numerator exceeds * the denominator. */ error BadFraction(); /** * @dev Revert with an error when a caller attempts to supply callvalue to a * non-payable basic order route or does not supply any callvalue to a * payable basic order route. */ error InvalidMsgValue(uint256 value); /** * @dev Revert with an error when attempting to fill a basic order using * calldata not produced by default ABI encoding. */ error InvalidBasicOrderParameterEncoding(); /** * @dev Revert with an error when attempting to fulfill any number of * available orders when none are fulfillable. */ error NoSpecifiedOrdersAvailable(); /** * @dev Revert with an error when attempting to fulfill an order with an * offer for a native token outside of matching orders. */ error InvalidNativeOfferItem(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title ConduitControllerInterface * @author 0age * @notice ConduitControllerInterface contains all external function interfaces, * structs, events, and errors for the conduit controller. */ interface ConduitControllerInterface { /** * @dev Track the conduit key, current owner, new potential owner, and open * channels for each deployed conduit. */ struct ConduitProperties { bytes32 key; address owner; address potentialOwner; address[] channels; mapping(address => uint256) channelIndexesPlusOne; } /** * @dev Emit an event whenever a new conduit is created. * * @param conduit The newly created conduit. * @param conduitKey The conduit key used to create the new conduit. */ event NewConduit(address conduit, bytes32 conduitKey); /** * @dev Emit an event whenever conduit ownership is transferred. * * @param conduit The conduit for which ownership has been * transferred. * @param previousOwner The previous owner of the conduit. * @param newOwner The new owner of the conduit. */ event OwnershipTransferred( address indexed conduit, address indexed previousOwner, address indexed newOwner ); /** * @dev Emit an event whenever a conduit owner registers a new potential * owner for that conduit. * * @param newPotentialOwner The new potential owner of the conduit. */ event PotentialOwnerUpdated(address indexed newPotentialOwner); /** * @dev Revert with an error when attempting to create a new conduit using a * conduit key where the first twenty bytes of the key do not match the * address of the caller. */ error InvalidCreator(); /** * @dev Revert with an error when attempting to create a new conduit when no * initial owner address is supplied. */ error InvalidInitialOwner(); /** * @dev Revert with an error when attempting to set a new potential owner * that is already set. */ error NewPotentialOwnerAlreadySet( address conduit, address newPotentialOwner ); /** * @dev Revert with an error when attempting to cancel ownership transfer * when no new potential owner is currently set. */ error NoPotentialOwnerCurrentlySet(address conduit); /** * @dev Revert with an error when attempting to interact with a conduit that * does not yet exist. */ error NoConduit(); /** * @dev Revert with an error when attempting to create a conduit that * already exists. */ error ConduitAlreadyExists(address conduit); /** * @dev Revert with an error when attempting to update channels or transfer * ownership of a conduit when the caller is not the owner of the * conduit in question. */ error CallerIsNotOwner(address conduit); /** * @dev Revert with an error when attempting to register a new potential * owner and supplying the null address. */ error NewPotentialOwnerIsZeroAddress(address conduit); /** * @dev Revert with an error when attempting to claim ownership of a conduit * with a caller that is not the current potential owner for the * conduit in question. */ error CallerIsNotNewPotentialOwner(address conduit); /** * @dev Revert with an error when attempting to retrieve a channel using an * index that is out of range. */ error ChannelOutOfRange(address conduit); /** * @notice Deploy a new conduit using a supplied conduit key and assigning * an initial owner for the deployed conduit. Note that the first * twenty bytes of the supplied conduit key must match the caller * and that a new conduit cannot be created if one has already been * deployed using the same conduit key. * * @param conduitKey The conduit key used to deploy the conduit. Note that * the first twenty bytes of the conduit key must match * the caller of this contract. * @param initialOwner The initial owner to set for the new conduit. * * @return conduit The address of the newly deployed conduit. */ function createConduit( bytes32 conduitKey, address initialOwner ) external returns (address conduit); /** * @notice Open or close a channel on a given conduit, thereby allowing the * specified account to execute transfers against that conduit. * Extreme care must be taken when updating channels, as malicious * or vulnerable channels can transfer any ERC20, ERC721 and ERC1155 * tokens where the token holder has granted the conduit approval. * Only the owner of the conduit in question may call this function. * * @param conduit The conduit for which to open or close the channel. * @param channel The channel to open or close on the conduit. * @param isOpen A boolean indicating whether to open or close the channel. */ function updateChannel( address conduit, address channel, bool isOpen ) external; /** * @notice Initiate conduit ownership transfer by assigning a new potential * owner for the given conduit. Once set, the new potential owner * may call `acceptOwnership` to claim ownership of the conduit. * Only the owner of the conduit in question may call this function. * * @param conduit The conduit for which to initiate ownership transfer. * @param newPotentialOwner The new potential owner of the conduit. */ function transferOwnership( address conduit, address newPotentialOwner ) external; /** * @notice Clear the currently set potential owner, if any, from a conduit. * Only the owner of the conduit in question may call this function. * * @param conduit The conduit for which to cancel ownership transfer. */ function cancelOwnershipTransfer(address conduit) external; /** * @notice Accept ownership of a supplied conduit. Only accounts that the * current owner has set as the new potential owner may call this * function. * * @param conduit The conduit for which to accept ownership. */ function acceptOwnership(address conduit) external; /** * @notice Retrieve the current owner of a deployed conduit. * * @param conduit The conduit for which to retrieve the associated owner. * * @return owner The owner of the supplied conduit. */ function ownerOf(address conduit) external view returns (address owner); /** * @notice Retrieve the conduit key for a deployed conduit via reverse * lookup. * * @param conduit The conduit for which to retrieve the associated conduit * key. * * @return conduitKey The conduit key used to deploy the supplied conduit. */ function getKey(address conduit) external view returns (bytes32 conduitKey); /** * @notice Derive the conduit associated with a given conduit key and * determine whether that conduit exists (i.e. whether it has been * deployed). * * @param conduitKey The conduit key used to derive the conduit. * * @return conduit The derived address of the conduit. * @return exists A boolean indicating whether the derived conduit has been * deployed or not. */ function getConduit( bytes32 conduitKey ) external view returns (address conduit, bool exists); /** * @notice Retrieve the potential owner, if any, for a given conduit. The * current owner may set a new potential owner via * `transferOwnership` and that owner may then accept ownership of * the conduit in question via `acceptOwnership`. * * @param conduit The conduit for which to retrieve the potential owner. * * @return potentialOwner The potential owner, if any, for the conduit. */ function getPotentialOwner( address conduit ) external view returns (address potentialOwner); /** * @notice Retrieve the status (either open or closed) of a given channel on * a conduit. * * @param conduit The conduit for which to retrieve the channel status. * @param channel The channel for which to retrieve the status. * * @return isOpen The status of the channel on the given conduit. */ function getChannelStatus( address conduit, address channel ) external view returns (bool isOpen); /** * @notice Retrieve the total number of open channels for a given conduit. * * @param conduit The conduit for which to retrieve the total channel count. * * @return totalChannels The total number of open channels for the conduit. */ function getTotalChannels( address conduit ) external view returns (uint256 totalChannels); /** * @notice Retrieve an open channel at a specific index for a given conduit. * Note that the index of a channel can change as a result of other * channels being closed on the conduit. * * @param conduit The conduit for which to retrieve the open channel. * @param channelIndex The index of the channel in question. * * @return channel The open channel, if any, at the specified channel index. */ function getChannel( address conduit, uint256 channelIndex ) external view returns (address channel); /** * @notice Retrieve all open channels for a given conduit. Note that calling * this function for a conduit with many channels will revert with * an out-of-gas error. * * @param conduit The conduit for which to retrieve open channels. * * @return channels An array of open channels on the given conduit. */ function getChannels( address conduit ) external view returns (address[] memory channels); /** * @dev Retrieve the conduit creation code and runtime code hashes. */ function getConduitCodeHashes() external view returns (bytes32 creationCodeHash, bytes32 runtimeCodeHash); }
{ "viaIR": true, "evmVersion": "cancun", "optimizer": { "enabled": true, "mode": "3" }, "outputSelection": { "*": { "*": [ "abi" ] } }, "detectMissingLibraries": false, "forceEVMLA": false, "enableEraVMExtensions": true, "libraries": { "contracts/usdc/util/SignatureChecker.sol": { "SignatureChecker": "0xbBB5d95A805b48E24f369127ECcDDF81e87f1A0F" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"conduitController","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BadContractSignature","type":"error"},{"inputs":[],"name":"BadFraction","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BadReturnValueFromERC20OnTransfer","type":"error"},{"inputs":[{"internalType":"uint8","name":"v","type":"uint8"}],"name":"BadSignatureV","type":"error"},{"inputs":[],"name":"CannotCancelOrder","type":"error"},{"inputs":[],"name":"ConsiderationCriteriaResolverOutOfRange","type":"error"},{"inputs":[],"name":"ConsiderationLengthNotEqualToTotalOriginal","type":"error"},{"inputs":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"considerationIndex","type":"uint256"},{"internalType":"uint256","name":"shortfallAmount","type":"uint256"}],"name":"ConsiderationNotMet","type":"error"},{"inputs":[],"name":"CriteriaNotEnabledForItem","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"identifiers","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"ERC1155BatchTransferGenericFailure","type":"error"},{"inputs":[],"name":"InexactFraction","type":"error"},{"inputs":[],"name":"InsufficientNativeTokensSupplied","type":"error"},{"inputs":[],"name":"Invalid1155BatchTransferEncoding","type":"error"},{"inputs":[],"name":"InvalidBasicOrderParameterEncoding","type":"error"},{"inputs":[{"internalType":"address","name":"conduit","type":"address"}],"name":"InvalidCallToConduit","type":"error"},{"inputs":[{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"address","name":"conduit","type":"address"}],"name":"InvalidConduit","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidContractOrder","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InvalidERC721TransferAmount","type":"error"},{"inputs":[],"name":"InvalidFulfillmentComponentData","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"InvalidMsgValue","type":"error"},{"inputs":[],"name":"InvalidNativeOfferItem","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidRestrictedOrder","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"InvalidTime","type":"error"},{"inputs":[{"internalType":"uint256","name":"fulfillmentIndex","type":"uint256"}],"name":"MismatchedFulfillmentOfferAndConsiderationComponents","type":"error"},{"inputs":[{"internalType":"enum Side","name":"side","type":"uint8"}],"name":"MissingFulfillmentComponentOnAggregation","type":"error"},{"inputs":[],"name":"MissingItemAmount","type":"error"},{"inputs":[],"name":"MissingOriginalConsiderationItems","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeTokenTransferGenericFailure","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NoContract","type":"error"},{"inputs":[],"name":"NoReentrantCalls","type":"error"},{"inputs":[],"name":"NoSpecifiedOrdersAvailable","type":"error"},{"inputs":[],"name":"OfferAndConsiderationRequiredOnFulfillment","type":"error"},{"inputs":[],"name":"OfferCriteriaResolverOutOfRange","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderAlreadyFilled","type":"error"},{"inputs":[{"internalType":"enum Side","name":"side","type":"uint8"}],"name":"OrderCriteriaResolverOutOfRange","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderIsCancelled","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderPartiallyFilled","type":"error"},{"inputs":[],"name":"PartialFillsNotEnabledForOrder","type":"error"},{"inputs":[],"name":"TStoreAlreadyActivated","type":"error"},{"inputs":[],"name":"TStoreNotSupported","type":"error"},{"inputs":[],"name":"TloadTestContractDeploymentFailed","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenTransferGenericFailure","type":"error"},{"inputs":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"considerationIndex","type":"uint256"}],"name":"UnresolvedConsiderationCriteria","type":"error"},{"inputs":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"UnresolvedOfferCriteria","type":"error"},{"inputs":[],"name":"UnusedItemParameters","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newCounter","type":"uint256"},{"indexed":true,"internalType":"address","name":"offerer","type":"address"}],"name":"CounterIncremented","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"offerer","type":"address"},{"indexed":true,"internalType":"address","name":"zone","type":"address"}],"name":"OrderCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"offerer","type":"address"},{"indexed":true,"internalType":"address","name":"zone","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false,"internalType":"struct SpentItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"indexed":false,"internalType":"struct ReceivedItem[]","name":"consideration","type":"tuple[]"}],"name":"OrderFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"indexed":false,"internalType":"struct OrderParameters","name":"orderParameters","type":"tuple"}],"name":"OrderValidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"}],"name":"OrdersMatched","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"counter","type":"uint256"}],"internalType":"struct OrderComponents[]","name":"orders","type":"tuple[]"}],"name":"cancel","outputs":[{"internalType":"bool","name":"cancelled","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"uint120","name":"numerator","type":"uint120"},{"internalType":"uint120","name":"denominator","type":"uint120"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct AdvancedOrder","name":"advancedOrder","type":"tuple"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"enum Side","name":"side","type":"uint8"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"bytes32[]","name":"criteriaProof","type":"bytes32[]"}],"internalType":"struct CriteriaResolver[]","name":"criteriaResolvers","type":"tuple[]"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"}],"name":"fulfillAdvancedOrder","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"uint120","name":"numerator","type":"uint120"},{"internalType":"uint120","name":"denominator","type":"uint120"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct AdvancedOrder[]","name":"advancedOrders","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"enum Side","name":"side","type":"uint8"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"bytes32[]","name":"criteriaProof","type":"bytes32[]"}],"internalType":"struct CriteriaResolver[]","name":"criteriaResolvers","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[][]","name":"offerFulfillments","type":"tuple[][]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[][]","name":"considerationFulfillments","type":"tuple[][]"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"maximumFulfilled","type":"uint256"}],"name":"fulfillAvailableAdvancedOrders","outputs":[{"internalType":"bool[]","name":"availableOrders","type":"bool[]"},{"components":[{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem","name":"item","type":"tuple"},{"internalType":"address","name":"offerer","type":"address"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"}],"internalType":"struct Execution[]","name":"executions","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Order[]","name":"orders","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[][]","name":"offerFulfillments","type":"tuple[][]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[][]","name":"considerationFulfillments","type":"tuple[][]"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"uint256","name":"maximumFulfilled","type":"uint256"}],"name":"fulfillAvailableOrders","outputs":[{"internalType":"bool[]","name":"availableOrders","type":"bool[]"},{"components":[{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem","name":"item","type":"tuple"},{"internalType":"address","name":"offerer","type":"address"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"}],"internalType":"struct Execution[]","name":"executions","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"considerationToken","type":"address"},{"internalType":"uint256","name":"considerationIdentifier","type":"uint256"},{"internalType":"uint256","name":"considerationAmount","type":"uint256"},{"internalType":"address payable","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"internalType":"address","name":"offerToken","type":"address"},{"internalType":"uint256","name":"offerIdentifier","type":"uint256"},{"internalType":"uint256","name":"offerAmount","type":"uint256"},{"internalType":"enum BasicOrderType","name":"basicOrderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"offererConduitKey","type":"bytes32"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalAdditionalRecipients","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct AdditionalRecipient[]","name":"additionalRecipients","type":"tuple[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct BasicOrderParameters","name":"parameters","type":"tuple"}],"name":"fulfillBasicOrder","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"considerationToken","type":"address"},{"internalType":"uint256","name":"considerationIdentifier","type":"uint256"},{"internalType":"uint256","name":"considerationAmount","type":"uint256"},{"internalType":"address payable","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"internalType":"address","name":"offerToken","type":"address"},{"internalType":"uint256","name":"offerIdentifier","type":"uint256"},{"internalType":"uint256","name":"offerAmount","type":"uint256"},{"internalType":"enum BasicOrderType","name":"basicOrderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"offererConduitKey","type":"bytes32"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalAdditionalRecipients","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct AdditionalRecipient[]","name":"additionalRecipients","type":"tuple[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct BasicOrderParameters","name":"parameters","type":"tuple"}],"name":"fulfillBasicOrder_efficient_6GL6yc","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Order","name":"order","type":"tuple"},{"internalType":"bytes32","name":"fulfillerConduitKey","type":"bytes32"}],"name":"fulfillOrder","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"contractOfferer","type":"address"}],"name":"getContractOffererNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"offerer","type":"address"}],"name":"getCounter","outputs":[{"internalType":"uint256","name":"counter","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"counter","type":"uint256"}],"internalType":"struct OrderComponents","name":"order","type":"tuple"}],"name":"getOrderHash","outputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"getOrderStatus","outputs":[{"internalType":"bool","name":"isValidated","type":"bool"},{"internalType":"bool","name":"isCancelled","type":"bool"},{"internalType":"uint256","name":"totalFilled","type":"uint256"},{"internalType":"uint256","name":"totalSize","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incrementCounter","outputs":[{"internalType":"uint256","name":"newCounter","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"information","outputs":[{"internalType":"string","name":"version","type":"string"},{"internalType":"bytes32","name":"domainSeparator","type":"bytes32"},{"internalType":"address","name":"conduitController","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"uint120","name":"numerator","type":"uint120"},{"internalType":"uint120","name":"denominator","type":"uint120"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct AdvancedOrder[]","name":"advancedOrders","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"enum Side","name":"side","type":"uint8"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"bytes32[]","name":"criteriaProof","type":"bytes32[]"}],"internalType":"struct CriteriaResolver[]","name":"criteriaResolvers","type":"tuple[]"},{"components":[{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[]","name":"offerComponents","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[]","name":"considerationComponents","type":"tuple[]"}],"internalType":"struct Fulfillment[]","name":"fulfillments","type":"tuple[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"matchAdvancedOrders","outputs":[{"components":[{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem","name":"item","type":"tuple"},{"internalType":"address","name":"offerer","type":"address"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"}],"internalType":"struct Execution[]","name":"executions","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Order[]","name":"orders","type":"tuple[]"},{"components":[{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[]","name":"offerComponents","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"orderIndex","type":"uint256"},{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"internalType":"struct FulfillmentComponent[]","name":"considerationComponents","type":"tuple[]"}],"internalType":"struct Fulfillment[]","name":"fulfillments","type":"tuple[]"}],"name":"matchOrders","outputs":[{"components":[{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem","name":"item","type":"tuple"},{"internalType":"address","name":"offerer","type":"address"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"}],"internalType":"struct Execution[]","name":"executions","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"contractName","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"offerer","type":"address"},{"internalType":"address","name":"zone","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"}],"internalType":"struct OfferItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifierOrCriteria","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"},{"internalType":"uint256","name":"endAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ConsiderationItem[]","name":"consideration","type":"tuple[]"},{"internalType":"enum OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes32","name":"conduitKey","type":"bytes32"},{"internalType":"uint256","name":"totalOriginalConsiderationItems","type":"uint256"}],"internalType":"struct OrderParameters","name":"parameters","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Order[]","name":"orders","type":"tuple[]"}],"name":"validate","outputs":[{"internalType":"bool","name":"validated","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
3cda3351000000000000000000000000000000000000000000000000000000000000000001001c8f194205e3aab04a245337783bca19841c1a5a66f32ed88f3411870d1c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001972ddfa941670a9f5fa2a0094f4490347b99d7b
Deployed Bytecode
0x000400000000000200220000000000020000000003010019000000600330027000001ba4043001970003000000410355000200000001035500001ba40030019d0000000100200190000000400000c13d0000022002000039000000400020043f000000040040008c000001130000413d000000000301043b000000e00330027000001bf60030009c0000011b0000a13d00001bf70030009c0000013d0000a13d00001bf80030009c000002140000a13d00001bf90030009c000003570000613d00001bfa0030009c0000034c0000613d00001bfb0030009c00000ca20000c13d000000240040008c00000ca20000413d0000000003000416000000000003004b00000ca20000c13d0000000403100370000000000303043b000200000003001d00001bce0030009c00000ca20000213d00000002030000290000002303300039000000000043004b00000ca20000813d00000002030000290000000403300039000000000131034f000000000101043b000100000001001d00001bce0010009c00000ca20000213d0000000201000029000c00240010003d000000010100002900000005011002100000000c01100029000000000041004b00000ca20000213d0000000103000039000000000103041a000000010010008c000004f00000c13d000000010000006b000006a80000c13d0000000000320435000003520000013d0000020003000039000000400030043f0000000002000416000000000002004b00000ca20000c13d0000001f0240003900001ba5022001970000020002200039000000400020043f0000001f0540018f00001ba6064001980000020002600039000000520000613d000000000701034f000000007807043c0000000003830436000000000023004b0000004e0000c13d000000000005004b0000005f0000613d000000000161034f0000000303500210000000000502043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f0000000000120435000000200040008c00000ca20000413d000002000300043d00001ba70030009c00000ca20000213d000000400100043d00001ba80010009c0000010d0000213d0000004002100039000000400020043f0000000702000039000000000121043600001ba902000041000000000021043500001ba40010009c00001ba4010080410000004001100210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001baa011001c70000801002000039001900000003001d6e8b6e860000040f000000010020019000000ca20000613d000000000201043b000000400100043d00001ba80010009c0000010d0000213d001800000002001d0000004002100039000000400020043f0000000302000039000000000121043600001bab02000041000000000021043500001ba40010009c00001ba4010080410000004001100210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bac011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000701043b000000400900043d000000200890003900001bad0100004100000000001804350000002a0290003900001bae010000410000000000120435000000390390003900001baf020000410000000000230435000000470390003900001bb0040000410000000000430435000000640390003900001bb1050000410000000000530435000000780390003900001bb2060000410000000000630435000000890690003900001bb30300004100000000003604350000006a06000039000000000069043500001bb40090009c0000010d0000213d000000a00b9000390000004000b0043f000000c00a90003900001bb50600004100000000006a0435000000d2069000390000000000160435000000e1019000390000000000210435000000ef0190003900000000004104350000010c019000390000000000510435000001200190003900001bb6020000410000000000210435000001320190003900001bb702000041000000000021043500000143019000390000000000310435000000840100003900000000001b043500001bb80090009c0000010d0000213d0000016006900039000000400060043f000001df0190003900001bb9020000410000000000210435000001e10190003900001bba020000410000000000210435000001f10190003900001bbb020000410000000000210435000002030190003900001bbc020000410000000000210435000002130190003900001bbd020000410000000000210435000001800590003900001bbe010000410000000000150435000001900190003900001bbf020000410000000000210435000002240190003900001bc0020000410000000000210435000001a00190003900001bc1020000410000000000210435000002310190003900001bc2020000410000000000210435000001ad0190003900001bc3020000410000000000210435000002440190003900001bc4020000410000000000210435000001bf0190003900001bc5020000410000000000210435000002530190003900001bb3020000410000000000210435000000d401000039000000000016043500001bc60090009c0000010d0000213d000002800190003900001bc70300004100000000003104350000028d0390003900001bc8040000410000000000430435000002990390003900001bc9040000410000000000430435000002a80390003900001bca040000410000000000430435000002b80390003900001bcb040000410000000000430435000002d103900039000000000023043500000260029000390000005203000039000000000032043500001bcc0090009c000005440000a13d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000004004b00000ca20000c13d0000000101000039000000000101041a000000030010008c000001370000c13d000000000100001900006e8c0001042e00001c030030009c0000017f0000213d00001c090030009c0000027a0000213d000000000003004b0000034c0000613d00001c0c0030009c00000ca20000c13d0000000001000416000000000001004b00000ca20000c13d0000026001000039000000400010043f0000000701000039000002200010043f00001ba901000041000002400010043f0000002001000039000002600010043f000002200100003900000280020000396e8b0fc00000040f000002600110008a00001ba40010009c00001ba401008041000000600110021000001c2a011001c700006e8c0001042e00001bf401000041000002200010043f0000000001000416000002240010043f00001bf50100004100006e8d0001043000001bfe0030009c000002990000213d00001c010030009c000003850000613d00001c020030009c00000ca20000c13d000000440040008c00000ca20000413d0000000402100370000000000302043b00001bce0030009c00000ca20000213d000000000534004900001c0f0050009c00000ca20000213d000000440050008c00000ca20000413d0000000402300039000000000421034f000000000404043b000001630550008a00001c0d0640019700001c0d07500197000000000876013f000000000076004b000000000600001900001c0d06004041000000000054004b000000000500001900001c0d0500804100001c0d0080009c000000000605c019000000000006004b00000ca20000c13d00000000034300190000008403300039000000000131034f000000000101043b000000040010008c00000ca20000213d0000000104000039000000000304041a000000010030008c000004f00000c13d000000040010008c00000002010000390000000301006039000000000014041b00000000010200196e8b33fb0000040f001900000001001d000000400100043d001800000001001d6e8b0fdd0000040f0000001802000029000000000002043500000024010000390000000201100367000000000301043b000000000400041100000019010000296e8b359c0000040f0000000102000039000000000022041b000000400100043d0000053e0000013d00001c040030009c000002fe0000213d00001c070030009c000003980000613d00001c080030009c00000ca20000c13d000000e40040008c00000ca20000413d0000000401100370000000000101043b00001bce0010009c00000ca20000213d000000040110003900000000020400196e8b12300000040f001900000001001d00000002010003670000002402100370000000000402043b00001bce0040009c00000ca20000213d0000002305400039000000000200003100001c0d0320019700001c0d06500197000000000736013f000000000036004b000000000600001900001c0d06004041000000000025004b000000000500001900001c0d0500804100001c0d0070009c000000000605c019000000000006004b00000ca20000c13d0000000405400039000000000551034f000000000505043b001800000005001d00001bce0050009c00000ca20000213d001700240040003d000000180400002900000005044002100000001704400029000000000024004b00000ca20000213d0000004404100370000000000404043b00001bce0040009c00000ca20000213d0000002305400039000000000025004b000000000600001900001c0d0600804100001c0d05500197000000000735013f000000000035004b000000000500001900001c0d0500404100001c0d0070009c000000000506c019000000000005004b00000ca20000c13d0000000405400039000000000551034f000000000505043b001600000005001d00001bce0050009c00000ca20000213d001500240040003d000000160400002900000005044002100000001504400029000000000024004b00000ca20000213d0000006404100370000000000404043b00001bce0040009c00000ca20000213d0000002305400039000000000025004b000000000600001900001c0d0600804100001c0d05500197000000000735013f000000000035004b000000000300001900001c0d0300404100001c0d0070009c000000000306c019000000000003004b00000ca20000c13d0000000403400039000000000331034f000000000303043b001400000003001d00001bce0030009c00000ca20000213d001300240040003d000000140300002900000005033002100000001303300029000000000023004b00000ca20000213d000000a401100370000000000101043b001200000001001d00001ba70010009c00000ca20000213d0000000101000039000000000101041a000000010010008c00000cb00000c13d000000120100002900101ba70010019b00000003010000390000000102000039000000000012041b00000019010000296e8b274d0000040f001100000001001d000000100000006b000001fe0000c13d0000000001000411001200000001001d00000002010003670000008402100370000000000202043b001000000002001d000000c401100370000000000101043b000f00000001001d0000000003000031000000170100002900000018020000296e8b24b30000040f0000000003010019000000190100002900000011020000290000001504000029000000160500002900000013060000290000001407000029000000100800002900000012090000290000000f0a000029000002f30000013d00001bfc0030009c0000044a0000613d00001bfd0030009c00000ca20000c13d000000840040008c00000ca20000413d0000000401100370000000000101043b00001bce0010009c00000ca20000213d000000040110003900000000020400196e8b12300000040f001900000001001d00000002040003670000002401400370000000000101043b00001bce0010009c00000ca20000213d0000002302100039000000000300003100001c0d0530019700001c0d06200197000000000756013f000000000056004b000000000600001900001c0d06004041000000000032004b000000000200001900001c0d0200804100001c0d0070009c000000000602c019000000000006004b00000ca20000c13d0000000402100039000000000224034f000000000202043b00001bce0020009c00000ca20000213d000000240110003900000005062002100000000006160019000000000036004b00000ca20000213d0000004406400370000000000606043b00001bce0060009c00000ca20000213d0000002307600039000000000037004b000000000800001900001c0d0800804100001c0d07700197000000000957013f000000000057004b000000000500001900001c0d0500404100001c0d0090009c000000000508c019000000000005004b00000ca20000c13d0000000405600039000000000554034f000000000505043b001800000005001d00001bce0050009c00000ca20000213d001700240060003d000000180500002900000005055002100000001705500029000000000035004b00000ca20000213d0000006404400370000000000404043b001600000004001d00001ba70040009c00000ca20000213d0000000104000039000000000404041a000000010040008c00000cb00000c13d00000003040000390000000105000039000000000045041b000000160000006b0000026d0000c13d0000000004000411001600000004001d6e8b24b30000040f000000000201001900000019010000290000001703000029000000180400002900000016050000296e8b2ecb0000040f0000000102000039000000000022041b000000400300043d001900000003001d0000002002000039000003400000013d00001c0a0030009c000004550000613d00001c0b0030009c00000ca20000c13d0000000001000416000000000001004b00000ca20000c13d0000000101000039000000000101041a000000010010008c000004f00000c13d00001c25010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000009e00000613d000000000101043b000000000001004b000004f40000c13d00001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d0001043000001bff0030009c000004720000613d00001c000030009c00000ca20000c13d000000a40040008c00000ca20000413d0000000402100370000000000302043b00001bce0030009c00000ca20000213d0000002302300039000000000042004b00000ca20000813d0000000402300039000000000221034f000000000202043b00001bce0020009c00000ca20000213d000000240330003900000005052002100000000005350019000000000045004b00000ca20000213d0000002405100370000000000505043b00001bce0050009c00000ca20000213d0000002306500039000000000046004b00000ca20000813d0000000406500039000000000661034f000000000606043b001900000006001d00001bce0060009c00000ca20000213d001800240050003d000000190500002900000005055002100000001805500029000000000045004b00000ca20000213d0000004405100370000000000505043b00001bce0050009c00000ca20000213d0000002306500039000000000046004b00000ca20000813d0000000406500039000000000161034f000000000101043b001700000001001d00001bce0010009c00000ca20000213d001600240050003d000000170100002900000005011002100000001601100029000000000041004b00000ca20000213d00000001010000390000000004010019000000000101041a000000010010008c000004f00000c13d0000000301000039000000000014041b00000000010300196e8b2cb90000040f001500000001001d6e8b274d0000040f001400000001001d000000400100043d001300000001001d6e8b0fdd0000040f0000001303000029000000000003043500000002010003670000006402100370000000000802043b0000008401100370000000000a01043b00000000090004110000001501000029000000140200002900000018040000290000001905000029000000160600002900000017070000296e8b28d50000040f0000000103000039000000000033041b00000000030100190000000004020019000000400100043d001900000001001d000000000203001900000000030400196e8b14400000040f000003420000013d00001c050030009c000004cc0000613d00001c060030009c00000ca20000c13d000000440040008c00000ca20000413d0000000402100370000000000302043b00001bce0030009c00000ca20000213d0000002302300039000000000042004b00000ca20000813d0000000402300039000000000221034f000000000202043b00001bce0020009c00000ca20000213d000000240330003900000005052002100000000005350019000000000045004b00000ca20000213d0000002405100370000000000505043b00001bce0050009c00000ca20000213d0000002306500039000000000046004b00000ca20000813d0000000406500039000000000161034f000000000101043b001900000001001d00001bce0010009c00000ca20000213d001800240050003d000000190100002900000005011002100000001801100029000000000041004b00000ca20000213d0000000104000039000000000104041a000000010010008c000004f00000c13d0000000301000039000000000014041b00000000010300196e8b2cb90000040f001700000001001d000000400100043d001600000001001d6e8b0fdd0000040f0000001602000029000000000002043500000000050004110000001701000029000000180300002900000019040000296e8b2ecb0000040f0000000102000039000000000022041b0000002002000039000000400300043d001900000003001d00000000022304366e8b14100000040f0000001902000029000000000121004900001ba40010009c00001ba401008041000000600110021000001ba40020009c00001ba4020080410000004002200210000000000121019f00006e8c0001042e00000000010400196e8b0fae0000040f6e8b14830000040f0000000101000039000000400200043d000000000012043500001ba40020009c00001ba402008041000000400120021000001c1c011001c700006e8c0001042e0000000001000416000000000001004b00000ca20000c13d0000026001000039000000400010043f0000000301000039000002200010043f00001bab01000041000002400010043f6e8b5fb70000040f0000006002000039000000400300043d001900000003001d0000000002230436001800000002001d001700000001001d000002200100003900000060023000396e8b0fc00000040f0000001802000029000000170300002900000000003204350000000002000412001b00000002001d001a01200000003d001800000001001d0000800501000039000000440300003900000000040004150000001b0440008a000000050440021000001c10020000416e8b6e630000040f00001ba701100197000000190300002900000040023000390000000000120435000000180130006900001ba40010009c00001ba401008041000000600110021000001ba40030009c00001ba4030080410000004002300210000000000121019f00006e8c0001042e000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000401100370000000000101043b00001ba70010009c00000ca20000213d000000000010043f0000000401000039000000200010043f000000400200003900000000010000196e8b6e4e0000040f000000000101041a000002200010043f00001c1d0100004100006e8c0001042e000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000402100370000000000202043b00001bce0020009c00000ca20000213d000000000324004900001c0f0030009c00000ca20000213d000001640030008c00000ca20000413d0000000403200039000000000531034f000000000505043b001900000005001d00001ba70050009c00000ca20000213d0000002005300039000000000651034f000000000606043b001800000006001d00001ba70060009c00000ca20000213d00000000063400490000002007500039000000000571034f000000000805043b0000001f0560008a00001c0d0650019700001c0d09800197000000000a69013f000000000069004b000000000900001900001c0d09004041000000000058004b000000000b00001900001c0d0b00804100001c0d00a0009c00000000090bc019000000000009004b00000ca20000c13d0000000008380019000000000981034f000000000909043b001700000009001d00001bce0090009c00000ca20000213d000000a00900008a00000017099000b90000000009490019000000200c80003900001c0d0890019700001c0d0ac00197000000000b8a013f00000000008a004b000000000800001900001c0d0800404100160000000c001d00000000009c004b000000000900001900001c0d0900204100001c0d00b0009c000000000809c019000000000008004b00000ca20000c13d0000002007700039000000000871034f000000000808043b00001c0d09800197000000000a69013f000000000069004b000000000600001900001c0d06004041000000000058004b000000000500001900001c0d0500804100001c0d00a0009c000000000605c019000000000006004b00000ca20000c13d0000000005380019000000000651034f000000000606043b001500000006001d00001bce0060009c00000ca20000213d000000c00600008a00000015066000b90000000004460019000000200950003900001c0d0540019700001c0d06900197000000000856013f000000000056004b000000000500001900001c0d05004041001400000009001d000000000049004b000000000400001900001c0d0400204100001c0d0080009c000000000504c019000000000005004b00000ca20000c13d001200200070003d0000001201100360000000000101043b001100000001001d000000040010008c00000ca20000213d000000640220003900000000010300196e8b24880000040f001000000001001d000000400100043d001300000001001d6e8b0fd20000040f0000001303000029000000200130003900000018020000290000000000210435000000190100002900000000001304350000000003000031000000160100002900000017020000296e8b0fe80000040f0000001302000029000000400220003900000000001204350000000003000031000000140100002900000015020000296e8b10330000040f000000130500002900000080025000390000001103000029000000000032043500000060025000390000000000120435000000120400002900000020014000390000000201100367000000000101043b000000a003500039000000000013043500000040014000390000000201100367000000000101043b000000c003500039000000000013043500000060014000390000000201100367000000000101043b000000e003500039000000000013043500000080014000390000000201100367000000000101043b00000100035000390000000000130435000000a0014000390000000201100367000000000101043b000001200350003900000000001304350000014003500039000000000105001900000010050000290000000000530435000000c0034000390000000202300367000000000202043b6e8b25460000040f000003500000013d000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000401100370000000000101043b00001ba70010009c00000ca20000213d6e8b25340000040f000003500000013d000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000401100370000000000101043b000000000010043f0000000301000039000000200010043f000000400200003900000000010000196e8b6e4e0000040f000000000101041a000000ff001001900000000002000039000000010200c039000002200020043f0000ff00001001900000000002000039000000010200c039000002400020043f000000100210027000001c1f02200197000002600020043f0000008801100270000002800010043f00001c290100004100006e8c0001042e000000840040008c00000ca20000413d0000000402100370000000000302043b00001bce0030009c00000ca20000213d000000000534004900001c0f0050009c00000ca20000213d000000a40050008c00000ca20000413d0000002402100370000000000202043b00001bce0020009c00000ca20000213d0000002306200039000000000046004b00000ca20000813d0000000406200039000000000661034f000000000606043b001900000006001d00001bce0060009c00000ca20000213d001800240020003d000000190200002900000005022002100000001802200029000000000042004b00000ca20000213d0000006402100370000000000202043b001700000002001d00001ba70020009c00000ca20000213d0000000402300039000000000621034f000000000606043b000001630550008a00001c0d0760019700001c0d08500197000000000987013f000000000087004b000000000700001900001c0d07004041000000000056004b000000000500001900001c0d0500804100001c0d0090009c000000000705c019000000000007004b00000ca20000c13d00000000036300190000008403300039000000000131034f000000000101043b000000040010008c00000ca20000213d0000000103000039000000000303041a000000010030008c000004f00000c13d000000040010008c000000020100003900000003010060390000000103000039000000000013041b000000170000006b000004b90000c13d0000000001000411001700000001001d000000000102001900000000020400196e8b10850000040f00000044020000390000000202200367000000000202043b001600000002001d001500000001001d0000000003000031000000180100002900000019020000296e8b24b30000040f00000000020100190000001501000029000000160300002900000017040000296e8b359c0000040f00000001020000390000017c0000013d000000240040008c00000ca20000413d0000000002000416000000000002004b00000ca20000c13d0000000402100370000000000202043b001400000002001d00001bce0020009c00000ca20000213d00000014020000290000002302200039000000000042004b00000ca20000813d00000014020000290000000402200039000000000121034f000000000101043b001300000001001d00001bce0010009c00000ca20000213d0000001401000029000000240e100039000000130100002900000005011002100000000001e10019000000000041004b00000ca20000213d0000000102000039000000000102041a000000010010008c000004f00000c13d000000130000006b000009e10000c13d00000220010000390000053e0000013d00001c2301000041000002200010043f00001c240100004100006e8d00010430001900000001001d0000000001000411000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d0000001902000029000000010220008a000000000101043b000000000101041a001900000001001d00001c260100004100000000001004430000000400200443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800b020000396e8b6e860000040f0000000100200190000009e00000613d000000000101043b0000008001100270001800000001001d000000190010002a000002930000413d0000000001000411000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d00000018030000290000001902300029000000000101043b000000000021041b000000400100043d001900000002001d000000000021043500001ba40010009c00001ba4010080410000004001100210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001c19011001c70000800d02000039000000020300003900001c280400004100000000050004116e8b6e810000040f000000010020019000000ca20000613d000000400100043d0000001902000029000000000021043500001ba40010009c00001ba401008041000000400110021000001c1c011001c700006e8c0001042e00140000000b001d001300000006001d001100000005001d00150000000a001d001600000008001d001000000007001d001700000009001d000002e003900039001200000003001d000000400030043f00001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000160200002900001ba40020009c00001ba40200804100000040022002100000001703000029000000000303043300001ba40030009c00001ba4030080410000006003300210000000000223019f000000000101043b000f00000001001d000000000100041400001ba40010009c00001ba401008041000000c001100210000000000121019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000150200002900001ba40020009c00001ba40200804100000040022002100000001403000029000000000303043300001ba40030009c00001ba4030080410000006003300210000000000223019f000000000101043b000e00000001001d000000000100041400001ba40010009c00001ba401008041000000c001100210000000000121019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d00000017020000290000030002200039000000000101043b000d00000001001d00000013010000290000000001010433000000000001004b00000011060000290000059d0000613d000000000300001900000000042300190000000005630019000000000505043300000000005404350000002003300039000000000013004b000005960000413d0000000001210019000000000001043500000014030000290000000003030433000000000003004b0000001507000029000005ac0000613d000000000400001900000000051400190000000006740019000000000606043300000000006504350000002004400039000000000034004b000005a50000413d0000000001130019000000000001043500000017030000290000000003030433000000000003004b0000001607000029000005bb0000613d000000000400001900000000051400190000000006740019000000000606043300000000006504350000002004400039000000000034004b000005b40000413d00000000011300190000000000010435000000130110006a000001a00310008a00000012040000290000000000340435000001610110008a00001c2b031001970000000001430019000000000031004b0000000003000039000000010300403900001bce0010009c0000010d0000213d00000001003001900000010d0000c13d000000400010043f00001ba40020009c00001ba40200804100000040012002100000001202000029000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b001200000001001d000000400300043d000000400130003900001bcf020000410000000000210435000000200430003900001bd00100004100000000001404350000003401000039000000000013043500001bd10030009c0000010d0000213d0000006001300039000000400010043f00000080023000390000000005030433000000000005004b000005fa0000613d000000000600001900000000072600190000000008460019000000000808043300000000008704350000002006600039000000000056004b000005f30000413d0000000004250019000000000004043500000014050000290000000005050433000000000005004b0000001509000029000006090000613d000000000600001900000000074600190000000008960019000000000808043300000000008704350000002006600039000000000056004b000006020000413d0000000004450019000000000004043500000017050000290000000005050433000000000005004b0000001609000029000006180000613d000000000600001900000000074600190000000008960019000000000808043300000000008704350000002006600039000000000056004b000006110000413d0000000004450019000000000004043500000013050000290000000005050433000000000005004b0000001109000029000006270000613d000000000600001900000000074600190000000008960019000000000808043300000000008704350000002006600039000000000056004b000006200000413d000000000445001900000000000404350000000003340049000000800430008a0000000000410435000000410330008a00001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c0000010d0000213d00000001004001900000010d0000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b001500000001001d000000400300043d000000600130003900000010020000290000000000210435000000400130003900000018020000290000000000210435001700000003001d00000020023000390000000f01000029001600000002001d000000000012043500001bd2010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000009e00000613d000000000301043b0000001704000029000000a001400039000000000200041000000000002104350000008001400039001400000003001d0000000000310435000000a001000039000000000014043500001bd40040009c0000010d0000213d0000001702000029000000c001200039000000400010043f000000160100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000001903000029000000010020019000000ca20000613d00001ba702300197000000000101043b000001800010043f002201400000003d0000001501000029000001400010043f0000001201000029000001200010043f0000000d01000029000001000010043f0000000e01000029000000e00010043f0000000f01000029000000c00010043f0000001001000029000000a00010043f0000001801000029000000800010043f002101600000003d0000001401000029000001600010043f000001a00020043f00001bd501000041000000400300043d001900000003001d0000000001130436001800000001001d0000000001000414000000040020008c00000ccf0000c13d0000000103000031000000400030008c0000004004000039000000000403401900000cfa0000013d0000000002000019000b00000002001d00000005012002100000000c021000290000000201000367000000000221034f000000000302043b0000000002000031000000020420006a000001830440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0000000c03300029000000000431034f000000000404043b000e00000004001d00001ba70040009c00000ca20000213d0000002004300039000000000541034f000000000505043b000d00000005001d00001ba70050009c00000ca20000213d0000006005400039000000000451034f000000000404043b000000050040008c00000ca20000813d000000040040008c00000cbb0000613d00000000060004110000000e0060006c000006d70000613d0000000d0060006c00000cbb0000c13d0000000006320049000000400950008a000000000591034f000000000705043b0000001f0560008a00001c0d0650019700001c0d08700197000000000a68013f000000000068004b000000000800001900001c0d08004041000000000057004b000000000b00001900001c0d0b00804100001c0d00a0009c00000000080bc019000000000008004b00000ca20000c13d0000000007370019000000000871034f000000000808043b00001bce0080009c00000ca20000213d00001c2c0a8000d1000000000a2a0019000000200770003900001c0d0ba0019700001c0d0c700197000000000dbc013f0000000000bc004b000000000b00001900001c0d0b0040410000000000a7004b000000000a00001900001c0d0a00204100001c0d00d0009c000000000b0ac01900000000000b004b00000ca20000c13d0000002009900039000000000991034f000000000909043b00001c0d0a900197000000000b6a013f00000000006a004b000000000600001900001c0d06004041000000000059004b000000000500001900001c0d0500804100001c0d00b0009c000000000605c019000000000006004b00000ca20000c13d0000000006390019000000000561034f000000000505043b00001bce0050009c00000ca20000213d00001c2d095000d10000000009290019000000200660003900001c0d0a90019700001c0d0b600197000000000cab013f0000000000ab004b000000000a00001900001c0d0a004041000000000096004b000000000900001900001c0d0900204100001c0d00c0009c000000000a09c01900000000000a004b00000ca20000c13d000000400900043d000f00000009001d00001bb80090009c0000010d0000213d0000000f0a0000290000016009a00039000000400090043f0000000e09000029000000000a9a04360000000d09000029000a0000000a001d00000000009a043500000005098002100000003f0990003900001c0e0a900197000000400900043d000000000aa9001900000000009a004b000000000b000039000000010b00403900001bce00a0009c0000010d0000213d0000000100b001900000010d0000c13d0000004000a0043f0000000000890435000000a0088000c90000000008780019000000000028004b00000ca20000213d000000000078004b0000076c0000a13d000000000a090019000000000b72004900001c0f00b0009c00000ca20000213d000000a000b0008c00000ca20000413d000000400b00043d00001bb400b0009c0000010d0000213d000000a00cb000390000004000c0043f000000000c71034f000000000c0c043b0000000500c0008c00000ca20000213d000000000dcb0436000000200c700039000000000ec1034f000000000e0e043b00001ba700e0009c00000ca20000213d000000200aa000390000000000ed0435000000200dc00039000000000dd1034f000000000d0d043b000000400eb000390000000000de0435000000400dc00039000000000dd1034f000000000d0d043b000000600eb000390000000000de0435000000600cc00039000000000cc1034f000000000c0c043b000000800db000390000000000cd04350000000000ba0435000000a007700039000000000087004b000007430000413d0000000f070000290000004007700039001600000007001d000000000097043500000005075002100000003f0770003900001c0e08700197000000400700043d0000000008870019000000000078004b0000000009000039000000010900403900001bce0080009c0000010d0000213d00000001009001900000010d0000c13d000000400080043f0000000000570435000000c0085000c90000000008680019000000000028004b00000ca20000213d000000000068004b000007b50000a13d0000000009070019000000000a62004900001c0f00a0009c00000ca20000213d000000c000a0008c00000ca20000413d000000400a00043d00001bd400a0009c0000010d0000213d000000c00ba000390000004000b0043f000000000b61034f000000000b0b043b0000000500b0008c00000ca20000213d000000000cba0436000000200b600039000000000db1034f000000000d0d043b00001ba700d0009c00000ca20000213d0000000000dc0435000000200cb00039000000000cc1034f000000000c0c043b000000400da000390000000000cd0435000000400cb00039000000000cc1034f000000000c0c043b000000600da000390000000000cd0435000000600cb00039000000000cc1034f000000000c0c043b000000800da000390000000000cd0435000000800bb00039000000000bb1034f000000000b0b043b00001ba700b0009c00000ca20000213d0000002009900039000000a00ca000390000000000bc04350000000000a90435000000c006600039000000000086004b000007850000413d0000000f060000290000006006600039001000000006001d0000000000760435000000040040008c00000caa0000213d0000000f070000290000008006700039000900000006001d0000000000460435000000a004300039000000000441034f000000000404043b000000a006700039000800000006001d0000000000460435000000c004300039000000000441034f000000000404043b000000c006700039000700000006001d0000000000460435000000e004300039000000000441034f000000000404043b000000e006700039000600000006001d00000000004604350000012004300039000000000441034f0000010006300039000000000661034f0000014003300039000000000331034f000000000606043b0000010008700039000500000008001d0000000000680435000000000404043b0000014006700039001500000006001d00000000005604350000012005700039000400000005001d0000000000450435000000000303043b000300000003001d00000016030000290000000003030433000000000403043300001bce0040009c0000010d0000213d00000005034002100000003f0530003900001c0e05500197000000400700043d0000000005570019000000000075004b0000000006000039000000010600403900001bce0050009c0000010d0000213d00000001006001900000010d0000c13d000000400050043f0000000004470436001300000004001d000000000121034f000000000003004b000008020000613d00000013050000290000000002350019000000000401034f000000004604043c0000000005650436000000000025004b000007fe0000c13d0000001f003001900000001502000029000000000302043300001bce0030009c0000010d0000213d00000005023002100000003f0420003900001c0e04400197000000400600043d0000000004460019000000000064004b0000000005000039000000010500403900001bce0040009c0000010d0000213d00000001005001900000010d0000c13d000000400040043f0000000003360436001200000003001d000000000002004b0000081e0000613d00000012040000290000000003240019000000001501043c0000000004540436000000000034004b0000081a0000c13d001900000007001d001400000006001d0000001f0020019000001c100100004100000000001004430000000001000412000000040010044300000060010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000009e00000613d000000000101043b001100000001001d000000160100002900000000010104330000000002010433000000000002004b0000087e0000613d000000000400001900000005054002100000000001510019000000200110003900000000010104330000000032010434000000050020008c00000caa0000213d001700000005001d001800000004001d0000000003030433000000400410003900000000040404330000006005100039000000000505043300000080011000390000000006010433000000400100043d000000c0071000390000000000670435000000a0061000390000000000560435000000800510003900000000004504350000004004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000011030000290000000000320435000000c003000039000000000031043500001c120010009c0000010d0000213d000000e003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000190200002900000000020204330000001804000029000000000042004b00000ca40000a13d00000017030000290000001302300029000000000101043b00000000001204350000000104400039000000160100002900000000010104330000000002010433000000000024004b000008380000413d00001c100100004100000000001004430000000001000412000000040010044300000080010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000009e00000613d000000000101043b001600000001001d00000015010000290000000001010433000000000001004b0000001907000029000008e50000613d0000000004000019000000100100002900000000010104330000000002010433000000000042004b00000ca40000a13d00000005054002100000000001150019000000200110003900000000010104330000000032010434000000050020008c00000caa0000213d001700000005001d001800000004001d0000000003030433000000a0041000390000000004040433000000400510003900000000050504330000006006100039000000000606043300000080011000390000000007010433000000400100043d000000c0081000390000000000780435000000a0071000390000000000670435000000800610003900000000005604350000004005100039000000000025043500001ba702400197000000e004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000016030000290000000000320435000000e003000039000000000031043500001c130010009c0000010d0000213d0000010003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000140200002900000000020204330000001804000029000000000042004b000000190700002900000ca40000a13d00000017030000290000001202300029000000000101043b0000000000120435000000010440003900000015010000290000000001010433000000000014004b000008950000413d000000400100043d00000020021000390000000a030000290000000003030433001900000003001d0000000f030000290000000003030433001800000003001d0000000003070433000000000003004b0000000004020019000008f90000613d000000000500001900000000040200190000002007700039000000000607043300000000046404360000000105500039000000000035004b000008f30000413d0000000003140049000000200430008a00000000004104350000001f0330003900001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c0000010d0000213d00000001004001900000010d0000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000400200043d0000002003200039000000000101043b001700000001001d00000014070000290000000001070433000000000001004b00000000040300190000092a0000613d000000000500001900000000040300190000002007700039000000000607043300000000046404360000000105500039000000000015004b000009240000413d0000000001240049000000200410008a00000000004204350000001f0110003900001c2b041001970000000001240019000000000041004b0000000004000039000000010400403900001bce0010009c0000010d0000213d00000001004001900000010d0000c13d000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b001600000001001d00000009010000290000000001010433001500000001001d000000040010008c00000caa0000213d00000004010000290000000001010433000f00000001001d00000005010000290000000001010433001000000001001d00000006010000290000000001010433001100000001001d00000007010000290000000001010433001200000001001d00000008010000290000000001010433001300000001001d000000400100043d001400000001001d00001c1001000041000000000010044300000000010004120000000400100443000000a0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000009e00000613d000000190200002900001ba702200197000000180300002900001ba703300197000000000401043b000000140600002900000180016000390000000305000029000000000051043500000160016000390000000f050000290000000000510435000001400160003900000010050000290000000000510435000001200160003900000011050000290000000000510435000001000160003900000012050000290000000000510435000000e00160003900000013050000290000000000510435000000c00160003900000015050000290000000000510435000000a001600039000000160500002900000000005104350000008001600039000000170500002900000000005104350000006001600039000000000021043500000040016000390000000000310435000000200160003900000000004104350000018002000039000000000026043500001c160060009c0000010d0000213d000001a002600039000000400020043f00001ba40010009c00001ba4010080410000004001100210000000000206043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b001900000001001d000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000000ca20000613d000000000101043b000000000201041a00001c180220019700000100022001bf000000000021041b000000400100043d0000001902000029000000000021043500001ba40010009c00001ba4010080410000004001100210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f0000000e0200002900001ba7052001970000000d0200002900001ba70620019700001c19011001c70000800d02000039000000030300003900001c1a040000416e8b6e810000040f000000010020019000000ca20000613d0000000b020000290000000102200039000000010020006c000006a90000413d000000400200043d00000001030000390000003e0000013d000000000001042f000000000f000019000f0000000e001d000009e90000013d000000ff00a0019000000b280000613d000000010ff000390000001300f0006c00000cb80000813d0000000501f002100000000001e100190000000202000367000000000112034f000000000101043b0000000003000031000000140430006a000000630440008a00001c0d0540019700001c0d06100197000000000756013f000000000056004b000000000500001900001c0d05004041000000000041004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0018000000e1001d0000001801200360000000000101043b000000180430006a0000015f0440008a00001c0d0540019700001c0d06100197000000000756013f000000000056004b000000000500001900001c0d05004041000000000041004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0000001801100029001900000001001d0000008001100039000000000112034f000000000401043b000000040040008c00000ca20000213d000009e60000613d000000190130006a0000001905200360000000000505043b001700000005001d00001c0f0010009c00000ca20000213d000001600010008c00000ca20000413d000000170100002900001ba70010009c00000ca20000213d000000400100043d00001bb80010009c0000010d0000213d0000016005100039000000400050043f000000170500002900000000055104360000001906000029001600200060003d0000001606200360000000000606043b00001ba70060009c00000ca20000213d00000000006504350000001605000029001200200050003d0000001205200360000000000505043b00001bce0050009c00000ca20000213d00000019075000290000001f05700039000000000035004b000000000600001900001c0d0600804100001c0d0850019700001c0d05300197000000000958013f000000000058004b000000000800001900001c0d0800404100001c0d0090009c000000000806c019000000000008004b00000ca20000c13d000000000672034f000000000806043b00001bce0080009c0000010d0000213d00000005068002100000003f0660003900001c0e09600197000000400600043d0000000009960019000000000069004b000000000a000039000000010a00403900001bce0090009c0000010d0000213d0000000100a001900000010d0000c13d0000002007700039000000400090043f0000000000860435000000a0088000c90000000008780019000000000038004b00000ca20000213d000000000078004b00000a890000a13d0000000009060019000000000a73004900001c0f00a0009c00000ca20000213d000000a000a0008c00000ca20000413d000000400a00043d00001bb400a0009c0000010d0000213d000000a00ba000390000004000b0043f000000000b72034f000000000b0b043b0000000500b0008c00000ca20000213d000000000cba0436000000200b700039000000000db2034f000000000d0d043b00001ba700d0009c00000ca20000213d00000020099000390000000000dc0435000000200cb00039000000000cc2034f000000000c0c043b000000400da000390000000000cd0435000000400cb00039000000000cc2034f000000000c0c043b000000600da000390000000000cd0435000000600bb00039000000000bb2034f000000000b0b043b000000800ca000390000000000bc04350000000000a90435000000a007700039000000000087004b00000a600000413d0000004007100039000000000067043500000019060000290000006006600039000000000662034f000000000606043b00001bce0060009c00000ca20000213d00000019066000290000001f07600039000000000037004b000000000800001900001c0d0800804100001c0d07700197000000000957013f000000000057004b000000000500001900001c0d0500404100001c0d0090009c000000000508c019000000000005004b00000ca20000c13d000000000562034f000000000705043b00001bce0070009c0000010d0000213d00000005057002100000003f0550003900001c0e08500197000000400500043d0000000008850019000000000058004b0000000009000039000000010900403900001bce0080009c0000010d0000213d00000001009001900000010d0000c13d0000002006600039000000400080043f0000000000750435000000c0077000c90000000007670019000000000037004b00000ca20000213d000000000067004b00000ae90000a13d0000000008050019000000000963004900001c0f0090009c00000ca20000213d000000c00090008c00000ca20000413d000000400900043d00001bd40090009c0000010d0000213d000000c00a9000390000004000a0043f000000000a62034f000000000a0a043b0000000500a0008c00000ca20000213d000000000ba90436000000200a600039000000000ca2034f000000000c0c043b00001ba700c0009c00000ca20000213d0000000000cb0435000000200ba00039000000000bb2034f000000000b0b043b000000400c9000390000000000bc0435000000400ba00039000000000bb2034f000000000b0b043b000000600c9000390000000000bc0435000000600ba00039000000000bb2034f000000000b0b043b000000800c9000390000000000bc0435000000800aa00039000000000aa2034f000000000a0a043b00001ba700a0009c00000ca20000213d0000002008800039000000a00b9000390000000000ab04350000000000980435000000c006600039000000000076004b00000ab90000413d00000080031000390000000000430435000000600310003900000000005304350000001905000029000000a003500039000000000332034f000000000303043b000000a0041000390000000000340435000000c003500039000000000332034f000000000303043b000000c0041000390000000000340435000000e003500039000000000332034f000000000303043b000000e00410003900000000003404350000010003500039000000000332034f000000000303043b000001000410003900000000003404350000012003500039000000000332034f000000000303043b00000120041000390000000000340435001101400050003d0000001102200360000000000202043b0000014003100039000000000023043500150000000f001d6e8b5a830000040f001000000001001d000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000150f0000290000000f0e000029000000010020019000000ca20000613d000000000901043b000000000a09041a0000ff0000a0019000000cbe0000c13d0000001001a0027000001c1f01100198000009e40000613d0000008802a00270000000000021004b000009e40000413d00000cc10000013d0000001101000029000000e00210008a0000000201000367000000000221034f000000000302043b0000000002000031000000190420006a0000001f0440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0000001904300029000000000341034f000000000303043b00001bce0030009c00000ca20000213d00001c2d053000d100000000052500190000002004400039000000000054004b000000000600001900001c0d0600204100001c0d0550019700001c0d04400197000000000754013f000000000054004b000000000400001900001c0d0400404100001c0d0070009c000000000406c019000000000004004b00000ca20000c13d0000001104100360000000000404043b000000000043004b00000ccc0000c13d000000180300002900000000043200490000002003300039000000000331034f000000000303043b0000001f0440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00000ca20000c13d0000001803300029000000000431034f000000000404043b00001bce0040009c00000ca20000213d0000000005420049000000200630003900001c0d0350019700001c0d07600197000000000837013f000000000037004b000000000300001900001c0d03004041000000000056004b000000000500001900001c0d0500204100001c0d0080009c000000000305c019000000000003004b00000ca20000c13d0000001f0340003900001c2b033001970000003f0330003900001c2b05300197000000400300043d0000000005530019000000000035004b0000000007000039000000010700403900001bce0050009c0000010d0000213d00000001007001900000010d0000c13d000000400050043f00000000054304360000000007640019000000000027004b00000ca20000213d001800000009001d000000000261034f00001c2b06400198000000000165001900000b9a0000613d000000000702034f0000000008050019000000007907043c0000000008980436000000000018004b00000b960000c13d00110000000a001d0000001f0740019000000ba80000613d000000000262034f0000000306700210000000000701043300000000076701cf000000000767022f000000000202043b0000010006600089000000000262022f00000000026201cf000000000272019f000000000021043500000000014500190000000000010435000000170100002900000010020000296e8b5c900000040f000001000100008a000000110110017f00000001011001bf0000001802000029000000000012041b000000400100043d0000002002100039000000400300003900000000003204350000001002000029000000000021043500000002020003670000001903200360000000000303043b00001ba70030009c00000ca20000213d000000400410003900000000003404350000001603200360000000000303043b00001ba70030009c00000ca20000213d0000006004100039000000000034043500000012042003600000000003000031000000190530006a0000001f0550008a000000000404043b00001c0d0740019700001c0d06500197000000000867013f000000000067004b000000000700001900001c0d07004041000000000054004b000000000900001900001c0d0900804100001c0d0080009c000000000709c019000000000007004b00000ca20000c13d0000001907400029000000000472034f000000000404043b00001bce0040009c00000ca20000213d00001c2c084000d10000000009380019000000200870003900001c0d0790019700001c0d0a800197000000000b7a013f00000000007a004b000000000700001900001c0d07004041000000000098004b000000000900001900001c0d0900204100001c0d00b0009c000000000709c019000000000007004b00000ca20000c13d000000800710003900000160090000390000000000970435000001a0071000390000000000470435000001c007100039000000000004004b00000c140000613d0000000009000019000000000a82034f000000000a0a043b0000000500a0008c00000ca20000213d000000000ba70436000000200a800039000000000ca2034f000000000c0c043b00001ba700c0009c00000ca20000213d0000000000cb0435000000200ba00039000000000bb2034f000000000b0b043b000000400c7000390000000000bc0435000000400ba00039000000000bb2034f000000000b0b043b000000600c7000390000000000bc0435000000600aa00039000000000aa2034f000000000a0a043b000000800b7000390000000000ab0435000000a008800039000000a0077000390000000109900039000000000049004b00000bf50000413d00000012040000290000002004400039000000000842034f000000000808043b00001c0d09800197000000000a69013f000000000069004b000000000600001900001c0d06002041000000000058004b000000000500001900001c0d0500404100001c0d00a0009c000000000605c019000000000006004b00000ca20000613d0000001906800029000000000562034f000000000505043b00001bce0050009c00000ca20000213d000000200660003900001c2d085000d10000000003380019000000000036004b000000000800001900001c0d0800204100001c0d0330019700001c0d09600197000000000a39013f000000000039004b000000000300001900001c0d0300404100001c0d00a0009c000000000308c019000000000003004b00000ca20000c13d0000000003170049000000400330008a000000a00810003900000000003804350000000003570436000000000005004b00000c670000613d0000000007000019000000000862034f000000000808043b000000050080008c00000ca20000213d00000000098304360000002008600039000000000a82034f000000000a0a043b00001ba700a0009c00000ca20000213d0000000000a904350000002009800039000000000992034f000000000909043b000000400a30003900000000009a04350000004009800039000000000992034f000000000909043b000000600a30003900000000009a04350000006009800039000000000992034f000000000909043b000000800a30003900000000009a04350000008008800039000000000882034f000000000808043b00001ba70080009c00000ca20000213d000000a0093000390000000000890435000000c006600039000000c0033000390000000107700039000000000057004b00000c410000413d0000002004400039000000000542034f000000000505043b000000050050008c00000caa0000813d000000c00610003900000000005604350000002005400039000000000552034f000000000505043b000000e00610003900000000005604350000004005400039000000000552034f000000000505043b000001000610003900000000005604350000006005400039000000000552034f000000000505043b000001200610003900000000005604350000008005400039000000000552034f000000000505043b00000140061000390000000000560435000000a005400039000000000552034f000000000505043b00000160061000390000000000560435000000c004400039000000000242034f000000000202043b00000180041000390000000000240435000000000213004900001ba40020009c00001ba402008041000000600220021000001ba40010009c00001ba4010080410000004001100210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c70000800d02000039000000010300003900001c22040000416e8b6e810000040f00000001002001900000000f0e000029000000150f000029000009e60000c13d000000000100001900006e8d0001043000001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c2302000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00000001020000390000053e0000013d000000400100043d00001c1b0200004100000cb20000013d000000400100043d00001c1e0200004100000cc30000013d000000400100043d00001c2002000041000000000021043500000004021000390000001003000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d00010430000000400100043d00001c210200004100000cb20000013d000000190300002900001ba40030009c00001ba403008041000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001bd6011001c76e8b6e860000040f0000000003010019000000600330027000001ba403300197000000400030008c000000400400003900000000040340190000001f0640018f0000006007400190000000190570002900000ce90000613d000000000801034f0000001909000029000000008a08043c0000000009a90436000000000059004b00000ce50000c13d000000000006004b00000cf60000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000f900000613d0000001f01400039000000e00210018f0000001901200029000000000021004b0000000002000039000000010200403900001bce0010009c0000010d0000213d00000001002001900000010d0000c13d000000400010043f000000400030008c00000ca20000413d0000001901000029000000000101043300000018020000290000000002020433002001e00000003d000001e00020043f001f01c00000003d000001c00010043f001e00010000003d000000200000043f00001bd70100004100001bd802000041000000000012041b001d00020000003d00001bd90100004100001bda02000041000000000012041b00001bdb0100004100001bdc02000041000000000012041b0000000401000039000000000010043f000000400200003900000000010000196e8b6e4e0000040f00001bdd02000041000000000021041b001c00050000003d0000000501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bde02000041000000000021041b0000000601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bdf02000041000000000021041b0000000701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be002000041000000000021041b0000000801000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be102000041000000000021041b0000000901000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be202000041000000000021041b0000000a01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be302000041000000000021041b0000000b01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be402000041000000000021041b0000000c01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be502000041000000000021041b0000000d01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be602000041000000000021041b0000000e01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be702000041000000000021041b0000000f01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be802000041000000000021041b0000001001000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001be902000041000000000021041b0000001101000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bea02000041000000000021041b0000001201000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001beb02000041000000000021041b0000001301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bec02000041000000000021041b0000001401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bed02000041000000000021041b0000001501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bee02000041000000000021041b0000001601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bef02000041000000000021041b0000001701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bf002000041000000000021041b0000001801000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f00001bf102000041000000000021041b0000000101000039000000000011041b000000000000043f0000000501000039000000200010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000101000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000201000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000001022001bf000000000021041b0000000501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000001022001bf000000000021041b0000000601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000001022001bf000000000021041b0000000701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000001022001bf000000000021041b0000000801000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000002022001bf000000000021041b0000000901000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000002022001bf000000000021041b0000000a01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000002022001bf000000000021041b0000000b01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000002022001bf000000000021041b0000000c01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000d01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000e01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000f01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000001001000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000004022001bf000000000021041b0000001101000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000004022001bf000000000021041b0000001201000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000004022001bf000000000021041b0000001301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000004022001bf000000000021041b0000001401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000005022001bf000000000021041b0000001501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000005022001bf000000000021041b0000001601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000005022001bf000000000021041b0000001701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000005022001bf000000000021041b0000000601000039000000200010043f00001bf201000041000000000201041a00001c2e02200197000000000021041b0000000401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000801000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000000c01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000001001000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000001401000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e02200197000000000021041b0000001e01000029001900000001001d000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001c01000029000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000901000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000d01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001101000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001501000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001d01000029001900000001001d000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000a01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000e01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001201000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000001601000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000019022001af000000000021041b0000000301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000b01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000000f01000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000001301000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b0000001701000039000000000010043f000000000100001900000040020000396e8b6e4e0000040f000000000201041a00001c2e0220019700000003022001bf000000000021041b000000800100043d000001400000044300000160001004430000002001000039000000a00200043d0000018000100443000001a000200443000000c00200043d0000004003000039000001c000300443000001e0002004430000006002000039000000e00300043d000002000020044300000220003004430000008002000039000001000300043d00000240002004430000026000300443000001200200043d000000a0030000390000028000300443000002a00020044300000022020000290000000002020433000000c003000039000002c000300443000002e00020044300000021020000290000000002020433000000e003000039000003000030044300000320002004430000010002000039000001800300043d000003400020044300000360003004430000012002000039000001a00300043d0000038000200443000003a0003004430000001f0200002900000000020204330000014003000039000003c000300443000003e0002004430000002002000029000000000202043300000160030000390000040000300443000004200020044300000100001004430000000c01000039000001200010044300001bf30100004100006e8c0001042e0000001f0530018f00001ba606300198000000400200043d000000000462001900000f9b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000f970000c13d000000000005004b00000fa80000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c0f0010009c00000fbe0000213d000000230010008c00000fbe0000a13d00000004020000390000000202200367000000000202043b00001bce0020009c00000fbe0000213d000000000121004900001c0f0010009c00000fbe0000213d000002440010008c00000fbe0000413d0000000401200039000000000001042d000000000100001900006e8d0001043000000000430104340000000001320436000000000003004b00000fcc0000613d000000000200001900000000052100190000000006240019000000000606043300000000006504350000002002200039000000000032004b00000fc50000413d000000000231001900000000000204350000001f0230003900001c2b022001970000000001210019000000000001042d00001c2f0010009c00000fd70000813d0000016001100039000000400010043f000000000001042d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c300010009c00000fe20000813d0000002001100039000000400010043f000000000001042d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c310020009c0000102d0000813d00000005042002100000003f0440003900001c0e05400197000000400400043d0000000005540019000000000045004b0000000006000039000000010600403900001bce0050009c0000102d0000213d00000001006001900000102d0000c13d000000400050043f0000000000240435000000a0022000c90000000002120019000000000032004b0000102b0000213d000000000012004b000010290000a13d00000002050003670000000006040019000000000713004900001c0f0070009c0000102b0000213d000000a00070008c0000102b0000413d000000400700043d00001bb40070009c0000102d0000213d000000a008700039000000400080043f000000000815034f000000000808043b000000050080008c0000102b0000213d00000000098704360000002008100039000000000a85034f000000000a0a043b00001ba700a0009c0000102b0000213d00000020066000390000000000a904350000002009800039000000000995034f000000000909043b000000400a70003900000000009a04350000004009800039000000000995034f000000000909043b000000600a70003900000000009a04350000006008800039000000000885034f000000000808043b000000800970003900000000008904350000000000760435000000a001100039000000000021004b000010000000413d0000000001040019000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c310020009c0000107f0000813d00000005042002100000003f0440003900001c0e05400197000000400400043d0000000005540019000000000045004b0000000006000039000000010600403900001bce0050009c0000107f0000213d00000001006001900000107f0000c13d000000400050043f0000000000240435000000c0022000c90000000002120019000000000032004b0000107d0000213d000000000012004b0000107b0000a13d00000002050003670000000006040019000000000713004900001c0f0070009c0000107d0000213d000000c00070008c0000107d0000413d000000400700043d00001bd40070009c0000107f0000213d000000c008700039000000400080043f000000000815034f000000000808043b000000050080008c0000107d0000213d00000000098704360000002008100039000000000a85034f000000000a0a043b00001ba700a0009c0000107d0000213d0000000000a904350000002009800039000000000995034f000000000909043b000000400a70003900000000009a04350000004009800039000000000995034f000000000909043b000000600a70003900000000009a04350000006009800039000000000995034f000000000909043b000000800a70003900000000009a04350000008008800039000000000885034f000000000808043b00001ba70080009c0000107d0000213d0000002006600039000000a00970003900000000008904350000000000760435000000c001100039000000000021004b0000104b0000413d0000000001040019000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d000104300001000000000002000000000f0100190000000001f2004900001c0f0010009c000012280000213d0000009f0010008c000012280000a13d000000400100043d00001c320010009c0000122a0000813d000000a006100039000000400060043f00000002040003670000000003f4034f000000000303043b00001bce0030009c000012280000213d0000000007f30019000000000372004900001c0f0030009c000012280000213d000001600030008c000012280000413d00001c330010009c0000122a0000213d0000020003100039000000400030043f000000000374034f000000000303043b00001ba70030009c000012280000213d00000000003604350000002003700039000000000534034f000000000505043b00001ba70050009c000012280000213d000000c00810003900000000005804350000002003300039000000000334034f000000000303043b00001bce0030009c000012280000213d00000000097300190000001f03900039000000000023004b000000000800001900001c0d0800804100001c0d0330019700001c0d05200197000000000a53013f000000000053004b000000000300001900001c0d0300404100001c0d00a0009c000000000308c019000000000003004b000012280000c13d000000000394034f000000000a03043b00001bce00a0009c0000122a0000213d0000000503a002100000003f0330003900001c0e03300197000000400800043d000000000b38001900000000008b004b0000000003000039000000010300403900001bce00b0009c0000122a0000213d00000001003001900000122a0000c13d00000020099000390000004000b0043f0000000000a80435000000a003a000c9000000000a93001900000000002a004b000012280000213d00000000009a004b000011030000a13d000000000b080019000000000392004900001c0f0030009c000012280000213d000000a00030008c000012280000413d000000400c00043d00001bb400c0009c0000122a0000213d000000a003c00039000000400030043f000000000394034f000000000303043b000000050030008c000012280000213d00000000033c0436000000200d900039000000000ed4034f000000000e0e043b00001ba700e0009c000012280000213d000000200bb000390000000000e304350000002003d00039000000000334034f000000000303043b000000400ec0003900000000003e04350000004003d00039000000000334034f000000000303043b000000600ec0003900000000003e04350000006003d00039000000000334034f000000000303043b000000800dc0003900000000003d04350000000000cb0435000000a0099000390000000000a9004b000010da0000413d000000e00310003900000000008304350000006003700039000000000334034f000000000303043b00001bce0030009c000012280000213d00000000097300190000001f03900039000000000023004b000000000800001900001c0d0800804100001c0d03300197000000000a53013f000000000053004b000000000300001900001c0d0300404100001c0d00a0009c000000000308c019000000000003004b000012280000c13d000000000394034f000000000a03043b00001bce00a0009c0000122a0000213d0000000503a002100000003f0330003900001c0e03300197000000400800043d000000000b38001900000000008b004b0000000003000039000000010300403900001bce00b0009c0000122a0000213d00000001003001900000122a0000c13d00000020099000390000004000b0043f0000000000a80435000000c003a000c9000000000a93001900000000002a004b000012280000213d00000000009a004b000011620000a13d000000000b080019000000000392004900001c0f0030009c000012280000213d000000c00030008c000012280000413d000000400c00043d00001bd400c0009c0000122a0000213d000000c003c00039000000400030043f000000000394034f000000000303043b000000050030008c000012280000213d00000000033c0436000000200d900039000000000ed4034f000000000e0e043b00001ba700e0009c000012280000213d0000000000e304350000002003d00039000000000334034f000000000303043b000000400ec0003900000000003e04350000004003d00039000000000334034f000000000303043b000000600ec0003900000000003e04350000006003d00039000000000334034f000000000303043b000000800ec0003900000000003e04350000008003d00039000000000334034f000000000303043b00001ba70030009c000012280000213d000000200bb00039000000a00dc0003900000000003d04350000000000cb0435000000c0099000390000000000a9004b000011320000413d000001000310003900000000008304350000008007700039000000000374034f000000000303043b000000040030008c000012280000213d000001200810003900000000003804350000002003700039000000000334034f000000000303043b000001400810003900000000003804350000004003700039000000000334034f000000000303043b000001600810003900000000003804350000006003700039000000000334034f000000000303043b000001800810003900000000003804350000008003700039000000000334034f000000000303043b000001a0081000390000000000380435000000a003700039000000000334034f000000000303043b000001c0081000390000000000380435000000c003700039000000000334034f000000000703043b0000000003610436000001e00610003900000000007604350000002006f00039000000000764034f000000000707043b00001c1f0070009c000012280000213d00000000007304350000002003600039000000000634034f000000000606043b00001c1f0060009c000012280000213d000000400710003900000000006704350000002007300039000000000374034f000000000303043b00001bce0030009c000012280000213d000000000af300190000001f03a00039000000000023004b000000000600001900001c0d0600804100001c0d03300197000000000853013f000000000053004b000000000300001900001c0d0300404100001c0d0080009c000000000306c019000000000003004b000012280000c13d0000000003a4034f000000000803043b00001bce0080009c0000122a0000213d0000001f0380003900001c2b033001970000003f0330003900001c2b03300197000000400900043d000000000b39001900000000009b004b0000000003000039000000010300403900001bce00b0009c0000122a0000213d00000001003001900000122a0000c13d000000200aa000390000004000b0043f0000000003890436000000000ba8001900000000002b004b000012280000213d000100000005001d00000000060f0019000000000ca4034f00001c2b0d8001980000001f0e80018f000000000bd30019000011ce0000613d000000000f0c034f000000000a03001900000000f50f043c000000000a5a04360000000000ba004b000011ca0000c13d00000000000e004b000011db0000613d0000000005dc034f000000030ae00210000000000c0b0433000000000cac01cf000000000cac022f000000000505043b000001000aa000890000000005a5022f0000000005a501cf0000000005c5019f00000000005b043500000000038300190000000000030435000000600310003900000000009304350000002003700039000000000334034f000000000303043b00001bce0030009c0000000105000029000012280000213d00000000076300190000001f03700039000000000023004b0000000006050019000000000500001900001c0d0500804100001c0d03300197000000000863013f000000000063004b000000000300001900001c0d0300404100001c0d0080009c000000000305c019000000000003004b000012280000c13d000000000374034f000000000303043b00001bce0030009c0000122a0000213d0000001f0530003900001c2b055001970000003f0550003900001c2b08500197000000400500043d0000000008850019000000000058004b0000000009000039000000010900403900001bce0080009c0000122a0000213d00000001009001900000122a0000c13d0000002009700039000000400080043f00000000073504360000000008930019000000000028004b000012280000213d000000000494034f00001c2b063001980000001f0830018f0000000002670019000012160000613d000000000904034f000000000a070019000000009b09043c000000000aba043600000000002a004b000012120000c13d000000000008004b000012230000613d000000000464034f0000000306800210000000000802043300000000086801cf000000000868022f000000000404043b0000010006600089000000000464022f00000000046401cf000000000484019f00000000004204350000000002370019000000000002043500000080021000390000000000520435000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d000104300006000000000002000300000001001d0000001f01100039000000000021004b000000000300001900001c0d0300404100061c0d0020019b00001c0d01100197000000060410014f000000060010006c000000000100001900001c0d0100204100001c0d0040009c000000000103c019000000000001004b000014080000613d00000002050003670000000301500360000000000101043b00001c310010009c0000140a0000813d00000005031002100000003f0430003900001c0e04400197000000400700043d0000000006470019000100000007001d000000000076004b0000000004000039000000010400403900001bce0060009c0000140a0000213d00000001004001900000140a0000c13d000000400060043f0000000104000029000000000014043500000003010000290000002006100039000200000036001d000000020020006b000014080000213d000000020060006c000014060000813d0000000104000029000012680000013d00000004040000290000002004400039000000000117001900000000000104350000008001a0003900000000003104350000000000a404350000002006600039000000020060006c000014060000813d000400000004001d000000000165034f000000000101043b00001bce0010009c000014080000213d0000000301100029000500000001001d000000200b1000390000000001b2004900001c0f0010009c000014080000213d000000a00010008c000014080000413d000000400a00043d00001bb400a0009c0000140a0000213d0000000001b5034f000000a00da000390000004000d0043f000000000101043b00001bce0010009c000014080000213d000000000eb100190000000001e2004900001c0f0010009c000014080000213d000001600010008c000014080000413d00001c3300a0009c0000140a0000213d0000020001a00039000000400010043f0000000001e5034f000000000101043b00001ba70010009c000014080000213d00000000001d04350000002001e00039000000000315034f000000000303043b00001ba70030009c000014080000213d000000c004a0003900000000003404350000002001100039000000000115034f000000000101043b00001bce0010009c000014080000213d0000000001e100190000001f03100039000000000023004b000000000400001900001c0d0400804100001c0d03300197000000060730014f000000060030006c000000000300001900001c0d0300404100001c0d0070009c000000000304c019000000000003004b000014080000c13d000000000315034f000000000703043b00001bce0070009c0000140a0000213d00000005037002100000003f0330003900001c0e03300197000000400f00043d00000000083f00190000000000f8004b0000000003000039000000010300403900001bce0080009c0000140a0000213d00000001003001900000140a0000c13d0000002003100039000000400080043f00000000007f0435000000a0017000c90000000007310019000000000027004b000014080000213d000000000037004b000012ea0000a13d00000000010f0019000000000432004900001c0f0040009c000014080000213d000000a00040008c000014080000413d000000400800043d00001bb40080009c0000140a0000213d000000a004800039000000400040043f000000000435034f000000000404043b000000050040008c000014080000213d00000000044804360000002009300039000000000c95034f000000000c0c043b00001ba700c0009c000014080000213d00000020011000390000000000c404350000002004900039000000000445034f000000000404043b000000400c80003900000000004c04350000004004900039000000000445034f000000000404043b000000600c80003900000000004c04350000006004900039000000000445034f000000000404043b000000800980003900000000004904350000000000810435000000a003300039000000000073004b000012c10000413d000000e001a000390000000000f104350000006001e00039000000000115034f000000000101043b00001bce0010009c000014080000213d0000000003e100190000001f01300039000000000021004b000000000400001900001c0d0400804100001c0d01100197000000060710014f000000060010006c000000000100001900001c0d0100404100001c0d0070009c000000000104c019000000000001004b000014080000c13d000000000135034f000000000701043b00001bce0070009c0000140a0000213d00000005017002100000003f0110003900001c0e04100197000000400100043d0000000008410019000000000018004b0000000004000039000000010400403900001bce0080009c0000140a0000213d00000001004001900000140a0000c13d0000002003300039000000400080043f0000000000710435000000c0047000c90000000007340019000000000027004b000014080000213d000000000037004b000013490000a13d000000000f010019000000000432004900001c0f0040009c000014080000213d000000c00040008c000014080000413d000000400800043d00001bd40080009c0000140a0000213d000000c004800039000000400040043f000000000435034f000000000404043b000000050040008c000014080000213d00000000044804360000002009300039000000000c95034f000000000c0c043b00001ba700c0009c000014080000213d0000000000c404350000002004900039000000000445034f000000000404043b000000400c80003900000000004c04350000004004900039000000000445034f000000000404043b000000600c80003900000000004c04350000006004900039000000000445034f000000000404043b000000800c80003900000000004c04350000008004900039000000000445034f000000000404043b00001ba70040009c000014080000213d000000200ff00039000000a009800039000000000049043500000000008f0435000000c003300039000000000073004b000013190000413d0000010003a0003900000000001304350000008001e00039000000000315034f000000000303043b000000040030008c000014080000213d0000012004a0003900000000003404350000002003100039000000000335034f000000000303043b0000014004a0003900000000003404350000004003100039000000000335034f000000000303043b0000016004a0003900000000003404350000006003100039000000000335034f000000000303043b0000018004a0003900000000003404350000008003100039000000000335034f000000000303043b000001a004a000390000000000340435000000a003100039000000000335034f000000000303043b000001c004a000390000000000340435000000c001100039000000000115034f000000000301043b0000000001da0436000001e004a00039000000000034043500000005030000290000004003300039000000000435034f000000000404043b00001c1f0040009c000014080000213d00000000004104350000002001300039000000000315034f000000000303043b00001c1f0030009c000014080000213d0000004004a000390000000000340435000000200c1000390000000001c5034f000000000101043b00001bce0010009c000014080000213d0000000007b100190000001f01700039000000000021004b000000000300001900001c0d0300804100001c0d01100197000000060410014f000000060010006c000000000100001900001c0d0100404100001c0d0040009c000000000103c019000000000001004b000014080000c13d000000000175034f000000000101043b00001bce0010009c0000140a0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000008430019000000000038004b0000000004000039000000010400403900001bce0080009c0000140a0000213d00000001004001900000140a0000c13d0000002004700039000000400080043f00000000071304360000000008410019000000000028004b000014080000213d000000000d45034f00001c2b091001980000000008970019000013b30000613d000000000e0d034f000000000f07001900000000e40e043c000000000f4f043600000000008f004b000013af0000c13d0000001f04100190000013c00000613d00000000099d034f0000000304400210000000000d080433000000000d4d01cf000000000d4d022f000000000909043b0000010004400089000000000949022f00000000044901cf0000000004d4019f0000000000480435000000000117001900000000000104350000006001a0003900000000003104350000002001c00039000000000115034f000000000101043b00001bce0010009c000014080000213d0000000007b100190000001f01700039000000000021004b000000000300001900001c0d0300804100001c0d01100197000000060410014f000000060010006c000000000100001900001c0d0100404100001c0d0040009c000000000103c019000000000001004b000014080000c13d000000000175034f000000000101043b00001bce0010009c0000140a0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000008430019000000000038004b0000000004000039000000010400403900001bce0080009c0000140a0000213d00000001004001900000140a0000c13d0000002004700039000000400080043f00000000071304360000000008410019000000000028004b000014080000213d000000000b45034f00001c2b091001980000000008970019000013f80000613d000000000c0b034f000000000d07001900000000c40c043c000000000d4d043600000000008d004b000013f40000c13d0000001f041001900000125e0000613d00000000099b034f0000000304400210000000000b080433000000000b4b01cf000000000b4b022f000000000909043b0000010004400089000000000949022f00000000044901cf0000000004b4019f00000000004804350000125e0000013d0000000101000029000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000301001900000000040304330000000001420436000000000004004b000014390000613d00000000020000190000002003300039000000000503043300000000670504340000000089070434000000060090008c0000143a0000813d0000000009910436000000000808043300001ba7088001970000000000890435000000400870003900000000080804330000004009100039000000000089043500000060087000390000000008080433000000600910003900000000008904350000008007700039000000000707043300001ba70770019700000080081000390000000000780435000000000606043300001ba706600197000000a007100039000000000067043500000040055000390000000005050433000000c0061000390000000000560435000000e0011000390000000102200039000000000042004b000014160000413d000000000001042d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400400003900000000044104360000000006020433000000400510003900000000006504350000006005100039000000000006004b000014520000613d000000000700001900000020022000390000000008020433000000000008004b0000000008000039000000010800c03900000000058504360000000107700039000000000067004b000014490000413d0000000001150049000000000014043500000000020304330000000001250436000000000002004b0000147c0000613d00000000040000190000002003300039000000000503043300000000670504340000000089070434000000060090008c0000147d0000813d0000000009910436000000000808043300001ba7088001970000000000890435000000400870003900000000080804330000004009100039000000000089043500000060087000390000000008080433000000600910003900000000008904350000008007700039000000000707043300001ba70770019700000080081000390000000000780435000000000606043300001ba706600197000000a007100039000000000067043500000040055000390000000005050433000000c0061000390000000000560435000000e0011000390000000104400039000000000024004b000014590000413d000000000001042d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430003200000000000200000000030100190000000102000039000000000102041a000000010010008c000023ea0000c13d0000000201000039001a00000002001d000e00000001001d000000000012041b0000010001300039001c00000001001d0000000201100367000000000101043b000000180010008c00001d0f0000813d000000000010043f0000000501000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c70000801002000039001e00000003001d6e8b6e860000040f000000010020019000001d0f0000613d000000000101043b000000000101041a001b00000001001d003200ff001001930000000601000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000001b050000290000001e04000029000000010020019000001d0f0000613d000000ff0250018f000000000101043b000000000101041a000a00000001001d003100ff00100193000000060020008c000024820000813d000000000002004b002f00000000003d002f00010000c03d003000000000003d003000010000603d000000010020008c000000000300003900000001030020390000000001000416001d00000001001d000000000001004b000014cc0000613d000000020020008c000014ce0000413d000000400100043d00001bf402000041000000000021043500000004021000390000000003000416000024030000013d000000010020008c0000242b0000a13d001800000003001d000000040020008c002d00000000003d002d00010000c03d002e00000000003d002e00010000603d0000000201000367000000fe0350018f000000040030008c000014da0000c13d0000001c04000029000000600440008a000000000141034f000000000101043b001600000001001d00001ba70010009c00001d0f0000213d000000020020008c0000000001000019000014fd0000413d000000020030008c000014f00000c13d00000000030004150000002a0330008a0000000503300210002c00010000003d000000040020008c0000000101000039000e00010000003d000014f60000613d000000050020008c000015030000c13d000e00000001001d000014f60000013d000000040020008c000014fc0000c13d0000000003000415000000290330008a0000000503300210002c00020000003d000100000003001d0000000501300270000000010100003f000200010000003d000b00010000003d000015120000013d0000000301000039002c00000001001d00000000030004150000002b0330008a0000000503300210000000050020008c000014ee0000613d00000002025001bf000000ff0220018f000000020020008c000100000003001d00000005023002700000150c0000c13d000000020200003f00000002020000390000150e0000013d000000030200003f0000000302000039000b00000002001d001a00000001001d000e00000001001d000200000000001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000023e00000613d0000001c0400002900000020034000390000000202000367000000000332034f0000004004400039000000000542034f000000000505043b000000000303043b000000000101043b000000000013004b000023ed0000213d000000000015004b000023ed0000a13d0000000003000031000000240030008c0000001e0900002900001d0f0000413d0000000401200370000000000101043b000000200010008c000023e70000c13d000002440030008c00001d0f0000413d0000022401200370000000000101043b000002400010008c000023e70000c13d000002840030008c00001d0f0000413d0000026401200370000000000101043b00001c370010009c000023e10000813d000000060110021000000260011000390000024405200370000000000505043b000000000015004b000023e70000c13d0000012401200370000000000101043b000000180010008c000023e70000813d000000c004400039000000000142034f000000000101043b00000000059300490000001f0550008a00001c0d0650019700001c0d07100197000000000867013f000000000067004b000000000600001900001c0d06004041000000000051004b000000000500001900001c0d0500804100001c0d0080009c000000000605c019000000000006004b00001d0f0000c13d0000000005910019000000000152034f000000000101043b00001bce0010009c00001d0f0000213d000000060610021000000000036300490000002005500039000000000035004b000000000600001900001c0d0600204100001c0d0330019700001c0d05500197000000000735013f000000000035004b000000000300001900001c0d0300404100001c0d0070009c000000000306c019000000000003004b00001d0f0000c13d000000200340008a000000000232034f000000400300043d000000000202043b000000000021004b000023f40000413d001900000003001d00001c380030009c000024250000813d0000001903000029000000e002300039000000400020043f00000060043000390000006002000039001700000004001d0000000000240435000000c0023000390000000000020435000000a00230003900000000000204350000008002300039000800000002001d00000000000204350000004002300039000700000002001d00000000000204350000000002030436001100000002001d0000000000020435000000400200043d000f00000002001d00001bb40020009c000024250000213d0000000a02000029000000ff0320018f0000000f02000029000000a002200039000000400020043f000900000003001d000000040030008c000024820000213d00000009020000290000000f03000029000000000523043600000080043000390000000b02000029000300000004001d00000000002404350000006006300039000000160200002900000000002604350000004007300039000000180200002900000000002704350000000e02000029001c00000005001d000000000025043500001c390010009c000024250000213d000000010210003900000005012002100000003f0310003900001c0e03300197000000400500043d0000000003350019000000000053004b0000000004000039000000010400403900001bce0030009c000024250000213d0000000100400190000024250000c13d001302000090003d001801e00090003d000000400030043f00000000082504360000000002000019000000400300043d00001bb40030009c000024250000213d000000a004300039000000400040043f000000800430003900000000000404350000006004300039000000000004043500000040043000390000000000040435000000200430003900000000000404350000000000030435000000000428001900000000003404350000002002200039000000000012004b000015bc0000413d000c00000008001d001400000007001d001500000006001d001600000005001d00001c100100004100000000001004430000000001000412000000040010044300000080010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b000000190200002900000000001204350000001c010000290000000003010433000000050030008c0000001e04000029000024820000213d0000000202000367000000000142034f000000000501043b00001ba70050009c00001d0f0000213d001200600040003d0000001201200360000000000401043b00001ba70040009c00001d0f0000213d000000400100043d00001bd40010009c000024250000213d000000c006100039000000400060043f000000200a10003900000000005a043500000000003104350000001206000029000d0040006000920000000d03200360000000000303043b000000400b10003900000000003b043500100020006000920000001003200360000000000503043b000000a00c10003900000000004c04350000006003100039000000800d10003900000000005d043500000000005304350000018004600039000000000442034f000000000404043b000000010540003a000023e10000613d00001c390040009c000024250000213d00000005065002100000003f0460003900001c0e07400197000000400400043d0000000007740019000000000047004b0000000008000039000000010800403900001bce0070009c000024250000213d0000000100800190000024250000c13d000000400070043f00000000075404360000001f0560018f000000000006004b000016290000613d00000000066700190000000002200368000000002802043c0000000007870436000000000067004b000016250000c13d000000000005004b000000170200002900000000004204350000000002010433000000050020008c000024820000213d0000001901000029000000000401043300000000050a043300000000060c043300000000070b0433000000000303043300000000080d0433000000400100043d000000c0091000390000000000890435000000a0081000390000000000380435000000800310003900000000007304350000004003100039000000000023043500001ba702600197000000e003100039000000000023043500001ba7025001970000006003100039000000000023043500000020021000390000000000420435000000e003000039000000000031043500001c130010009c000024250000213d00040000000d001d00050000000c001d00060000000b001d001b0000000a001d0000010003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000c0c000029000000140b000029000000150a00002900000016090000290000001e08000029000000010020019000001d0f0000613d000000170200002900000000020204330000000023020434000000000003004b0000233e0000613d000000000101043b0000000000120435000000400100043d00001bb40010009c0000001b03000029000000060400002900000005060000290000000405000029000024250000213d000000a002100039000000400020043f000000800210003900000000000204350000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435000000400100043d00001bd40010009c000024250000213d000000c002100039000000400020043f000000a00210003900000000000204350000008002100039000000000002043500000060021000390000000000020435000000400210003900000000000204350000002002100039000000000002043500000000000104350000001c010000290000000002010433000000050020008c000024820000213d000000400100043d00001bb40010009c000024250000213d0000000003030433000000000404043300000000050504330000000006060433000000a007100039000000400070043f00001ba70660019700000080071000390000000000670435000000600610003900000000005604350000004005100039000000000045043500001ba7033001970000002004100039000000000034043500000000002104350000000002090433000000000002004b0000233e0000613d00000000001c043500000002010003670000001802100360000000000202043b000000000002004b000017640000613d000000000c0000190000001302100360000000000302043b000000000200003100000000048200490000001f0440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00001d0f0000c13d0000000004830019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200440003900001c0d0650019700001c0d07400197000000000867013f000000000067004b000000000600001900001c0d06004041000000000054004b000000000500001900001c0d0500204100001c0d0080009c000000000605c019000000000006004b00001d0f0000c13d00000000003c004b0000233e0000813d0000000603c002100000000005340019000000000252004900001c0f0020009c00001d0f0000213d000000400020008c00001d0f0000413d000000400200043d00001ba80020009c000024250000213d0000004003200039000000400030043f000000000351034f000000000403043b00000000034204360000002005500039000000000151034f000000000501043b00001ba70050009c00001d0f0000213d000000000053043500000000060b0433000000050060008c000024820000213d000000400100043d00001bb40010009c000024250000213d00000000070a0433000000a008100039000000400080043f000000800810003900000000005804350000006005100039000000000045043500001ba70470019700000020051000390000000000450435000000000061043500000040041000390000000000040435000000010cc0003900000000040904330000000000c4004b0000233e0000a13d0000000504c0021000000020054000390000000004950019000000000014043500000000010904330000000000c1004b0000233e0000a13d00000000010b0433000000050010008c000024820000213d001c00000005001d000000400400043d00001bd40040009c000024250000213d00000000050a043300000000060204330000000002030433000000c003400039000000400030043f00001ba703200197000000a0024000390000000000320435000000800240003900000000006204350000006002400039000000000062043500001ba7055001970000002002400039000000000052043500000000001404350000004002400039000000000002043500000019020000290000000004020433000000400200043d000000e0072000390000000000370435000000c0032000390000000000630435000000a00320003900000000006304350000006003200039000000000053043500000040032000390000000000130435000000e001000039000000000112043600000000004104350000008003200039000000000003043500001c130020009c000024250000213d0000010003200039000000400030043f00001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c70000801002000039001b0000000c001d6e8b6e860000040f0000001b0c000029000000140b000029000000150a00002900000016090000290000001e08000029000000010020019000001d0f0000613d0000001702000029000000000202043300000000030204330000000000c3004b0000001c030000290000233e0000a13d0000000002230019000000000101043b000000000012043500000002010003670000001802100360000000000202043b00000000002c004b000016b30000413d000000400100043d0000002002100039000000170300002900000000030304330000000004030433000000000004004b0000000005020019000017740000613d000000000600001900000000050200190000002003300039000000000703043300000000057504360000000106600039000000000046004b0000176e0000413d0000000003150049000000200430008a00000000004104350000001f0330003900001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c000024250000213d0000000100400190000024250000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000c0f000029000000140e000029000000150d000029000000160c0000290000001e08000029000000010020019000001d0f0000613d000000000101043b00000008020000290000000000120435000000180100002900000020021000390000000201000367000000000221034f000000000302043b000000000200003100000000048200490000001f0440008a00001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00001d0f0000c13d0000000004830019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d000000200440003900000006053002100000000005520049000000000054004b000000000600001900001c0d0600204100001c0d0550019700001c0d07400197000000000857013f000000000057004b000000000500001900001c0d0500404100001c0d0080009c000000000506c019000000000005004b00001d0f0000c13d0000001805100360000000000505043b000000000035004b000017fd0000813d00000006065002100000000007640019000000000672004900001c0f0060009c00001d0f0000213d000000400060008c00001d0f0000413d000000400800043d00001ba80080009c000024250000213d0000004006800039000000400060043f000000000671034f000000000606043b00000000096804360000002007700039000000000771034f000000000807043b00001ba70080009c00001d0f0000213d000000000089043500000000090e0433000000050090008c000024820000213d000000400700043d00001bb40070009c000024250000213d000000000a0d0433000000a00b7000390000004000b0043f000000800b70003900000000008b04350000006008700039000000000068043500001ba706a0019700000020087000390000000000680435000000000097043500000040067000390000000000060435000000010550003900000000060c0433000000000056004b0000233e0000a13d000000050650021000000000066f0019000000000076043500000000060c0433000000000056004b000017c80000213d0000233e0000013d000000400200043d00001ba80020009c000024250000213d0000004001200039000000400010043f00000001010000390000000003120436000000400100043d00001c3a0010009c000024250000213d001c00000002001d0000008002100039000000400020043f0000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435001b00000003001d000000000013043500001c100100004100000000001004430000000001000412000000040010044300000060010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b0000001902000029000000000012043500000003010000290000000004010433000000050040008c000024820000213d0000001801000029000001400510008a0000000201000367000000000251034f000000000602043b00001ba70060009c0000001b0800002900001d0f0000213d000000400200043d00001c3a0020009c0000001c07000029000024250000213d0000008003200039000000400030043f0000002003200039000000000063043500000000004204350000002004500039000000000441034f000000000604043b00000040042000390000000000640435001800400050003d0000001801100360000000000101043b000000600520003900000000001504350000000001070433000000000001004b0000233e0000613d0000000000280435000000400800043d00001c3b0080009c000024250000213d0000002001800039000000400010043f0000000002020433000000050020008c000024820000213d00000019060000290000000006060433000000000303043300000000040404330000000005050433000000e0078000390000000000570435000000c0078000390000000000570435000000a00580003900000000004504350000006004800039000000000024043500001ba7023001970000008003800039000000000023043500000040028000390000000000620435000000c003000039000000000031043500001c130080009c000024250000213d001b00000008001d0000010003800039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000001d0f0000613d000000000301043b0000001b0100002900000000003104350000002002000039000000400100043d0000000002210436000000000032043500001ba80010009c000024250000213d0000004003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000001d0f0000613d000000000101043b0000000702000029000000000012043500001c1001000041000000000010044300000000010004120000000400100443000000a0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b000000190200002900000000001204350000001801000029000000800310008a0000000201300367000000000101043b00001ba70010009c00001d0f0000213d000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c70000801002000039001b00000003001d6e8b6e860000040f0000001b07000029000000010020019000001d0f0000613d0000000202000367000000000372034f00000019040000290000000006040433000000000101043b000000000101041a000000000503043b00001ba70050009c00001d0f0000213d0000002004700039000000000342034f000000000703043b00001ba70070009c00001d0f0000213d0000000f030000290000000008030433000000040080008c000024820000213d000000070300002900000000090304330000000803000029000000000a030433000000400300043d000000c00b30003900000000008b0435000000a0083000390000000000a8043500000080083000390000000000980435000000600830003900000000007804350000004007300039000000000057043500000020053000390000000000650435000000a006400039000000000662034f000000000606043b000000e0073000390000000000670435000000c006400039000000000662034f000000000606043b00000100073000390000000000670435000000e006400039000000000662034f000000000606043b000001200730003900000000006704350000010006400039000000000662034f000000000606043b00000140073000390000000000670435001b01200040003d0000001b02200360000000000202043b00000180043000390000000000140435000001600130003900000000002104350000018001000039000000000013043500001c160030009c000024250000213d000001a001300039000000400010043f00001ba40050009c00001ba4050080410000004001500210000000000203043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000160a000029000000010020019000001d0f0000613d000000000201043b000000110100002900000000002104350000001b01000029000001400310008a0000000201000367000000000431034f000000000504043b00001ba70050009c00001d0f0000213d000000200c3000390000000001c1034f000000000601043b00001ba70060009c00001d0f0000213d000000400100043d0000004003100039000000800400003900000000004304350000000002210436000000000300041100001ba703300197000c00000003001d00000000003204350000001c0b00002900000000030b043300000080021000390000000000320435000000a002100039000000000003004b0000194d0000613d0000000004000019000000200bb0003900000000070b04330000000089070434000000050090008c000024820000213d0000000009920436000000000808043300001ba70880019700000000008904350000004008700039000000000808043300000040092000390000000000890435000000600770003900000000070704330000006008200039000000000078043500000080022000390000000104400039000000000034004b000019380000413d00000000031200490000006004100039000000000034043500000000030a04330000000002320436000000000003004b0000196f0000613d0000000004000019000000200aa0003900000000070a04330000000089070434000000050090008c000024820000213d0000000009920436000000000808043300001ba7088001970000000000890435000000400870003900000000080804330000004009200039000000000089043500000060087000390000000008080433000000600920003900000000008904350000008007700039000000000707043300001ba70770019700000080082000390000000000780435000000a0022000390000000104400039000000000034004b000019550000413d000000000212004900001ba40020009c00001ba402008041000000600220021000001ba40010009c00001ba4010080410000004001100210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bcd011001c70000800d02000039000000030300003900001c3c04000041001c0000000c001d6e8b6e810000040f0000001c060000290000001e0f000029000000010020019000001d0f0000613d000000400300043d00001c3b0030009c000024250000213d00000011010000290000000001010433001b00000001001d0000002001300039000000400010043f0000000000030435000000400400043d00001ba80040009c000024250000213d0000004001400039000000400010043f00000001010000390000000005140436000000400100043d00001c3a0010009c000024250000213d0000008002100039000000400020043f0000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435000000000015043500000020076000390000000201000367000000000271034f000000000202043b00001ba70020009c00001d0f0000213d000000400600043d00001c3a0060009c000024250000213d0000008008600039000000400080043f000000200860003900000000002804350000000b0800002900000000008604350000002008700039000000000881034f000000000808043b000000400960003900000000008904350000004007700039000000000871034f000000000808043b000000600960003900000000008904350000000008040433000000000008004b0000233e0000613d00000000006504350000012005700039000000000551034f00000000060000310000000007f600490000001f0770008a000000000505043b00001c0d0850019700001c0d09700197000000000a98013f000000000098004b000000000800001900001c0d08004041000000000075004b000000000700001900001c0d0700804100001c0d00a0009c000000000807c019000000000008004b00001d0f0000c13d0000000007f50019000000000571034f000000000505043b00001bce0050009c00001d0f0000213d00000006085002100000000006860049000000200770003900001c0d0860019700001c0d09700197000000000a89013f000000000089004b000000000800001900001c0d08004041000000000067004b000000000600001900001c0d0600204100001c0d00a0009c000000000806c019000000000008004b00001d0f0000c13d00001c390050009c000024250000213d000000010850003900000005098002100000003f0690003900001c0e0a600197000000400600043d000000000aa6001900000000006a004b000000000b000039000000010b00403900001bce00a0009c000024250000213d0000000100b00190000024250000c13d001600a000f0003d001800c000f0003d001901a000f0003d0000004000a0043f0000000008860436000000000a000019000000400b00043d00001bb400b0009c000024250000213d000000a00cb000390000004000c0043f000000800cb0003900000000000c0435000000600cb0003900000000000c0435000000400cb0003900000000000c0435000000200cb0003900000000000c043500000000000b0435000000000c8a00190000000000bc0435000000200aa0003900000000009a004b000019fd0000413d0000000009f1034f000000000a09043b00001ba700a0009c00001d0f0000213d0000001209100360000000000909043b001c00000009001d00001ba70090009c00001d0f0000213d000000400b00043d00001bb400b0009c000024250000213d000000a009b00039000000400090043f0000002009b000390000000000a904350000000e0900002900000000009b04350000000d09100360000000000909043b000000400cb0003900000000009c0435000000100c100360000000000c0c043b000000800db000390000001c0e0000290000000000ed0435000000600db000390000000000cd0435000000000c06043300000000000c004b0000233e0000613d0000000000b80435000000020000006b00000000020a6019000000000900c01900001ba702200197000000000a00001900000000005a004b00001a5b0000813d000000060ba00210000000000c7b0019000000200bc00039000000000bb1034f000000000d0b043b00001ba700d0009c00001d0f0000213d000000400b00043d00001bb400b0009c000024250000213d000000a00eb000390000004000e0043f000000400eb0003900000000009e0435000000200eb0003900000000002e04350000001a0e0000290000000000eb0435000000000cc1034f000000000c0c043b000000800eb000390000000000de0435000000600db000390000000000cd0435000000010aa00039000000000c0604330000000000ac004b0000233e0000a13d000000050ca00210000000000c8c00190000000000bc0435000000000b0604330000000000ab004b00001a360000213d0000233e0000013d0000000902000029000000020020008c002700000000003d002700010000603d002600000000003d002600010000c03d002800000000003d0000000a02000029000000fe0220018f000000020020008c00000010020000290000004002200039000f00000002001d00001b720000c13d000000000221034f000000000202043b00001ba70020009c00001d0f0000213d0000000005000411000000000025004b00001b720000613d000000400900043d00001c3d0090009c000024250000213d0000014005900039000000400050043f00000080079000390000000000670435000000600890003900000000004804350000001c0400002900001ba704400197000000400a90003900000000004a04350000001b04000029000000000b490436000000000400041100000000004b0435000000400400043d00001c3b0040009c000024250000213d0000002005400039000000400050043f0000000000040435000000c0059000390000000000350435000000a00690003900000000004604350000000f0d000029000000a003d00039000000000331034f000000000403043b000000e0039000390000000000430435000000c004d00039000000000441034f000000000c04043b00000100049000390000000000c40435000000e00cd000390000000001c1034f000000000c01043b00000120019000390000000000c1043500001c3e0c000041000000400e00043d0000000000ce0435000000040ce00039000000200d0000390000000000dc04350000000009090433000000240ce0003900000000009c043500000000090b043300001ba709900197000000440be0003900000000009b043500000000090a043300001ba709900197000000640ae0003900000000009a043500000000090804330000014008000039000000840ae0003900000000008a04350000016408e00039000000000a0904330000000000a80435001c0000000e001d0000018408e0003900000000000a004b00001acd0000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c000024820000213d000000000ee80436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e8000390000000000de0435000000600cc00039000000000c0c0433000000600d8000390000000000cd04350000008008800039000000010bb000390000000000ab004b00001ab80000413d0000001c0b0000290000000009b80049000000240a90008a0000000009070433000000a407b000390000000000a70435000000000a0904330000000007a8043600000000000a004b00001af20000613d00000000080000190000002009900039000000000b09043300000000cd0b04340000000500d0008c000024820000213d000000000dd70436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d7000390000000000cd0435000000600cb00039000000000c0c0433000000600d7000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c7000390000000000bc0435000000a00770003900000001088000390000000000a8004b00001ad80000413d0000001c0c0000290000000008c70049000000240880008a0000000006060433000000c409c00039000000000089043500000000980604340000000006870436000000000008004b00001b040000613d0000000007000019000000000a670019000000000b790019000000000b0b04330000000000ba04350000002007700039000000000087004b00001afd0000413d000000000786001900000000000704350000001f0780003900001c2b0770019700000000087600190000000006c80049000000240760008a0000000006050433000000e405c00039000000000075043500000000070604330000000005780436000000000007004b00001b190000613d00000000080000190000002006600039000000000906043300000000059504360000000108800039000000000078004b00001b130000413d00000000030304330000010406c00039000000000036043500000000030404330000012404c0003900000000003404350000014403c00039000000000101043300000000001304350000000001000414000000040020008c00001b2a0000c13d0000000103000031000000200030008c0000002004000039000000000403401900001b5b0000013d0000000003c5004900001ba40030009c00001ba403008041000000600330021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000334019f00001ba40010009c00001ba401008041000000c001100210000000000131019f6e8b6e810000040f0000001c0c0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057c001900001b490000613d000000000801034f00000000090c0019000000008a08043c0000000009a90436000000000059004b00001b450000c13d000000000006004b00001b560000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000001e0f000029000024620000613d0000001f01400039000000600210018f0000000001c20019000000000021004b0000000002000039000000010200403900001bce0010009c000024250000213d0000000100200190000024250000c13d000000400010043f000000200030008c00001d0f0000413d00000000020c043300001c3f0020019800001d0f0000c13d00001c400220019700001c3e0020009c000024540000c13d00000002010003670000001202100360000000000202043b001c00000002001d0000001c0200002900001ba70020009c00001d0f0000213d00000011020000290000000002020433001b00000002001d001a022000f0003d0000001a02100360000000000202043b00000000030000310000000004f300490000001f0440008a00001c0d0540019700001c0d06200197000000000756013f000000000056004b000000000500001900001c0d05004041000000000042004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000005004b00001d0f0000c13d0000000004f20019000000000241034f000000000202043b00001bce0020009c00001d0f0000213d0000000006230049000000200540003900001c0d0460019700001c0d07500197000000000847013f000000000047004b000000000400001900001c0d04004041000000000065004b000000000600001900001c0d0600204100001c0d0080009c000000000406c019000000000004004b00001d0f0000c13d0000001f0420003900001c2b044001970000003f0440003900001c2b04400197000000400700043d0000000004470019000000000074004b0000000006000039000000010600403900001bce0040009c000024250000213d0000000100600190000024250000c13d000000400040043f001700000007001d00000000042704360000000006520019000000000036004b00001d0f0000213d000000000351034f00001c2b052001980000001f0620018f000000000154001900001bbd0000613d000000000703034f0000000008040019000000007907043c0000000008980436000000000018004b00001bb90000c13d000000000006004b00001bca0000613d000000000353034f0000000305600210000000000601043300000000065601cf000000000656022f000000000303043b0000010005500089000000000353022f00000000035301cf000000000363019f0000000000310435000000000124001900000000000104350000001b01000029000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f00000001002001900000001e0b00002900001d0f0000613d000000000201043b000000000102041a0000ff0000100190000023fb0000c13d00001c4200100198000023fe0000c13d000000ff0010019000001be90000c13d0000001c01000029001c00000002001d0000001b0200002900000017030000296e8b5c900000040f0000001c020000290000001e0b00002900001c4401000041000000000012041b00000011010000290000000001010433001300000001001d002500000001001d0000003201000029000000050010008c000024820000213d000000000500003900000001050060390000002d0000002a0000002e020000290000000005026019000000010010008c000000000700003900000001070060390000002f0000002a00000030030000290000000007036019000001c00cb00039000000000005004b00000000060c001900000019060060290000000204000367000000000664034f000000000606043b000000000007004b00001c1c0000613d0000000007b4034f000000000707043b00001ba70070009c00001d0f0000213d0000002008b00039000000000884034f000000000808043b000000000878019f0000000007000415000000230770008a0000000507700210000000000008004b002300000000003d002300010000c03d00001c440000c13d000000020010008c00001c220000c13d0000000008000415000000220880008a0000000508800210002200010000003d00001c2a0000013d0000000007000415000000240770008a0000000507700210002400000000003d000000020010008c00001c170000613d0000000008000415000000200880008a0000000508800210000000030010008c00000000090000390000000109006039002000000009001d00001c470000c13d0000001a09000029000002000990008a000000000994034f000000000909043b000000000009004b000000000a000039000000010a00c039000000050880027000000000080a001f000000050770027000000000070a001f00210000000a001d0000000007000415000000210770008a0000000507700210000000000009004b00001c440000c13d000000000005004b00001c4f0000613d0000001805400360000000000505043b000000000005004b0000000505700270000000000500003f000000010500c03f00001c510000613d000000400100043d00001c4e02000041000023cc0000013d0000000507700270000000000709001f001f00000009001d00000000070004150000001f0770008a0000000507700210000000000005004b00001c3d0000c13d0000000505700270000000000500003f000000400500043d001900000005001d00001ba80050009c000024250000213d00000019080000290000004005800039000000400050043f00000020078000390000006005000039001500000007001d00000000005704350000000000080435000000000003004b00001d230000613d0000001601400360000000000101043b00001ba70010009c00001d0f0000213d0000001602000029000000400320008a000000000234034f000000000202043b00001ba70020009c00001d0f0000213d0000000005030019001c00000005001d0000006003500039000000000334034f0000008005500039000000000454034f000000000504043b000000000403043b000000000300041100000019070000296e8b48f10000040f0000001e0d00002900001c5109d000990000001c08000029000001a00a80003900000002010003670000000002a1034f000000000302043b0000000002000031000000000492001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000200480008a000000000441034f000000000404043b001400000004001d000000000005004b00001d0f0000c13d000000000b000019001800000009001d00170000000a001d0000000004d30019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d00000000003b004b00001d110000813d0000000603b002100000000002230019000000000321034f000000000503043b001d001d00500073000023c70000413d0000002002200039000000000121034f000000000401043b00001ba70040009c00001d0f0000213d000000000005004b000023ca0000613d0000000001000414000000040040008c001c00000005001d001b00000004001d00001cbf0000c13d00000001010000310000000102000039000000000001004b00001cd30000c13d00001cfa0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000030500190000000005000019001a0000000b001d6e8b6e810000040f0000001a0b000029000000170a00002900000018090000290000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00001cfa0000613d00001bce0010009c000024250000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000613043600001c2b041001980000000003460019000000030500036700001ced0000613d000000000705034f000000007807043c0000000006860436000000000036004b00001ce90000c13d0000001f0110019000001cfa0000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b000023d20000613d00000002010003670000000002a1034f000000000302043b0000000002000031000000000492001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c019000000010bb00039000000000005004b00001c910000c13d000000000100001900006e8d0001043000000014030000290000001d0030006b000023c70000413d0000001201100360000000000401043b00001ba70040009c00001d0f0000213d000000140000006b000023ca0000613d0000000001000414000000040040008c001c00000004001d00001da60000c13d00000001020000390000000101000031000000000001004b00001db60000c13d00001dde0000013d000000010010008c00001e2d0000613d000000020010008c00001ede0000613d000000030010008c00001f610000c13d0000001601400360000000000101043b00001ba70010009c00001d0f0000213d0000001602000029000000400320008a000000000234034f000000000202043b00001ba70020009c00001d0f0000213d001c00000003001d0000001c030000290000006003300039000000000334034f0000001c050000290000008005500039000000000454034f000000000504043b000000000403043b00000000030004110000001907000029001d0000000c001d6e8b46c00000040f0000001c030000290000001d090000290000001e080000290000000201000367000000000231034f000000000202043b001700000002001d00001ba70020009c00001d0f0000213d000000000281034f000000200330008a000000000331034f000000000303043b001400000003001d000000000202043b001c00000002001d00001ba70020009c00001d0f0000213d00001c5104800099001800400090003d0000001802100360000000000302043b0000000002000031001a00000004001d000000000442001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000491034f000000000404043b001b00000004001d000000000005004b00001d0f0000c13d00000000090000190000000004830019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d000000000039004b00001f5b0000813d000000060390021000000000022300190000002003200039000000000331034f000000000303043b00001ba70030009c00001d0f0000213d000000000121034f000000000401043b0000001c0100002900000000020004110000001b050000290000001906000029001d00000009001d6e8b604a0000040f0000001d090000290000001e0800002900000002010003670000001802100360000000000302043b00000000020000310000001a0420002900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c0190000000109900039000000000005004b00001d6a0000c13d00001d0f0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c70000800902000039000000140300002900000000050000196e8b6e810000040f0000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00001dde0000613d00001bce0010009c000024250000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000713043600001c2b041001980000001f0510018f0000000003470019000000030600036700001dd10000613d000000000806034f000000008908043c0000000007970436000000000037004b00001dcd0000c13d000000000005004b00001dde0000613d000000000446034f0000000305500210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000000002004b000024090000613d00000014030000290000001d0930006b000020b10000a13d00000000020004140000000c04000029000000040040008c00001deb0000c13d0000000102000039000000000001004b00001dfd0000c13d00001e230000013d00001ba40020009c00001ba402008041000000c00120021000001bcd011001c7000080090200003900000000030900190000000005000019001d00000009001d6e8b6e810000040f0000001d090000290000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00001e230000613d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000613043600001c2b031001980000001f0410018f0000000001360019000000030500036700001e160000613d000000000705034f000000007807043c0000000006860436000000000016004b00001e120000c13d000000000004004b00001e230000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000000002004b000020b10000c13d000000400100043d0000002402100039000000000092043500001c4502000041000000000021043500000004021000390000000c03000029000023da0000013d0000001601400360000000000101043b00001ba70010009c00001d0f0000213d0000001602000029000000400320008a000000000234034f000000000202043b00001ba70020009c00001d0f0000213d0000000005030019001c00000005001d0000006003500039000000000334034f0000008005500039000000000454034f000000000504043b000000000403043b000000000300041100000019070000296e8b46c00000040f0000001e0d00002900001c5109d000990000001c08000029000001a00a80003900000002010003670000000002a1034f000000000302043b0000000002000031000000000492001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000200480008a000000000441034f000000000404043b001400000004001d000000000005004b00001d0f0000c13d000000000b000019001800000009001d00170000000a001d0000000004d30019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d00000000003b004b00001fdc0000813d0000000603b002100000000002230019000000000321034f000000000503043b001d001d00500073000023c70000413d0000002002200039000000000121034f000000000401043b00001ba70040009c00001d0f0000213d000000000005004b000023ca0000613d0000000001000414000000040040008c001c00000005001d001b00000004001d00001e8d0000c13d00000001010000310000000102000039000000000001004b00001ea10000c13d00001ec80000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000030500190000000005000019001a0000000b001d6e8b6e810000040f0000001a0b000029000000170a00002900000018090000290000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00001ec80000613d00001bce0010009c000024250000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000613043600001c2b041001980000000003460019000000030500036700001ebb0000613d000000000705034f000000007807043c0000000006860436000000000036004b00001eb70000c13d0000001f0110019000001ec80000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b000023d20000613d00000002010003670000000002a1034f000000000302043b0000000002000031000000000492001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c019000000010bb00039000000000005004b00001e5f0000c13d00001d0f0000013d0000001601400360000000000101043b00001ba70010009c00001d0f0000213d0000001602000029000000400320008a000000000234034f000000000202043b00001ba70020009c00001d0f0000213d001c00000003001d0000001c030000290000006003300039000000000334034f0000001c050000290000008005500039000000000454034f000000000504043b000000000403043b00000000030004110000001907000029001d0000000c001d6e8b48f10000040f0000001c030000290000001d090000290000001e080000290000000201000367000000000231034f000000000202043b001700000002001d00001ba70020009c00001d0f0000213d000000000281034f000000200330008a000000000331034f000000000303043b001400000003001d000000000202043b001c00000002001d00001ba70020009c00001d0f0000213d00001c5104800099001800400090003d0000001802100360000000000302043b0000000002000031001a00000004001d000000000442001900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05004041000000000043004b000000000400001900001c0d0400804100001c0d0070009c000000000504c019000000000491034f000000000404043b001b00000004001d000000000005004b00001d0f0000c13d00000000090000190000000004830019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d000000000039004b00001f5b0000813d000000060390021000000000022300190000002003200039000000000331034f000000000303043b00001ba70030009c00001d0f0000213d000000000121034f000000000401043b0000001c0100002900000000020004110000001b050000290000001906000029001d00000009001d6e8b604a0000040f0000001d090000290000001e0800002900000002010003670000001802100360000000000302043b00000000020000310000001a0420002900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c0190000000109900039000000000005004b00001f1f0000c13d00001d0f0000013d0000001c010000290000000002000411000000170300002900000014040000290000001b05000029000020ae0000013d0000000001b4034f000000000101043b000000000002004b000020320000613d00001ba70010009c00001d0f0000213d0000001202400360000000000302043b00001ba70030009c00001d0f0000213d0000000d024003600000001004400360000000000504043b000000000402043b000000000200041100000019070000296e8b48f10000040f0000001e0900002900000002010003670000001202100360000000000202043b001a00000002001d00001ba70020009c00001d0f0000213d00000012020000290000004004200039000000000241034f000000000202043b001800000002001d00001ba70020009c00001d0f0000213d00001c5105900099001b01600040003d0000001b02100360000000000302043b0000000002000031001400000005001d000000000552001900001c0d0650019700001c0d07300197000000000867013f000000000067004b000000000600001900001c0d06004041000000000053004b000000000500001900001c0d0500804100001c0d0080009c000000000605c0190000010004400039000000000441034f000000000404043b001700000004001d000000000006004b00001d0f0000c13d0000001b04000029000001200440008a000000000441034f000000000404043b001d00000004001d00000000080000190000000004930019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d000000000038004b000020a90000813d00000006038002100000000002230019000000000321034f000000000403043b001d001d00400073000023e10000413d0000002002200039000000000121034f000000000301043b00001ba70030009c00001d0f0000213d00000018010000290000001a0200002900000017050000290000001906000029001c00000008001d6e8b604a0000040f0000001c080000290000001e0900002900000002010003670000001b02100360000000000302043b0000000002000031000000140420002900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c0190000000108800039000000000005004b00001f9e0000c13d00001d0f0000013d00000014030000290000001d0030006b000023c70000413d0000001201100360000000000401043b00001ba70040009c00001d0f0000213d000000140000006b000023ca0000613d0000000001000414000000040040008c001c00000004001d00001fee0000c13d00000001020000390000000101000031000000000001004b00001ffe0000c13d000020260000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c70000800902000039000000140300002900000000050000196e8b6e810000040f0000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000020260000613d00001bce0010009c000024250000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000713043600001c2b041001980000001f0510018f00000000034700190000000306000367000020190000613d000000000806034f000000008908043c0000000007970436000000000037004b000020150000c13d000000000005004b000020260000613d000000000446034f0000000305500210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000000002004b000024090000613d00000014030000290000001d0330006b000020b10000a13d00000000020004140000000c04000029000000040040008c001d00000003001d0000238b0000c13d0000000102000039000023980000013d00001ba70010009c00001d0f0000213d0000001202400360000000000302043b00001ba70030009c00001d0f0000213d0000000d024003600000001004400360000000000504043b000000000402043b000000000200041100000019070000296e8b46c00000040f0000001e0900002900000002010003670000001202100360000000000202043b001a00000002001d00001ba70020009c00001d0f0000213d00000012020000290000004004200039000000000241034f000000000202043b001800000002001d00001ba70020009c00001d0f0000213d00001c5105900099001b01600040003d0000001b02100360000000000302043b0000000002000031001400000005001d000000000552001900001c0d0650019700001c0d07300197000000000867013f000000000067004b000000000600001900001c0d06004041000000000053004b000000000500001900001c0d0500804100001c0d0080009c000000000605c0190000010004400039000000000441034f000000000404043b001700000004001d000000000006004b00001d0f0000c13d0000001b04000029000001200440008a000000000441034f000000000404043b001d00000004001d00000000080000190000000004930019000000000341034f000000000303043b00001bce0030009c00001d0f0000213d00000006053002100000000005520049000000200240003900001c0d0450019700001c0d06200197000000000746013f000000000046004b000000000400001900001c0d04004041000000000052004b000000000500001900001c0d0500204100001c0d0070009c000000000405c019000000000004004b00001d0f0000c13d000000000038004b000020a90000813d00000006038002100000000002230019000000000321034f000000000403043b001d001d00400073000023e10000413d0000002002200039000000000121034f000000000301043b00001ba70030009c00001d0f0000213d00000018010000290000001a0200002900000017050000290000001906000029001c00000008001d6e8b604a0000040f0000001c080000290000001e0900002900000002010003670000001b02100360000000000302043b0000000002000031000000140420002900001c0d0540019700001c0d06300197000000000756013f000000000056004b000000000500001900001c0d05002041000000000043004b000000000400001900001c0d0400404100001c0d0070009c000000000504c0190000000108800039000000000005004b0000206b0000c13d00001d0f0000013d00000018010000290000001a0200002900000000030004110000001d04000029000000170500002900000019060000296e8b604a0000040f0000001e0d000029000000150100002900000000010104330000000001010433000000000001004b000021950000613d00000019010000290000000001010433001c00000001001d000000400100043d001d00000001001d000000200210003900001c4801000041001b00000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b0000001d0400002900000060024000390000001c030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000023e00000613d000000000101043b0000001d04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c000024250000213d0000001d02000029000000c001200039000000400010043f0000001b0100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000001d0f0000613d000000000101043b00001c4a02000041000000000020044300001ba701100197001d00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000023e00000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b000024120000613d0000001501000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b0000001e0d000029000021470000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c000024820000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000021280000413d00000000040004140000001d02000029000000040020008c000021500000c13d0000000103000031000000200030008c00000020040000390000000004034019000021820000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f001d0000000b001d6e8b6e810000040f0000001d0b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000021700000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b0000216c0000c13d000000000006004b0000217d0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000001e0d000029000024310000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c000024250000213d0000000100200190000024250000c13d000000400010043f000000200030008c00001d0f0000413d00000000010b043300001c3f0010019800001d0f0000c13d000000600100003900000015020000290000000000120435000000400100043d001c00000001001d00001ba80010009c000024250000213d0000001c020000290000004001200039000000400010043f000000010100003900000000021204360000000201000367000000000600003100000013030000290000000000320435000000400200043d001d00000002001d00001ba80020009c000024250000213d0000000102000029000000050220027000000000050200310000002c020000290000001d040000290000004007400039000000400070043f00000001030000390000000008340436000000400700043d00001c3a0070009c000024250000213d0000008009700039000000400090043f000000600970003900000000000904350000004009700039000000000009043500000020097000390000000000090435000000000007043500000000007804350000001607100360000000000707043b00001ba70070009c00001d0f0000213d000000400900043d00001c3a0090009c000024250000213d000000800a9000390000004000a0043f000000050050008c000024820000213d000000200a90003900000000007a043500000000005904350000001603000029000000200a300039000000000aa1034f000000000a0a043b000000400b9000390000000000ab0435000000400a300039000000000ba1034f000000000b0b043b000000600c9000390000000000bc04350000001d03000029000000000b03043300000000000b004b0000233e0000613d00000000009804350000000009d600490000012008a00039000000000881034f000000000808043b0000001f0990008a00001c0d0a90019700001c0d0b800197000000000cab013f0000000000ab004b000000000a00001900001c0d0a004041000000000098004b000000000900001900001c0d0900804100001c0d00c0009c000000000a09c01900000000000a004b00001d0f0000c13d000000000cd800190000000008c1034f000000000808043b00001bce0080009c00001d0f0000213d000000060980021000000000069600490000002009c0003900001c0d0a60019700001c0d0b900197000000000dab013f0000000000ab004b000000000a00001900001c0d0a004041000000000069004b000000000600001900001c0d0600204100001c0d00d0009c000000000a06c01900000000000a004b00001d0f0000c13d00001c390080009c000024250000213d000000010b800039000000050ab002100000003f06a0003900001c0e0d600197000000400600043d000000000dd6001900000000006d004b000000000e000039000000010e00403900001bce00d0009c000024250000213d0000000100e00190000024250000c13d0000004000d0043f000000000bb60436000000000d000019000000400e00043d00001bb400e0009c000024250000213d000000a00fe000390000004000f0043f000000800fe0003900000000000f0435000000600fe0003900000000000f0435000000400fe0003900000000000f0435000000200fe0003900000000000f043500000000000e0435000000000fbd00190000000000ef04350000001e03000029000000200dd000390000000000ad004b000022130000413d000000000a31034f000000000e0a043b00001ba700e0009c00001d0f0000213d000000120a100360000000000a0a043b00001ba700a0009c00001d0f0000213d000000400f00043d00001bb400f0009c000024250000213d000000a00df000390000004000d0043f000000050020008c000024820000213d000000200df000390000000000ed043500000000002f04350000000d0d100360000000000d0d043b0000004003f000390000000000d304350000001003100360000000000303043b0000008004f000390000000000a404350000006004f0003900000000003404350000000003060433000000000003004b0000233e0000613d0000000000fb0435000000010050008c0000000102006039000000050020008c000023160000a13d000000000008004b0000241d0000c13d000000280000002a000024820000c13d0000003102000029000000030020008c00000000020000390000000102006039000000260000002a0000002702006029000000000002004b000023880000613d0000000f02100360000000000202043b00001ba70020009c00001d0f0000213d0000000003000411000000000023004b000023880000613d000000400900043d00001c3d0090009c000024250000213d0000014003900039000000400030043f0000008007900039000000000067043500000060089000390000001d03000029000000000038043500001ba703a00197000000400a90003900000000003a04350000001303000029000000000b390436000000000300041100000000003b0435000000400400043d00001c3b0040009c000024250000213d0000002003400039000000400030043f0000000000040435000000c0059000390000001c030000290000000000350435000000a00690003900000000004604350000000f0d000029000000a003d00039000000000331034f000000000403043b000000e0039000390000000000430435000000c004d00039000000000441034f000000000c04043b00000100049000390000000000c40435000000e00cd000390000000001c1034f000000000c01043b00000120019000390000000000c1043500001c4d0c000041000000400f00043d0000000000cf0435000000040cf00039000000200d0000390000000000dc04350000000009090433000000240cf0003900000000009c043500000000090b043300001ba709900197000000440bf0003900000000009b043500000000090a043300001ba709900197000000640af0003900000000009a043500000000090804330000014008000039000000840af0003900000000008a04350000016408f00039000000000a0904330000000000a804350000018408f0003900000000000a004b000022bb0000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c000024820000213d000000000ee80436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e8000390000000000de0435000000600cc00039000000000c0c0433000000600d8000390000000000cd04350000008008800039000000010bb000390000000000ab004b000022a60000413d0000000009f80049000000240a90008a0000000009070433000000a407f000390000000000a70435000000000a0904330000000007a8043600000000000a004b000022df0000613d00000000080000190000002009900039000000000b09043300000000cd0b04340000000500d0008c000024820000213d000000000dd70436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d7000390000000000cd0435000000600cb00039000000000c0c0433000000600d7000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c7000390000000000bc0435000000a00770003900000001088000390000000000a8004b000022c50000413d0000000008f70049000000240880008a0000000006060433000000c409f00039000000000089043500000000980604340000000006870436000000000008004b000022f00000613d0000000007000019000000000a670019000000000b790019000000000b0b04330000000000ba04350000002007700039000000000087004b000022e90000413d000000000786001900000000000704350000001f0780003900001c2b0770019700000000087600190000000006f80049000000240760008a0000000006050433000000e405f00039000000000075043500000000070604330000000005780436000000000007004b000023050000613d00000000080000190000002006600039000000000906043300000000059504360000000108800039000000000078004b000022ff0000413d00000000030304330000010406f00039000000000036043500000000030404330000012404f0003900000000003404350000014403f00039000000000101043300000000001304350000000001000414000000040020008c000023440000c13d0000000103000031000000200030008c00000020040000390000000004034019000023750000013d000000010050008c00000000070ec019000000000d00601900001ba7057001970000000007000019000000000087004b0000224d0000813d0000000603700210000000000e9300190000002003e00039000000000331034f000000000f03043b00001ba700f0009c00001d0f0000213d000000400c00043d00001bb400c0009c000024250000213d000000a003c00039000000400030043f0000004003c000390000000000d304350000002003c00039000000000053043500000000002c04350000000003e1034f000000000303043b0000008004c000390000000000f404350000006004c00039000000000034043500000001077000390000000003060433000000000073004b0000233e0000a13d00000005037002100000000003b300190000000000c304350000000003060433000000000073004b0000231b0000213d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d000104300000000003f5004900001ba40030009c00001ba403008041000000600330021000001ba400f0009c00001ba40400004100000000040f40190000004004400210000000000343019f00001ba40010009c00001ba401008041000000c001100210000000000131019f001e0000000f001d6e8b6e810000040f0000001e0f0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057f0019000023640000613d000000000801034f00000000090f0019000000008a08043c0000000009a90436000000000059004b000023600000c13d000000000006004b000023710000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000024560000613d0000001f01400039000000600210018f0000000001f20019000000000021004b0000000002000039000000010200403900001bce0010009c000024250000213d0000000100200190000024250000c13d000000400010043f000000200030008c00001d0f0000413d00000000020f043300001c3f0020019800001d0f0000c13d00001c400220019700001c4d0020009c0000244f0000c13d0000000101000039000000000011041b000000000001042d00001ba40020009c00001ba402008041000000c00120021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f0000001e0d000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000023c00000613d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000024250000213d0000000100500190000024250000c13d000000400040043f000000000613043600001c2b031001980000001f0410018f00000000013600190000000305000367000023b30000613d000000000705034f000000007807043c0000000006860436000000000016004b000023af0000c13d000000000004004b000023c00000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000000002004b0000001d03000029000020b10000c13d000000400100043d0000002402100039000000000032043500001e280000013d000000400100043d00001c4702000041000023cc0000013d000000400100043d00001c4602000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00000024021000390000001c03000029000000000032043500001c4502000041000000000021043500000004021000390000001b03000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c36011001c700006e8d00010430000000000001042f00001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c5002000041000023cc0000013d000000400100043d00001c2302000041000023cc0000013d000000400100043d0000002402100039000000000052043500001c350200004100000000002104350000000402100039000023da0000013d00001c4f01000041000000000013043500001ba40030009c00001ba403008041000000400130021000001bd6011001c700006e8d00010430000000400100043d00001c1e02000041000024000000013d000000400100043d00001c4302000041000000000021043500000004021000390000001b03000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d00010430000000400100043d00000024021000390000001403000029000000000032043500001c4502000041000000000021043500000004021000390000001c03000029000023da0000013d00001c4c0100004100000000001b04350000001c0100002900000000001304350000001d01000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d000104300000004002c00039000000000121034f000000000101043b00001ba70010009c00001d0f0000213d000000400100043d00001bb40010009c000024800000a13d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001bf402000041000000000021043500000004021000390000000000020435000024040000013d0000001f0530018f00001ba606300198000000400200043d00000000046200190000243c0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000024380000c13d000000000005004b000024490000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c4102000041000000000021043500000004021000390000002503000029000024030000013d00001c4102000041000024000000013d0000001f0530018f00001ba606300198000000400200043d00000000046200190000246d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000245d0000c13d0000246d0000013d0000001f0530018f00001ba606300198000000400200043d00000000046200190000246d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000024690000c13d000000000005004b0000247a0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000121019f00006e8d00010430000000a001100039000000400010043f00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d000104300000000203000367000000000223034f000000000402043b000000000200003100000000051200490000001f0550008a00001c0d0650019700001c0d07400197000000000867013f000000000067004b000000000600001900001c0d06002041000000000054004b000000000500001900001c0d0500404100001c0d0080009c000000000605c019000000000006004b000024b10000613d0000000004140019000000000143034f000000000101043b00001bce0010009c000024b10000213d00001c2d031000d100000000022300190000002003400039000000000023004b000000000400001900001c0d0400204100001c0d0220019700001c0d03300197000000000523013f000000000023004b000000000200001900001c0d0200404100001c0d0050009c000000000204c019000000000002004b000024b10000c13d000000000001042d000000000100001900006e8d0001043000001c310020009c0000252e0000813d00000005052002100000003f0450003900001c0e06400197000000400400043d0000000006640019000000000046004b0000000007000039000000010700403900001bce0060009c0000252e0000213d00000001007001900000252e0000c13d000000400060043f00000000002404350000000002150019000000000032004b0000252c0000213d000000000012004b0000252a0000a13d000000020500036700000000060400190000000007010019000024d30000013d0000002006600039000000800a80003900000000009a043500000000008604350000002007700039000000000027004b0000252a0000813d000000000875034f000000000808043b00001bce0080009c0000252c0000213d0000000009180019000000000893004900001c0f0080009c0000252c0000213d000000a00080008c0000252c0000413d000000400800043d00001bb40080009c0000252e0000213d000000a00a8000390000004000a0043f000000000a95034f000000000a0a043b000000000ba80436000000200a900039000000000ca5034f000000000c0c043b0000000100c0008c0000252c0000213d0000000000cb0435000000200ba00039000000000bb5034f000000000b0b043b000000400c8000390000000000bc0435000000400ba00039000000000bb5034f000000000b0b043b000000600c8000390000000000bc0435000000600aa00039000000000aa5034f000000000a0a043b00001bce00a0009c0000252c0000213d000000000a9a00190000001f09a00039000000000039004b000000000b00001900001c0d0b00804100001c0d0990019700001c0d0c300197000000000dc9013f0000000000c9004b000000000900001900001c0d0900404100001c0d00d0009c00000000090bc019000000000009004b0000252c0000c13d0000000009a5034f000000000b09043b00001bce00b0009c0000252e0000213d000000050cb002100000003f09c0003900001c0e0d900197000000400900043d000000000dd9001900000000009d004b000000000e000039000000010e00403900001bce00d0009c0000252e0000213d0000000100e001900000252e0000c13d0000004000d0043f0000000000b90435000000200aa00039000000000bca001900000000003b004b0000252c0000213d0000000000ba004b000024cc0000813d000000000c090019000000000da5034f000000000d0d043b000000200cc000390000000000dc0435000000200aa000390000000000ba004b000025220000413d000024cc0000013d0000000001040019000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001ba701100197000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000025440000613d000000000101043b000000000101041a000000000001042d000000000100001900006e8d00010430000d000000000002000300000002001d000400000001001d0000004001100039000a00000001001d0000000001010433000000000101043300001c310010009c000027240000813d00000005021002100000003f0320003900001c0e03300197000000400700043d0000000003370019000000000073004b0000000004000039000000010400403900001bce0030009c000027240000213d0000000100400190000027240000c13d000000400030043f0000000001170436000700000001001d0000001f0320018f00000000010000310000000201100367000000000002004b0000256a0000613d00000007050000290000000002250019000000000401034f000000004604043c0000000005650436000000000025004b000025660000c13d000000000003004b00000004020000290000014002200039000900000002001d000000000302043300001bce0030009c000027240000213d00000005023002100000003f0420003900001c0e04400197000000400600043d0000000004460019000000000064004b0000000005000039000000010500403900001bce0040009c000027240000213d0000000100500190000027240000c13d000000400040043f0000000003360436000600000003001d0000001f0320018f000000000002004b000025890000613d00000006040000290000000002240019000000001501043c0000000004540436000000000024004b000025850000c13d000d00000007001d000800000006001d000000000003004b00001c100100004100000000001004430000000001000412000000040010044300000060010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000027320000613d000000000101043b000500000001001d0000000a0100002900000000010104330000000002010433000000000002004b000025e80000613d0000000004000019000b0005004002180000000b01100029000000200110003900000000010104330000000032010434000000060020008c0000272c0000813d000c00000004001d0000000003030433000000400410003900000000040404330000006005100039000000000505043300000080011000390000000006010433000000400100043d000000c0071000390000000000670435000000a0061000390000000000560435000000800510003900000000004504350000004004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000005030000290000000000320435000000c003000039000000000031043500001c120010009c000027240000213d000000e003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d0000000d0200002900000000020204330000000c04000029000000000042004b0000271e0000a13d0000000b030000290000000702300029000000000101043b000000000012043500000001044000390000000a0100002900000000010104330000000002010433000000000024004b000025a30000413d00001c100100004100000000001004430000000001000412000000040010044300000080010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000027320000613d000000000101043b000a00000001001d00000009010000290000000001010433000000000001004b0000000d07000029000026500000613d0000000401000029000700600010003d0000000004000019000000070100002900000000010104330000000002010433000000000042004b0000271e0000a13d000b0005004002180000000b01100029000000200110003900000000010104330000000032010434000000050020008c0000272c0000213d000c00000004001d0000000003030433000000a0041000390000000004040433000000400510003900000000050504330000006006100039000000000606043300000080011000390000000007010433000000400100043d000000c0081000390000000000780435000000a0071000390000000000670435000000800610003900000000005604350000004005100039000000000025043500001ba702400197000000e004100039000000000024043500001ba7023001970000006003100039000000000023043500000020021000390000000a030000290000000000320435000000e003000039000000000031043500001c130010009c000027240000213d0000010003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d000000080200002900000000020204330000000c04000029000000000042004b0000000d070000290000271e0000a13d0000000b030000290000000602300029000000000101043b0000000000120435000000010440003900000009010000290000000001010433000000000014004b000026010000413d000000400100043d000000200210003900000004030000290000000034030434000d00000004001d0000000003030433000c00000003001d0000000003070433000000000003004b0000000004020019000026630000613d000000000500001900000000040200190000002007700039000000000607043300000000046404360000000105500039000000000035004b0000265d0000413d0000000003140049000000200430008a00000000004104350000001f0330003900001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c000027240000213d0000000100400190000027240000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d000000400200043d0000002003200039000000000101043b000b00000001001d00000008070000290000000001070433000000000001004b0000000004030019000026940000613d000000000500001900000000040300190000002007700039000000000607043300000000046404360000000105500039000000000015004b0000268e0000413d0000000001240049000000200410008a00000000004204350000001f0110003900001c2b041001970000000001240019000000000041004b0000000004000039000000010400403900001bce0010009c000027240000213d0000000100400190000027240000c13d000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d000000000101043b000a00000001001d000000040100002900000080011000390000000001010433000900000001001d000000040010008c0000272c0000213d000000040200002900000120012000390000000001010433000100000001001d00000100012000390000000001010433000200000001001d000000e0012000390000000001010433000500000001001d000000c0012000390000000001010433000600000001001d000000a0012000390000000001010433000700000001001d000000400100043d000800000001001d00001c1001000041000000000010044300000000010004120000000400100443000000a0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000027320000613d0000000d0200002900001ba7022001970000000c0300002900001ba703300197000000000401043b0000000806000029000001800160003900000003050000290000000000510435000001600160003900000001050000290000000000510435000001400160003900000002050000290000000000510435000001200160003900000005050000290000000000510435000001000160003900000006050000290000000000510435000000e00160003900000007050000290000000000510435000000c00160003900000009050000290000000000510435000000a0016000390000000a05000029000000000051043500000080016000390000000b0500002900000000005104350000006001600039000000000031043500000040016000390000000000210435000000200160003900000000004104350000018002000039000000000026043500001c160060009c000027240000213d000001a002600039000000400020043f00001ba40010009c00001ba4010080410000004001100210000000000206043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000272a0000613d000000000101043b000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000400100043d00001c380010009c000027470000813d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000000000001042d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000d000000000002000200000001001d0000000021010434000100000002001d000300000001001d00001c310010009c000028c90000813d000000030100002900000005011002100000003f0210003900001c0e02200197000000400300043d0000000002230019000800000003001d000000000032004b0000000003000039000000010300403900001bce0020009c000028c90000213d0000000100300190000028c90000c13d000000400020043f000000030200002900000008030000290000000003230436000700000003001d000000000002004b000028c10000613d00000000020000190000006005000039000000400300043d00001c120030009c000028c90000213d000000e004300039000000400040043f000000c0043000390000000000540435000000a0043000390000000000540435000000400430003900000000005404350000002004300039000000000054043500000080043000390000000000040435000000600430003900000000000404350000000000030435000000070420002900000000003404350000002002200039000000000012004b0000276b0000413d0000000001000031000400020010036b000000000200001900000002010000290000000001010433000a00000002001d000000000021004b000028c30000a13d000000400100043d00001c120010009c000028c90000213d0000000a020000290000000503200210000600000003001d0000000102300029000000000202043300000000240204340000000002020433000500000002001d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000900000004001d0000004001400039000000000401043300000000e204043400001bce0020009c000028c90000213d00000005012002100000003f0310003900001c0e03300197000000400c00043d00000000033c00190000000000c3004b0000000005000039000000010500403900001bce0030009c000028c90000213d0000000100500190000028c90000c13d000000400030043f00000000032c0436000000000002004b000027cd0000613d0000000002000019000000400500043d00001c3a0050009c000028c90000213d0000008006500039000000400060043f0000006006500039000000000006043500000040065000390000000000060435000000200650003900000000000604350000000000050435000000000623001900000000005604350000002002200039000000000012004b000027bc0000413d000000000104043300001bce0010009c000028c90000213d00000005021002100000003f0520003900001c0e05500197000000400600043d0000000005560019000d00000006001d000000000065004b0000000006000039000000010600403900001bce0050009c000028c90000213d0000000100600190000028c90000c13d000000400050043f0000000d050000290000000001150436000000000002004b000027e90000613d0000000005210019000000040600035f0000000007010019000000006806043c0000000007870436000000000057004b000027e50000c13d0000001f002001900000000002040433000000000002004b000028190000613d0000000005000019000000050250021000000000062e0019000000000a06043300000000b90a0434000000060090008c000028cf0000813d000000400700043d00001c3a0070009c000028c90000213d0000006006a0003900000000080b0433000000400aa00039000000000a0a0433000000000b060433000000800f7000390000004000f0043f000000600f7000390000000000bf0435000000400b7000390000000000ab043500001ba708800197000000200a70003900000000008a0435000000000097043500000000080c0433000000000058004b000028c30000a13d0000000008230019000000000078043500000000070c0433000000000057004b000028c30000a13d0000000d070000290000000007070433000000000057004b000028c30000a13d00000000021200190000000006060433000000000062043500000001055000390000000002040433000000000025004b000027ee0000413d000000090100002900000060011000390000000001010433000c00000001001d0000000012010434000b00000001001d00001bce0020009c000028c90000213d00000005012002100000003f0310003900001c0e03300197000000400e00043d00000000033e00190000000000e3004b0000000005000039000000010500403900001bce0030009c000028c90000213d0000000100500190000028c90000c13d000000400030043f00000000032e0436000000000002004b000028450000613d0000000002000019000000400500043d00001bb40050009c000028c90000213d000000a006500039000000400060043f000000800650003900000000000604350000006006500039000000000006043500000040065000390000000000060435000000200650003900000000000604350000000000050435000000000623001900000000005604350000002002200039000000000012004b000028320000413d0000000c01000029000000000501043300001bce0050009c000028c90000213d00000005025002100000003f0120003900001c0e06100197000000400100043d0000000006610019000000000016004b0000000007000039000000010700403900001bce0060009c000028c90000213d0000000100700190000028c90000c13d000000400060043f0000000007510436000000000002004b000028600000613d0000000005270019000000040600035f0000000008070019000000006906043c0000000008980436000000000058004b0000285c0000c13d0000001f002001900000000c020000290000000002020433000000000002004b000028980000613d000000000500001900000005025002100000000b06200029000000000a06043300000000890a0434000000050090008c000028cf0000213d000000400b00043d00001bb400b0009c000028c90000213d0000006006a000390000000008080433000000400da00039000000000d0d04330000000004060433000000a00aa00039000000000a0a0433000000000f0c0019000000a00cb000390000004000c0043f00001ba70aa00197000000800cb000390000000000ac0435000000000c0f0019000000600ab0003900000000004a04350000004004b000390000000000d4043500001ba7048001970000002008b00039000000000048043500000000009b043500000000040e0433000000000054004b000028c30000a13d00000000042300190000000000b4043500000000040e0433000000000054004b000028c30000a13d0000000004010433000000000054004b000028c30000a13d00000000027200190000000004060433000000000042043500000001055000390000000c020000290000000002020433000000000025004b000028660000413d000000400200043d00001c120020009c000028c90000213d000000050300002900001c1f033001970000000905000029000000000405043300000120055000390000000005050433000000e006200039000000400060043f000000c0062000390000000000160435000000a0012000390000000d060000290000000000610435000000800120003900000000003104350000006001200039000000000051043500000040012000390000000000e1043500000020012000390000000000c1043500001ba7014001970000000000120435000000080100002900000000010104330000000a0010006c000028c30000a13d000000060300002900000007013000290000000000210435000000080100002900000000010104330000000a0010006c000028c30000a13d0000000a020000290000000102200039000000030020006c000027850000413d0000000801000029000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000f000000000002000400000008001d000700000007001d000e00000006001d000f00000004001d000300000001001d000000800020043f000000a00090043f000000400400043d00001c520040009c00002c720000813d0000006001400039000000400010043f00000020014000390000000000a104350000000000040435000000a00100043d00001ba70110019700000040024000390000000000120435000000800200043d0000000301000029000d00000005001d6e8b4b140000040f0000000d04000029000100000001001d000200000002001d00001bce0040009c00002c720000213d00000005014002100000003f0210003900001c0e02200197000000400900043d0000000002290019000000000092004b0000000003000039000000010300403900001bce0020009c00002c720000213d000000010030019000002c720000c13d0000000003000031000000400020043f000000000a4904360000000f01100029000000000031004b00002c7e0000213d0000000f0010006c000029530000a13d000000020200036700001c0d0430019700000000050900190000000f06000029000029100000013d000000200550003900000000007504350000002006600039000000000016004b000029530000813d000000000762034f000000000707043b00001bce0070009c00002c7e0000213d0000000f087000290000001f07800039000000000037004b000000000b00001900001c0d0b00804100001c0d07700197000000000c47013f000000000047004b000000000700001900001c0d0700404100001c0d00c0009c00000000070bc019000000000007004b00002c7e0000c13d000000000782034f000000000b07043b00001bce00b0009c00002c720000213d0000000507b002100000003f0770003900001c0e0c700197000000400700043d000000000cc7001900000000007c004b000000000d000039000000010d00403900001bce00c0009c00002c720000213d0000000100d0019000002c720000c13d00000020088000390000004000c0043f0000000000b70435000000060bb00210000000000b8b001900000000003b004b00002c7e0000213d00000000008b004b0000290b0000a13d000000000c070019000000000d83004900001c0f00d0009c00002c7e0000213d0000004000d0008c00002c7e0000413d000000400d00043d00001ba800d0009c00002c720000213d000000200cc00039000000400ed000390000004000e0043f000000000e82034f000000000e0e043b000000000eed0436000000200f800039000000000ff2034f000000000f0f043b0000000000fe04350000000000dc043500000040088000390000000000b8004b0000293c0000413d0000290b0000013d000000070100002900001bce0010009c00002c720000213d000000070100002900000005011002100000003f0210003900001c0e02200197000000400400043d0000000002240019000600000004001d000000000042004b0000000004000039000000010400403900001bce0020009c00002c720000213d000000010040019000002c720000c13d000000400020043f000000070200002900000006040000290000000002240436000500000002001d0000000e01100029000000000031004b00002c7e0000213d0000000e06000029000000000061004b000029be0000a13d000000020200036700001c0d043001970000000605000029000029780000013d000000200550003900000000007504350000002006600039000000000016004b000029bb0000813d000000000762034f000000000707043b00001bce0070009c00002c7e0000213d0000000e087000290000001f07800039000000000037004b000000000b00001900001c0d0b00804100001c0d07700197000000000c47013f000000000047004b000000000700001900001c0d0700404100001c0d00c0009c00000000070bc019000000000007004b00002c7e0000c13d000000000782034f000000000b07043b00001bce00b0009c00002c720000213d0000000507b002100000003f0770003900001c0e0c700197000000400700043d000000000cc7001900000000007c004b000000000d000039000000010d00403900001bce00c0009c00002c720000213d0000000100d0019000002c720000c13d00000020088000390000004000c0043f0000000000b70435000000060bb00210000000000b8b001900000000003b004b00002c7e0000213d00000000008b004b000029730000a13d000000000c070019000000000d83004900001c0f00d0009c00002c7e0000213d0000004000d0008c00002c7e0000413d000000400d00043d00001ba800d0009c00002c720000213d000000200cc00039000000400ed000390000004000e0043f000000000e82034f000000000e0e043b000000000eed0436000000200f800039000000000ff2034f000000000f0f043b0000000000fe04350000000000dc043500000040088000390000000000b8004b000029a40000413d000029730000013d00000006010000290000000001010433000700000001001d0000000002090433000800000002001d000000070020002a00002cb30000413d0000000802000029000000070220002900001bce0020009c00002c720000213d00000005012002100000003f0310003900001c0e03300197000000400400043d0000000003340019000b00000004001d000000000043004b0000000004000039000000010400403900001bce0030009c00002c720000213d000000010040019000002c720000c13d000000400030043f0000000b030000290000000003230436000900000003001d000000000002004b000029f50000613d0000000002000019000000400300043d00001bd10030009c00002c720000213d0000006004300039000000400040043f00001c130030009c00002c720000213d0000010005300039000000400050043f00000000000404350000000004430436000000e0053000390000000000050435000000c0053000390000000000050435000000a005300039000000000005043500000080053000390000000000050435000000400530003900000000000504350000000000040435000000090420002900000000003404350000002002200039000000000012004b000029da0000413d000001000000043f000000080000006b000000010c00003900002b100000613d00000000010000190000000002090433000000000012004b00002c780000a13d000000050110021000000000011a00190000000001010433000001200010043f000000400100043d00001bd10010009c00002c720000213d0000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400100043d000001200200043d0000000002020433000000000002004b00002ca40000613d00001bd10010009c00002c720000213d0000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400600043d00001bd10060009c00002c720000213d0000006001600039000000400010043f00001c130060009c00002c720000213d0000010002600039000000400020043f00000000000104350000000001160436000000e0026000390000000000020435000000c0026000390000000000020435000000a002600039000000000002043500000080026000390000000000020435000000400260003900000000000204350000000000010435000000c00000043f000000400100043d00001c120010009c00002c720000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000000e00000043f000001200500043d0000000001050433000000000001004b00002aff0000613d000000800700043d000000000400001900002a700000013d0000000001050433000000000001004b00000000010000390000000101006039000000e00010043f000000000005043500002c8f0000613d000001200500043d000000800700043d00000001044000390000000001050433000000000014004b00002aff0000813d000000050140021000000000021500190000002002200039000000000202043300000000320204340000000008070433000000000082004b00002c8f0000813d00000005022002100000000002720019000000200220003900000000020204330000008008200039000000000808043300001c1f0080019800002a6c0000613d000000000303043300000020082000390000000008080433000000000b0804330000000000b3004b00002a6c0000813d0000000503300210000000000383001900000020033000390000000003030433000000c00500043d000000000005004b00002abe0000613d0000006001300039000000000501043300000000780604340000006008800039000000000b0804330000000000b5001a00002cb30000413d0000000005b500190000000000580435000000400530003900000000080504330000000005060433000000400b500039000000000b0b043300000000008b004b00002c890000c13d00000000080204330000000007070433000000000778013f00001ba70070019800002c890000c13d0000006002200039000000000202043300000040076000390000000007070433000000000027004b00002c890000c13d0000000025050434000000060050008c00002c9e0000813d0000000037030434000000050070008c00002c9e0000213d000000000075004b00002c890000c13d000000000303043300000000050204330000000002010433000000000002004b00000000070000390000000107006039000000e00070043f000000000353013f00001ba70030019800002c8e0000c13d0000000000010435000000000002004b00002a6a0000c13d00002c8f0000013d000000c000c0043f0000000056030434000000050060008c00002c9e0000213d000000400700043d00001bb40070009c00002c720000213d00000000080504330000004005300039000000000b05043300000060053000390000000003050433000000a00c7000390000004000c0043f000000600c70003900000000003c0435000000010c00003900000040037000390000000000b3043500001ba7038001970000002008700039000000000038043500000000006704350000008003700039000000a00600043d00001ba7066001970000000000630435000000400600043d00001bd10060009c00002c720000213d0000000003020433000000600220003900000000020204330000006008600039000000400080043f0000004008600039000000000028043500001ba702300197000000200360003900000000002304350000000000760435000000000004004b00002a630000613d000001200200043d0000000032020434000000000002004b00002c780000613d000000000042004b00002c780000a13d0000000002030433000000000713001900000000070704330000000000730435000001200300043d0000000007030433000000000047004b00002c780000a13d000000000131001900000020011000390000000000210435000001200100043d0000000001010433000000000041004b00002a630000213d00002c780000013d0000000b010000290000000002010433000001000100043d000000000012004b00002c780000a13d0000000501100210000000090110002900000000006104350000000b010000290000000002010433000001000100043d000000000012004b00002c780000a13d0000000101100039000001000010043f000000080010006c000029fa0000413d000000070000006b00002c690000613d000000000900001900000006010000290000000001010433000000000091004b00002c780000a13d000000400100043d00001bd10010009c00002c720000213d00000005029002100000000502200029000000000b0204330000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400100043d00000000320b0434000a00000003001d000000000002004b00002ca90000613d00001bd10010009c00002c720000213d0000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400100043d00001bd10010009c00002c720000213d0000006002100039000000400020043f00001c130010009c00002c720000213d0000010003100039000000400030043f00000000000204350000000002210436000000e0031000390000000000030435000000c0031000390000000000030435000000a003100039000000000003043500000080031000390000000000030435000000400110003900000000000104350000000000020435000000400d00043d00001bb400d0009c00002c720000213d000000800e00043d000000a001d00039000000400010043f0000008001d0003900000000000104350000004001d0003900000000000104350000002001d00039000000000001043500000000000d04350000006001d000390000000000010435000000400600043d00001c3a0060009c00002c720000213d0000008002600039000000400020043f0000006002600039000d00000002001d0000000000020435000000400460003900000000000404350000000002060436000e00000002001d0000000000020435000000400200043d00001bb40020009c00002c720000213d000000a003200039000000400030043f000000800320003900000000000304350000006003200039000000000003043500000040032000390000000000030435000000200320003900000000000304350000000000020435000000400200043d00001c120020009c00002c720000213d000000e003200039000000400030043f000000c00320003900000060050000390000000000530435000000a003200039000000000053043500000040032000390000000000530435000000200320003900000000005304350000008003200039000000000003043500000060032000390000000000030435000000000002043500000000020b0433000000000002004b00002c400000613d000000200fe00039000f00000000001d00000000010000190000000a020000290000000e0a000029000c0000000f001d00002bbd0000013d0000000103a0018f00000000003404350000000e0a0000290000000c0f0000290000000003050433000000000003004b000000000300003900000001030060390000000d0700002900000000003704350000000007040433000000000007004b000000010330c1bf000000000034043500000000000504350000000003040433000000000003004b00002c800000c13d000000010110003900000000030b0433000000000031004b00002c3e0000813d0000000503100210000000000723001900000000030704330000000005030433000000000056043500000000030b0433000000000013004b00002c780000a13d00000000030704330000002003300039000000000303043300000000003a043500000000080e0433000000000085004b00000000080000390000000108008039000000000084043500002c800000813d00000000080e0433000000000058004b00002c780000a13d000000050550021000000000055f001900000000050504330000008008500039000000000808043300001c1f0080019800002bb90000613d000000400550003900000000050504330000000008050433000000000083004b00002bb90000813d00000005033002100000000003530019000000200330003900000000030304330000000f0000006b00002c0b0000613d0000006007d00039000000000a070433000000600530003900000000080504330000000000a8001a00002cb30000413d0000000008a8001900000000008704350000008007d00039000000000707043300000080083000390000000008080433000000000778013f00001ba700700198000000000a0c001900002ba70000c13d000000007a0d04340000000500a0008c00002c9e0000213d00000000f8030434000000050080008c00002c9e0000213d00000000008a004b000000000a0c001900002ba70000c13d000000000707043300000000080f0433000000000778013f00001ba700700198000000000a0c001900002ba70000c13d000000400330003900000000030304330000004007d000390000000007070433000000000037004b000000000a000039000000010a00c03900002ba70000013d0000000058030434000000050080008c00002c9e0000213d000000400d00043d00001bb400d0009c00002c720000213d0000000002090019000000000a0504330000004005300039000000000f0504330000008005300039000000000c05043300000060053000390000000003050433000000a009d00039000000400090043f00001ba709c00197000000800cd0003900000000009c04350000006009d0003900000000003904350000004003d000390000000000f3043500001ba703a001970000002009d00039000000000039043500000000008d0435000000000001004b00002c390000613d00000000030b0433000000000013004b000000010c00003900000000090200190000000a020000290000000e0a0000290000000c0f00002900002c780000a13d000000000302043300000000080704330000000000820435000000000037043500000000030b0433000000000013004b00002c780000a13d000f0000000c001d00002bab0000013d000000010c000039000f0000000c001d00000000090200190000000a0200002900002ba90000013d0000006001d0003900002c430000013d0000000002040433000000000002004b00002c800000c13d000000400200043d0000000001010433000000000001004b00002c4f0000613d00001bd10020009c00002c720000213d0000006001200039000000400010043f0000000000d204350000000001000411000000040300002900002c560000013d00001bd10020009c00002c720000213d0000006001200039000000400010043f0000000000d2043500000000010000190000000003000019000000400420003900000000003404350000002003200039000000000013043500000008019000290000000b030000290000000003030433000000000013004b00002c780000a13d0000000503100210000000090330002900000000002304350000000b020000290000000002020433000000000012004b00002c780000a13d0000000109900039000000070090006c00002b130000413d000000800200043d000000a00500043d00000003010000290000000b03000029000000010400002900000002060000296e8b62c60000040f0000000b02000029000000000001042d00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d00010430000000400200043d00001ba40020009c00001ba4010000410000000001024019000000400110021000001bd6011001c70000000d03000029000000000303043300002c960000013d0000000002010433000000000002004b00000000020000390000000102006039000000e00020043f0000000000010435000000400200043d00001ba40020009c00001ba4010000410000000001024019000000400110021000001bd6011001c7000000e00300043d000000000003004b00002c9b0000c13d00001c5303000041000000000032043500006e8d0001043000001c4603000041000000000032043500006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d0001043000001c540200004100000000002104350000000402100039000000000002043500002cae0000013d00001c5402000041000000000021043500000004021000390000000103000039000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d000104300009000000000002000800000001001d000400000002001d00001c310020009c00002ebf0000813d000000040100002900000005011002100000003f0210003900001c0e02200197000000400300043d0000000002230019000300000003001d000000000032004b0000000003000039000000010300403900001bce0020009c00002ebf0000213d000000010030019000002ebf0000c13d000000400020043f000000040200002900000003030000290000000004230436000700000004001d000000000002004b00002ebb0000613d00000000020000190000006006000039000000400300043d00001bb40030009c00002ebf0000213d000000a004300039000000400040043f00001c330030009c00002ebf0000213d0000020005300039000000400050043f000000000004043500000100053000390000000000650435000000e005300039000000000065043500000080053000390000000000650435000000600530003900000000006504350000000004430436000001e0053000390000000000050435000001c0053000390000000000050435000001a005300039000000000005043500000180053000390000000000050435000001600530003900000000000504350000014005300039000000000005043500000120053000390000000000050435000000c0053000390000000000050435000000400530003900000000000504350000000000040435000000070420002900000000003404350000002002200039000000000012004b00002cd50000413d0000000006000031000000080160006a00000002070003670000003f0110008a000200000001001d00011c0d0010019b0000000002000019000600000002001d0000000502200210000500000002001d0000000801200029000000000117034f000000000201043b00001c0d01200197000000010310014f000000010010006c000000000100001900001c0d01002041000000020020006c000000000400001900001c0d0400404100001c0d0030009c000000000104c019000000000001004b00002ebd0000613d000000400100043d00001bb40010009c00002ebf0000213d000000a003100039000000400030043f00001c330010009c00002ebf0000213d00000008022000290000020004100039000000400040043f0000000000030435000001000410003900000060050000390000000000540435000000e004100039000000000054043500000080041000390000000000540435000000600410003900000000005404350000000003310436000001e0041000390000000000040435000001c0041000390000000000040435000001a004100039000000000004043500000180041000390000000000040435000001600410003900000000000404350000014004100039000000000004043500000120041000390000000000040435000000c00410003900000000000404350000004001100039000000000001043500000000000304350000000003260049000000000127034f000000000101043b0000015f0430008a00001c0d0540019700001c0d08100197000000000958013f000000000058004b000000000500001900001c0d05004041000000000041004b000000000400001900001c0d0400804100001c0d0090009c000000000504c019000000000005004b00002ebd0000c13d0000002004200039000000000447034f000000000404043b0000001f0330008a00001c0d0540019700001c0d08300197000000000985013f000000000085004b000000000500001900001c0d05004041000000000034004b000000000300001900001c0d0300804100001c0d0090009c000000000503c019000000000005004b00002ebd0000c13d0000000003240019000000000437034f000000000e04043b00001bce00e0009c00002ebd0000213d0000000004e60049000000200a30003900001c0d0340019700001c0d05a00197000000000835013f000000000035004b000000000300001900001c0d0300404100000000004a004b000000000400001900001c0d0400204100001c0d0080009c000000000304c019000000000003004b00002ebd0000c13d000000400f00043d00001bb400f0009c00002ebf0000213d000000000b2100190000000001b60049000000a002f00039000900000002001d000000400020043f00001c0f0010009c00002ebd0000213d000001600010008c00002ebd0000413d00001c3300f0009c00002ebf0000213d0000020001f00039000000400010043f0000000001b7034f000000000101043b00001ba70010009c00002ebd0000213d000000090200002900000000001204350000002001b00039000000000217034f000000000202043b00001ba70020009c00002ebd0000213d000000c003f0003900000000002304350000002001100039000000000117034f000000000101043b00001bce0010009c00002ebd0000213d0000000001b100190000001f02100039000000000062004b000000000300001900001c0d0300804100001c0d0420019700001c0d02600197000000000524013f000000000024004b000000000400001900001c0d0400404100001c0d0050009c000000000403c019000000000004004b00002ebd0000c13d000000000317034f000000000303043b00001bce0030009c00002ebf0000213d00000005043002100000003f0440003900001c0e04400197000000400900043d0000000004490019000000000094004b0000000005000039000000010500403900001bce0040009c00002ebf0000213d000000010050019000002ebf0000c13d0000002001100039000000400040043f0000000000390435000000a0033000c90000000003130019000000000063004b00002ebd0000213d000000000013004b00002deb0000a13d0000000004090019000000000516004900001c0f0050009c00002ebd0000213d000000a00050008c00002ebd0000413d000000400500043d00001bb40050009c00002ebf0000213d000000a008500039000000400080043f000000000817034f000000000808043b000000050080008c00002ebd0000213d0000000008850436000000200d100039000000000cd7034f000000000c0c043b00001ba700c0009c00002ebd0000213d00000020044000390000000000c804350000002008d00039000000000887034f000000000808043b000000400c50003900000000008c04350000004008d00039000000000887034f000000000808043b000000600c50003900000000008c04350000006008d00039000000000887034f000000000808043b000000800c50003900000000008c04350000000000540435000000a001100039000000000031004b00002dc20000413d000000e001f0003900000000009104350000006001b00039000000000117034f000000000101043b00001bce0010009c00002ebd0000213d0000000001b100190000001f03100039000000000063004b000000000400001900001c0d0400804100001c0d03300197000000000523013f000000000023004b000000000200001900001c0d0200404100001c0d0050009c000000000204c019000000000002004b00002ebd0000c13d000000000217034f000000000302043b00001bce0030009c00002ebf0000213d00000005023002100000003f0220003900001c0e04200197000000400200043d0000000005420019000000000025004b0000000004000039000000010400403900001bce0050009c00002ebf0000213d000000010040019000002ebf0000c13d0000002004100039000000400050043f0000000000320435000000c0013000c90000000001410019000000000061004b00002ebd0000213d000000000041004b00002e4a0000a13d0000000003020019000000000546004900001c0f0050009c00002ebd0000213d000000c00050008c00002ebd0000413d000000400900043d00001bd40090009c00002ebf0000213d000000c005900039000000400050043f000000000547034f000000000505043b000000050050008c00002ebd0000213d00000000085904360000002005400039000000000c57034f000000000c0c043b00001ba700c0009c00002ebd0000213d0000000000c804350000002008500039000000000887034f000000000808043b000000400c90003900000000008c04350000004008500039000000000887034f000000000808043b000000600c90003900000000008c04350000006008500039000000000887034f000000000808043b000000800c90003900000000008c04350000008005500039000000000557034f000000000505043b00001ba70050009c00002ebd0000213d0000002003300039000000a00890003900000000005804350000000000930435000000c004400039000000000014004b00002e1a0000413d0000010001f0003900000000002104350000008001b00039000000000217034f000000000202043b000000040020008c00002ebd0000213d0000012003f0003900000000002304350000002002100039000000000227034f000000000202043b0000014003f0003900000000002304350000004002100039000000000227034f000000000202043b0000016003f0003900000000002304350000006002100039000000000227034f000000000202043b0000018003f0003900000000002304350000008002100039000000000227034f000000000202043b000001a003f000390000000000230435000000a002100039000000000227034f000000000202043b000001c003f000390000000000230435000000c001100039000000000117034f000000000101043b0000004002f00039000000010300003900000000003204350000002002f000390000000000320435000000090200002900000000002f0435000001e002f0003900000000001204350000001f01e0003900001c2b011001970000003f0110003900001c2b02100197000000400100043d0000000002210019000000000012004b0000000003000039000000010300403900001bce0020009c00002ebf0000213d000000010030019000002ebf0000c13d000000400020043f0000000002e104360000000003ae0019000000000063004b00002ebd0000213d0000000004a7034f00001c2b05e00198000000000352001900002e940000613d000000000804034f0000000009020019000000008a08043c0000000009a90436000000000039004b00002e900000c13d0000001f08e0019000002ea10000613d000000000454034f0000000305800210000000000803043300000000085801cf000000000858022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000484019f00000000004304350000000002e2001900000000000204350000006002f000390000000000120435000000400100043d00001c3b0010009c00002ebf0000213d0000002002100039000000400020043f00000000000104350000008002f000390000000000120435000000030300002900000000010304330000000602000029000000000021004b00002ec50000a13d000000050400002900000007014000290000000000f104350000000001030433000000000021004b00002ec50000a13d0000000102200039000000040020006c00002d070000413d0000000001030019000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d000104300015000000000002000300000005001d000700000004001d000a00000003001d000800000002001d000600000001001d0000000021010434000900000002001d000b00000001001d00001c310010009c000033b90000813d0000000b0100002900000005021002100000003f0120003900001c0e01100197000000400300043d0000000001130019001500000003001d000000000031004b0000000003000039000000010300403900001bce0010009c000033b90000213d0000000100300190000033b90000c13d000000400010043f00000015010000290000000b030000290000000001310436001400000001001d000000000003004b000030430000613d00000000010000190000006005000039000000400300043d00001c120030009c000033b90000213d000000e004300039000000400040043f000000c0043000390000000000540435000000a0043000390000000000540435000000400430003900000000005404350000002004300039000000000054043500000080043000390000000000040435000000600430003900000000000404350000000000030435000000140410002900000000003404350000002001100039000000000021004b00002eed0000413d0000000001000031000c00020010036b000000000200001900000006010000290000000001010433001000000002001d000000000021004b000033b30000a13d000000400100043d00001c120010009c000033b90000213d00000010020000290000000503200210000d00000003001d0000000902300029000000000202043300000000240204340000000002020433000e00000002001d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000f00000004001d0000004001400039000000000b01043300000000c20b043400001bce0020009c000033b90000213d00000005012002100000003f0310003900001c0e03300197000000400900043d0000000003390019000000000093004b0000000004000039000000010400403900001bce0030009c000033b90000213d0000000100400190000033b90000c13d000000400030043f000000000d290436000000000002004b00002f4f0000613d0000000002000019000000400300043d00001c3a0030009c000033b90000213d0000008004300039000000400040043f000000600430003900000000000404350000004004300039000000000004043500000020043000390000000000040435000000000003043500000000042d001900000000003404350000002002200039000000000012004b00002f3e0000413d00000000020b043300001bce0020009c000033b90000213d00000005012002100000003f0310003900001c0e03300197000000400400043d0000000003340019001300000004001d000000000043004b0000000004000039000000010400403900001bce0030009c000033b90000213d0000000100400190000033b90000c13d000000400030043f00000013030000290000000003230436000000000001004b00002f6b0000613d00000000021300190000000c0400035f0000000005030019000000004604043c0000000005650436000000000025004b00002f670000c13d0000001f0010019000000000010b0433000000000001004b00002f9b0000613d0000000002000019000000050120021000000000041c0019000000000704043300000000e8070434000000060080008c000033bf0000813d000000400600043d00001c3a0060009c000033b90000213d000000600470003900000000050e043300000040077000390000000007070433000000000e040433000000800f6000390000004000f0043f000000600f6000390000000000ef0435000000400e60003900000000007e043500001ba7055001970000002007600039000000000057043500000000008604350000000005090433000000000025004b000033b30000a13d00000000051d001900000000006504350000000005090433000000000025004b000033b30000a13d00000013050000290000000005050433000000000025004b000033b30000a13d000000000131001900000000040404330000000000410435000000010220003900000000010b0433000000000012004b00002f700000413d0000000f0100002900000060011000390000000001010433001200000001001d0000000012010434001100000001001d00001bce0020009c000033b90000213d00000005012002100000003f0310003900001c0e03300197000000400b00043d00000000033b00190000000000b3004b0000000004000039000000010400403900001bce0030009c000033b90000213d0000000100400190000033b90000c13d000000400030043f000000000e2b0436000000000002004b00002fc70000613d0000000002000019000000400300043d00001bb40030009c000033b90000213d000000a004300039000000400040043f00000080043000390000000000040435000000600430003900000000000404350000004004300039000000000004043500000020043000390000000000040435000000000003043500000000042e001900000000003404350000002002200039000000000012004b00002fb40000413d0000001201000029000000000201043300001bce0020009c000033b90000213d00000005012002100000003f0310003900001c0e03300197000000400f00043d00000000033f00190000000000f3004b0000000004000039000000010400403900001bce0030009c000033b90000213d0000000100400190000033b90000c13d000000400030043f00000000032f0436000000000001004b00002fe20000613d00000000021300190000000c0400035f0000000005030019000000004604043c0000000005650436000000000025004b00002fde0000c13d0000001f0010019000000012010000290000000001010433000000000001004b0000301a0000613d00000000020000190000000501200210000000110410002900000000070404330000000056070434000000050060008c000033bf0000213d000000400800043d00001bb40080009c000033b90000213d00000060047000390000000005050433000000400a700039000000000a0a0433000000000d040433000000a0077000390000000007070433000000000c090019000000a009800039000000400090043f00001ba7077001970000008009800039000000000079043500000000090c001900000060078000390000000000d7043500000040078000390000000000a7043500001ba70550019700000020078000390000000000570435000000000068043500000000050b0433000000000025004b000033b30000a13d00000000051e0019000000000085043500000000050b0433000000000025004b000033b30000a13d00000000050f0433000000000025004b000033b30000a13d000000000131001900000000040404330000000000410435000000010220003900000012010000290000000001010433000000000012004b00002fe80000413d000000400100043d00001c120010009c000033b90000213d0000000e0200002900001c1f022001970000000f04000029000000000304043300000120044000390000000004040433000000e005100039000000400050043f000000c0051000390000000000f50435000000a00510003900000013060000290000000000650435000000800510003900000000002504350000006002100039000000000042043500000040021000390000000000b204350000002002100039000000000092043500001ba702300197000000000021043500000015020000290000000002020433000000100020006c000033b30000a13d0000000d030000290000001402300029000000000012043500000015010000290000000001010433000000100010006c000033b30000a13d000000100200002900000001022000390000000b0020006c00002f070000413d000000400400043d00001bd10040009c000033b90000213d000000060100002900000000050104330000006002400039000000400020043f000000030200002900001ba702200197000000400340003900000000002304350000002002400039000000000052043500000001020000390000000000240435000000150200002900000008030000296e8b4b140000040f0000002004000039000000400300043d0000000004430436000200000002001d000000000201043300000000002404350000004007300039000000000002004b000100000001001d000030670000613d000000000400001900000000050100190000002005500039000000000605043300000000076704360000000104400039000000000024004b000030610000413d000000000137004900001ba40010009c00001ba401008041000000600110021000001ba40030009c00001ba4030080410000004002300210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bcd011001c70000800d02000039000000010300003900001c55040000416e8b6e810000040f0000000100200190000033c50000613d000000070100002900001bce0010009c000033b90000213d000000070100002900000005011002100000003f0210003900001c0e02200197000000400300043d0000000002230019000b00000003001d000000000032004b0000000003000039000000010300403900001bce0020009c000033b90000213d0000000100300190000033b90000c13d000000400020043f00000007020000290000000b030000290000000003230436000900000003001d000000000002004b000033aa0000613d0000000002000019000000400300043d00001bd10030009c000033b90000213d0000006004300039000000400040043f00001c130030009c000033b90000213d0000010005300039000000400050043f00000000000404350000000004430436000000e0053000390000000000050435000000c0053000390000000000050435000000a005300039000000000005043500000080053000390000000000050435000000400530003900000000000504350000000000040435000000090420002900000000003404350000002002200039000000000012004b000030940000413d000000000c0000310000000a01c0006a00000002040003670000003f0110008a000500000001001d00041c0d0010019b000000000200001900100000000c001d000c000000040353000e00000002001d0000000502200210000800000002001d0000000a01200029000000000114034f000000000101043b00001c0d02100197000000040320014f000000040020006c000000000200001900001c0d02004041000000050010006c000000000500001900001c0d0500804100001c0d0030009c000000000205c019000000000002004b000033c50000c13d0000000a01100029000000000214034f000000000502043b00000000021c00490000001f0320008a00001c0d0630019700001c0d02500197000000000762013f000000000062004b000000000200001900001c0d02004041000000000035004b000000000800001900001c0d0800804100001c0d0070009c000000000208c019000000000002004b000033c50000c13d0000000005150019000000000254034f000000000702043b00001bce0070009c000033c50000213d000000060970021000000000029c0049000000200550003900001c0d0820019700001c0d0a500197000000000b8a013f00000000008a004b000000000800001900001c0d08004041000000000025004b000000000200001900001c0d0200204100001c0d00b0009c000000000802c019000000000008004b000033c50000c13d0000002002100039000000000224034f000000000802043b00001c0d02800197000000000a62013f000000000062004b000000000200001900001c0d02004041000000000038004b000000000300001900001c0d0300804100001c0d00a0009c000000000203c019000000000002004b000033c50000c13d0000000001180019000000000214034f000000000302043b00001bce0030009c000033c50000213d000000060630021000000000026c0049000000200110003900001c0d0820019700001c0d0a100197000000000b8a013f00000000008a004b000000000800001900001c0d08004041000000000021004b000000000200001900001c0d0200204100001c0d00b0009c000000000802c019000000000008004b000033c50000c13d00000005027002100000003f0220003900001c0e02200197000000400a00043d00000000082a001900120000000a001d0000000000a8004b0000000002000039000000010200403900001bce0080009c000033b90000213d0000000100200190000033b90000c13d000000400080043f00000012020000290000000002720436000f00000002001d00000000075900190000000000c7004b000033c50000213d000000000057004b000031420000a13d000000120800002900000000025c004900001c0f0020009c000033c50000213d000000400020008c000033c50000413d000000400900043d00001ba80090009c000033b90000213d00000020088000390000004002900039000000400020043f000000000254034f000000000202043b0000000002290436000000200a500039000000000aa4034f000000000a0a043b0000000000a2043500000000009804350000004005500039000000000075004b0000312c0000413d00000005023002100000003f0220003900001c0e02200197000000400b00043d00000000052b00190000000000b5004b0000000002000039000000010200403900001bce0050009c000033b90000213d0000000100200190000033b90000c13d000000400050043f000000000d3b043600000000031600190000000000c3004b000033c50000213d000000000013004b0000316c0000a13d00000000050b001900000000021c004900001c0f0020009c000033c50000213d000000400020008c000033c50000413d000000400600043d00001ba80060009c000033b90000213d00000020055000390000004002600039000000400020043f000000000214034f000000000202043b00000000022604360000002007100039000000000774034f000000000707043b000000000072043500000000006504350000004001100039000000000031004b000031560000413d000000400a00043d00001bd100a0009c000033b90000213d0000006001a00039000000400010043f00001c1300a0009c000033b90000213d0000010002a00039000000400020043f000000000001043500000000011a0436000000e002a000390000000000020435000000c002a000390000000000020435000000a002a0003900000000000204350000008002a0003900000000000204350000004002a000390000000000020435000000000001043500000012010000290000000001010433000000000001004b000033e70000613d00000000010b0433000000000001004b000033e70000613d000000400100043d001300000001001d00001bb40010009c000033b90000213d0000001302000029000000a001200039000000400010043f0000008001200039000000000001043500000040012000390000000000010435000000200120003900000000000104350000000000020435000000600e20003900000000000e0435000000400500043d00001c3a0050009c000033b90000213d0000008001500039000000400010043f00000060065000390000000000060435000000400150003900000000000104350000000002050436001100000002001d0000000000020435000000400300043d00001bb40030009c000033b90000213d000000a002300039000000400020043f000000800230003900000000000204350000006002300039000000000002043500000040023000390000000000020435000000200230003900000000000204350000000000030435000000400300043d00001c120030009c000033b90000213d000000e002300039000000400020043f000000c00230003900000060070000390000000000720435000000a002300039000000000072043500000040023000390000000000720435000000200230003900000000007204350000008002300039000000000002043500000060023000390000000000020435000000000003043500000000020b0433000000000002004b000032720000613d0000000007000019000000000e000019000000110f000029000d00000006001d000031e30000013d0000000102f0018f0000000000210435000000100c000029000000110f0000290000000002030433000000000002004b0000000002000039000000010200603900000000002604350000000008010433000000000008004b000000010220c1bf000000000021043500000000000304350000000002010433000000000002004b000033c70000c13d000000010ee0003900000000020b043300000000002e004b0000326f0000813d0000000502e002100000000009d2001900000000020904330000000008020433000000000085043500000000020b04330000000000e2004b000033b30000a13d00000000020904330000002002200039000000000302043300000000003f043500000015020000290000000002020433000000000028004b000000000200003900000001020080390000000000210435000033c70000813d00000015020000290000000002020433000000000082004b000033b30000a13d0000000502800210000000140220002900000000080204330000008002800039000000000202043300001c1f00200198000031df0000613d000000400280003900000000080204330000000002080433000000000023004b000031df0000813d0000000502300210000000000282001900000020022000390000000008020433000000000007004b000032360000613d00000013020000290000006009200039000000000c090433000000600380003900000000020304330000000000c2001a000033f50000413d0000000002c20019000000000029043500000013020000290000008002200039000000000202043300000080098000390000000009090433000000000229013f00001ba700200198000000010f000039000031ce0000c13d0000001302000029000000009f0204340000000500f0008c000033bf0000213d00000000c2080434000000050020008c000033bf0000213d00000000002f004b000000010f000039000031ce0000c13d000000000209043300000000090c0433000000000229013f00001ba700200198000031ce0000c13d00000040028000390000000002020433000000130800002900000040088000390000000008080433000000000028004b000000000f000039000000010f00c039000031ce0000013d0000000037080434000000050070008c000033bf0000213d000000400200043d001300000002001d00001bb40020009c000033b90000213d00000000040d0019000000000d0a001900000000020304330000004003800039000000000c0304330000008003800039000000000f030433000000600380003900000000080304330000001306000029000000a00a6000390000004000a0043f00001ba70af00197000000800f6000390000000000af0435000000600a60003900000000008a043500000040086000390000000000c8043500001ba70220019700000020086000390000000000280435000000000076043500000000000e004b000032680000613d00000000020b04330000000000e2004b000000100c000029000000000a0d0019000000000d0400190000000c0400035f0000000d06000029000000110f000029000033b30000a13d00000000020d0433000000000709043300000000007d0435000000000029043500000000020b04330000000000e2004b000033b30000a13d0000000107000039000031d20000013d0000000107000039000000100c000029000000000a0d0019000000000d0400190000000c0400035f0000000d06000029000031d10000013d0000001301000029000000600e100039000032750000013d0000000001010433000000000001004b000033c70000c13d00000000010e0433000000000001004b0000339b0000613d000000400a00043d00001bd100a0009c000033b90000213d0000006001a00039000000400010043f00001c1300a0009c000033b90000213d0000010002a00039000000400020043f000000000001043500000000011a0436000000e002a000390000000000020435000000c002a000390000000000020435000000a002a0003900000000000204350000008002a0003900000000000204350000004002a0003900000000000204350000000000010435000000400100043d00001c120010009c000033b90000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a002100039000000000032043500000040021000390000000000320435000000200210003900000000003204350000008002100039000000000002043500000060021000390000000000020435000000000001043500000012010000290000000006010433000000000006004b000033380000613d000000000f0a0019000000000100001900000000050000190000000f0a000029000032b10000013d00000000020504330000000000050435000000000002004b00000001050000390000000f0a000029000032fb0000c13d000033da0000013d00000005021002100000000003a200190000000002030433000000008702043400000015020000290000000002020433000000000027004b000033df0000813d0000000502700210000000140220002900000000070204330000008002700039000000000202043300001c1f00200198000032fd0000613d0000000008080433000000200270003900000000090204330000000002090433000000000028004b000032fd0000813d0000000502800210000000000292001900000020022000390000000006020433000000000005004b000033010000613d00000060036000390000000008030433000000000a0f001900000000920a0434000000600c20003900000000020c0433000000000028001a000033f50000413d000000000228001900000000002c04350000004002600039000000000202043300000000080a0433000000400a800039000000000a0a043300000000002a004b000000000a0f0019000033d60000c13d00000000020704330000000009090433000000000292013f00001ba700200198000033d60000c13d000000600270003900000000020204330000004007a000390000000007070433000000000027004b000033d60000c13d0000000078080434000000050080008c000033bf0000213d0000000062060434000000050020008c000033bf0000213d000000000028004b000033d60000c13d0000000002060433000000000707043300000000060304330000000000030435000000000272013f00001ba700200198000033dd0000c13d000000000006004b0000000f0a000029000033da0000613d000000120200002900000000060204330000000101100039000000000061004b000032b10000413d000033360000013d0000000059060434000000050090008c000033bf0000213d000000400800043d00001bb40080009c000033b90000213d00000000020504330000004005600039000000000a05043300000060056000390000000006050433000000a00c8000390000004000c0043f000000600c80003900000000006c043500000040068000390000000000a6043500001ba70220019700000020068000390000000000260435000000000098043500000080028000390000000000020435000000400f00043d00001bd100f0009c000033b90000213d0000000002070433000000600670003900000000060604330000006007f00039000000400070043f0000004007f00039000000000067043500001ba7022001970000002006f00039000000000026043500000000008f0435000000000001004b000032aa0000613d00000012020000290000000002020433000000000012004b000033b30000a13d0000000f07000029000000000207043300000000060304330000000000670435000000000023043500000012020000290000000002020433000000000012004b000032aa0000213d000033b30000013d000000000a0f0019000033390000013d000000000600001900000000010a04330000000035010434000000050050008c000033bf0000213d00000013020000290000000072020434000000050020008c000033bf0000213d000000000025004b000033ea0000c13d00000000020304330000000003070433000000000223013f00001ba700200198000033ea0000c13d00000013020000290000004002200039000000000202043300000040031000390000000003030433000000000023004b000033ea0000c13d00000000030e043300000060011000390000000005010433000000000153004b000033720000a13d00000000020b0433000000000002004b000000100c000029000033b30000613d00000000020d0433000000003502043400000015020000290000000002020433000000000052004b000033b30000a13d0000000502500210000000140220002900000000020204330000004002200039000000000502043300000000060504330000000002030433000000000026004b000033b30000a13d00000005022002100000000002250019000000200220003900000000020204330000006002200039000000000012043500000000010a04330000006001100039000000000101043300000000001e04350000338d0000013d000000000006004b000000100c000029000033b30000613d0000000f010000290000000001010433000000001601043400000015020000290000000002020433000000000062004b000033b30000a13d0000000502600210000000140220002900000000020204330000002002200039000000000602043300000000020604330000000001010433000000000012004b000033b30000a13d000000000235004900000005011002100000000001160019000000200110003900000000010104330000006001100039000000000021043500000000010e043300000000020a04330000006002200039000000000012043500000000010a043300000060021000390000000002020433000000000002004b0000339b0000613d000000800110003900000013020000290000008002200039000000000202043300001ba70220019700000000002104350000000b0100002900000000010104330000000e0010006c000033b30000a13d000000080200002900000009012000290000000000a104350000000b0100002900000000010104330000000e0010006c000033b30000a13d0000000e020000290000000102200039000000070020006c000030b80000413d000000060100002900000015020000290000000b030000290000000104000029000000030500002900000002060000296e8b62c60000040f0000000b01000029000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d00010430000000400200043d00001ba40020009c00001ba4010000410000000001024019000000400110021000001bd6011001c70000000003060433000000000003004b000033d30000c13d00001c5303000041000000000032043500006e8d0001043000001c4603000041000000000032043500006e8d0001043000000000010304330000000000030435000000000001004b000033df0000c13d000000400100043d00001c4602000041000033e10000013d000000000006004b000033da0000613d000000400100043d00001c5302000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00001c5702000041000033e10000013d000000400100043d00001c5602000041000000000021043500000004021000390000000e03000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d0001043000010000000000020000000002010019000000400100043d00001c320010009c000035960000813d000000a003100039000000400030043f00001c330010009c000035960000213d0000020004100039000000400040043f0000000000030435000001000410003900000060050000390000000000540435000000e004100039000000000054043500000080041000390000000000540435000000600410003900000000005404350000000003310436000001e0041000390000000000040435000001c0041000390000000000040435000001a004100039000000000004043500000180041000390000000000040435000001600410003900000000000404350000014004100039000000000004043500000120041000390000000000040435000000c00410003900000000000404350000004001100039000000000001043500000000000304350000000203000367000000000123034f000000000701043b000000000500003100000000012500490000015f0410008a00001c0d0640019700001c0d08700197000000000968013f000000000068004b000000000600001900001c0d06002041000000000047004b000000000400001900001c0d0400404100001c0d0090009c000000000604c019000000000006004b000035940000613d0000002004200039000000000443034f000000000404043b0000001f0110008a00001c0d0640019700001c0d08100197000000000986013f000000000086004b000000000600001900001c0d06004041000000000014004b000000000100001900001c0d0100804100001c0d0090009c000000000601c019000000000006004b000035940000c13d0000000001240019000000000413034f000000000404043b00001bce0040009c000035940000213d0000000008450049000000200610003900001c0d0180019700001c0d09600197000000000a19013f000000000019004b000000000100001900001c0d01004041000000000086004b000000000800001900001c0d0800204100001c0d00a0009c000000000108c019000000000001004b000035940000c13d000000400100043d00001bb40010009c000035960000213d00000000072700190000000008750049000000a002100039000100000002001d000000400020043f00001c0f0080009c000035940000213d000001600080008c000035940000413d00001c330010009c000035960000213d0000020002100039000000400020043f000000000273034f000000000202043b00001ba70020009c000035940000213d000000010800002900000000002804350000002008700039000000000283034f000000000902043b00001ba70090009c000035940000213d000000c00210003900000000009204350000002002800039000000000223034f000000000202043b00001bce0020009c000035940000213d000000000a7200190000001f02a00039000000000052004b000000000900001900001c0d0900804100001c0d0220019700001c0d08500197000000000b82013f000000000082004b000000000200001900001c0d0200404100001c0d00b0009c000000000209c019000000000002004b000035940000c13d0000000002a3034f000000000b02043b00001bce00b0009c000035960000213d0000000502b002100000003f0220003900001c0e02200197000000400900043d000000000c29001900000000009c004b0000000002000039000000010200403900001bce00c0009c000035960000213d0000000100200190000035960000c13d000000200aa000390000004000c0043f0000000000b90435000000a002b000c9000000000ba2001900000000005b004b000035940000213d0000000000ab004b000034d00000a13d000000000c0900190000000002a5004900001c0f0020009c000035940000213d000000a00020008c000035940000413d000000400d00043d00001bb400d0009c000035960000213d000000a002d00039000000400020043f0000000002a3034f000000000202043b000000050020008c000035940000213d000000000f2d0436000000200ea000390000000002e3034f000000000202043b00001ba70020009c000035940000213d000000200cc0003900000000002f04350000002002e00039000000000223034f000000000202043b000000400fd0003900000000002f04350000004002e00039000000000223034f000000000202043b000000600fd0003900000000002f04350000006002e00039000000000223034f000000000202043b000000800ed0003900000000002e04350000000000dc0435000000a00aa000390000000000ba004b000034a70000413d000000e00210003900000000009204350000006002700039000000000223034f000000000202043b00001bce0020009c000035940000213d00000000097200190000001f02900039000000000052004b000000000a00001900001c0d0a00804100001c0d02200197000000000b82013f000000000082004b000000000200001900001c0d0200404100001c0d00b0009c00000000020ac019000000000002004b000035940000c13d000000000293034f000000000a02043b00001bce00a0009c000035960000213d0000000502a002100000003f0220003900001c0e02200197000000400800043d000000000b28001900000000008b004b0000000002000039000000010200403900001bce00b0009c000035960000213d0000000100200190000035960000c13d00000020099000390000004000b0043f0000000000a80435000000c002a000c9000000000a92001900000000005a004b000035940000213d00000000009a004b0000352f0000a13d000000000b080019000000000295004900001c0f0020009c000035940000213d000000c00020008c000035940000413d000000400c00043d00001bd400c0009c000035960000213d000000c002c00039000000400020043f000000000293034f000000000202043b000000050020008c000035940000213d000000000e2c0436000000200d9000390000000002d3034f000000000202043b00001ba70020009c000035940000213d00000000002e04350000002002d00039000000000223034f000000000202043b000000400ec0003900000000002e04350000004002d00039000000000223034f000000000202043b000000600ec0003900000000002e04350000006002d00039000000000223034f000000000202043b000000800ec0003900000000002e04350000008002d00039000000000223034f000000000d02043b00001ba700d0009c000035940000213d000000200bb00039000000a002c000390000000000d204350000000000cb0435000000c0099000390000000000a9004b000034ff0000413d000001000210003900000000008204350000008007700039000000000273034f000000000202043b000000040020008c000035940000213d000001200810003900000000002804350000002002700039000000000223034f000000000202043b000001400810003900000000002804350000004002700039000000000223034f000000000202043b000001600810003900000000002804350000006002700039000000000223034f000000000202043b000001800810003900000000002804350000008002700039000000000223034f000000000202043b000001a0081000390000000000280435000000a002700039000000000223034f000000000202043b000001c0081000390000000000280435000000c002700039000000000223034f000000000202043b0000004007100039000000010800003900000000008704350000002007100039000000000087043500000001070000290000000000710435000001e00710003900000000002704350000001f0240003900001c2b022001970000003f0220003900001c2b07200197000000400200043d0000000007720019000000000027004b0000000009000039000000010900403900001bce0070009c000035960000213d0000000100900190000035960000c13d000000400070043f00000000074204360000000009640019000000000059004b000035940000213d000000000563034f00001c2b064001980000001f0840018f00000000036700190000357a0000613d000000000905034f000000000a070019000000009b09043c000000000aba043600000000003a004b000035760000c13d000000000008004b000035870000613d000000000565034f0000000306800210000000000803043300000000086801cf000000000868022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000585019f00000000005304350000000003470019000000000003043500000060031000390000000000230435000000400200043d00001c3b0020009c000035960000213d0000002003200039000000400030043f000000000002043500000080031000390000000000230435000000000001042d000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d000104300026000000000002000300000004001d001300000003001d001600000002001d000a00000001001d000000400400043d00001c580040009c000045b20000813d0000008001400039000000400010043f00000040014000390000000000010435000000200140003900000000000104350000000000040435000000400100043d00001c120010009c000045b20000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435001b00000004001d000000600240003900000000001204350000000a010000290000000012010434001700000001001d000000c0012000390000000001010433001a00000001001d001800000002001d000000a0012000390000000001010433001900000001001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000001903000029000000000013004b0000001a04000029000045fc0000213d000000000014004b000045fc0000a13d000000180100002900000080011000390000000001010433000000050010008c000045cc0000813d0000000a020000290000004002200039000000000202043300001c1f042001970000001702000029000000000202043300001c1f03200197000000040010008c0000371a0000c13d000000010030008c000046030000c13d000000010040008c000046030000c13d000000400100043d00001c120010009c000045b20000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000000180100002900000040011000390000000004010433000000005304043400001bce0030009c000045b20000213d00000005023002100000003f0120003900001c0e06100197000000400100043d0000000006610019001b00000001001d000000000016004b0000000007000039000000010700403900001bce0060009c000045b20000213d0000000100700190000045b20000c13d000000400060043f0000001b010000290000000006310436000000000003004b0000362c0000613d0000000003000019000000400700043d00001c3a0070009c000045b20000213d0000008008700039000000400080043f0000006008700039000000000008043500000040087000390000000000080435000000200870003900000000000804350000000000070435000000000836001900000000007804350000002003300039000000000023004b0000361b0000413d000000000304043300001bce0030009c000045b20000213d00000005083002100000003f0280003900001c0e07200197000000400100043d0000000007710019001a00000001001d000000000017004b0000000009000039000000010900403900001bce0070009c000045b20000213d0000000100900190000045b20000c13d000000400070043f0000001a0100002900000000073104360000001f0980018f00000000030000310000000203300367000000000008004b0000364b0000613d0000000008870019000000000a03034f000000000b07001900000000ac0a043c000000000bcb043600000000008b004b000036470000c13d000000000009004b0000000008040433000000000008004b0000367d0000613d00000000080000190000000509800210000000000a950019000000000d0a043300000000ec0d04340000000500c0008c000045cc0000213d000000400b00043d00001c3a00b0009c000045b20000213d000000600ad00039000000000e0e0433000000400dd00039000000000d0d0433000000000f0a04330000008002b00039000000400020043f0000006002b000390000000000f204350000004002b000390000000000d2043500001ba702e00197000000200db0003900000000002d04350000000000cb04350000001b010000290000000002010433000000000082004b000045ba0000a13d00000000029600190000000000b204350000001b010000290000000002010433000000000082004b000045ba0000a13d0000001a010000290000000002010433000000000082004b000045ba0000a13d000000000279001900000000090a0433000000000092043500000001088000390000000002040433000000000028004b000036500000413d0000001801000029000000600410003900000000050404330000000019050434001900000001001d00001bce0090009c000045b20000213d00000005089002100000003f0480003900001c0e07400197000000400400043d0000000007740019000000000047004b000000000a000039000000010a00403900001bce0070009c000045b20000213d0000000100a00190000045b20000c13d000000400070043f0000000007940436000000000009004b000036a80000613d0000000009000019000000400a00043d00001bb400a0009c000045b20000213d000000a00ba000390000004000b0043f000000800ba0003900000000000b0435000000600ba0003900000000000b0435000000400ba0003900000000000b0435000000200ba0003900000000000b043500000000000a0435000000000b9700190000000000ab04350000002009900039000000000089004b000036950000413d000000000905043300001bce0090009c000045b20000213d000000050a9002100000003f08a0003900001c0e0b800197000000400800043d000000000bb8001900000000008b004b000000000c000039000000010c00403900001bce00b0009c000045b20000213d0000000100c00190000045b20000c13d0000004000b0043f00000000099804360000001f0ba0018f00000000000a004b000036c20000613d000000000aa90019000000000c090019000000003d03043c000000000cdc04360000000000ac004b000036be0000c13d00000000000b004b0000000003050433000000000003004b000036f60000613d0000000003000019000000050a3002100000001902a00029000000000e02043300000000fd0e04340000000500d0008c000045cc0000213d000000400c00043d00001bb400c0009c000045b20000213d000000600be0003900000000020f0433000000400fe00039000000000f0f043300000000060b0433000000a00ee00039000000000e0e0433000000a001c00039000000400010043f00001ba701e00197000000800ec0003900000000001e04350000006001c0003900000000006104350000004001c000390000000000f1043500001ba7012001970000002002c0003900000000001204350000000000dc04350000000001040433000000000031004b000045ba0000a13d0000000001a700190000000000c104350000000001040433000000000031004b000045ba0000a13d0000000001080433000000000031004b000045ba0000a13d00000000019a001900000000020b0433000000000021043500000001033000390000000001050433000000000013004b000036c70000413d000000400600043d00001c120060009c000045b20000213d0000001802000029000000000102043300000120022000390000000003020433000000e002600039000000400020043f000000c0026000390000000000820435000000a0026000390000001a050000290000000000520435000000800560003900000001020000390000000000250435000000600560003900000000003504350000004003600039000000000043043500000020036000390000001b04000029000000000043043500001ba7011001970000000000160435000000400100043d000000000301001900001c3a0010009c000045b20000213d0000008001300039000000400010043f0000000001230436000200000001001d0000000000210435000038c10000013d000000010230008a000000000042004b000046030000813d001700000003001d001500000004001d000000000043004b000037230000813d00000001001001900000461a0000613d00000018010000296e8b5a830000040f0000001b020000290000000000120435000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d0000001b060000290000000002060433000000000101043b000000000401041a0000ff00004001900000461d0000c13d0000008807400270000000100140027000001c1f031001980000001705000029000037400000613d000000000073004b000046200000813d000000ff00400190000037450000613d00001c590040009c000037560000813d000037910000013d0000000a010000290000006001100039001900000003001d00000000030104330000001801000029000000000101043300001ba701100197001a00000007001d001400000004001d6e8b5c900000040f000000140400002900000019030000290000001a070000290000001b06000029000000170500002900001c590040009c000037910000413d0000001501000029000000010010008c0000375e0000c13d00000000050700190000000001350019000000000071004b000037640000a13d000037700000013d000000000017004b0000376a0000c13d00000000070100190000000001350019000000000071004b000037700000213d000000000271019f00001c5a0020009c000037760000813d001700000005001d001500000007001d000037910000013d00000000055700a900000000071700a900000000031300a90000000001350019000000000071004b000037640000a13d000000000537004b000045c00000413d0000000001070019000000000271019f00001c5a0020009c000037670000413d000000000007004b000037800000613d00000000030700190000000004010019000000000203001900000000302400d9000000000003004b00000000040200190000377a0000c13d000037830000013d000000000001004b0000000002010019000045a90000613d0000000004050019000000000302001900000000203400d9000000000002004b0000000004030019000037840000c13d00000000013100d900001c1f0010009c000045c00000213d00000000013700d9001500000001001d00001c1f0010009c000045c00000213d00170000003500e1000000400200043d00001c120020009c000045b20000213d0000000001060433001400000001001d000000e001200039000000400010043f000000c00120003900000060030000390000000000310435000000a0012000390000000000310435000000400120003900000000003104350000002001200039000000000031043500000080012000390000000000010435000000600120003900000000000104350000000000020435000000180100002900000040011000390000000005010433000000006405043400001bce0040009c000045b20000213d00000005034002100000003f0130003900001c0e01100197000000400200043d0000000007120019001b00000002001d000000000027004b0000000001000039000000010100403900001bce0070009c000045b20000213d0000000100100190000045b20000c13d000000400070043f0000001b010000290000000007410436000000000004004b000037d00000613d0000000004000019000000400800043d00001c3a0080009c000045b20000213d0000008001800039000000400010043f0000006001800039000000000001043500000040018000390000000000010435000000200180003900000000000104350000000000080435000000000147001900000000008104350000002004400039000000000034004b000037bf0000413d000000000405043300001bce0040009c000045b20000213d00000005094002100000003f0190003900001c0e01100197000000400200043d0000000008120019001a00000002001d000000000028004b0000000001000039000000010100403900001bce0080009c000045b20000213d0000000100100190000045b20000c13d000000400080043f0000001a0100002900000000084104360000001f0a90018f00000000010000310000000204100367000000000009004b000037ef0000613d0000000009980019000000000b04034f000000000108001900000000bc0b043c0000000001c10436000000000091004b000037eb0000c13d00000000000a004b0000000001050433000000000001004b000038210000613d0000000009000019000000050a9002100000000001a60019000000000e01043300000000fd0e04340000000500d0008c000045cc0000213d000000400c00043d00001c3a00c0009c000045b20000213d000000600be0003900000000010f0433000000400ee00039000000000e0e0433000000000f0b04330000008003c00039000000400030043f0000006003c000390000000000f304350000004003c000390000000000e3043500001ba7011001970000002003c0003900000000001304350000000000dc04350000001b010000290000000001010433000000000091004b000045ba0000a13d0000000001a700190000000000c104350000001b010000290000000001010433000000000091004b000045ba0000a13d0000001a010000290000000001010433000000000091004b000045ba0000a13d00000000018a001900000000030b0433000000000031043500000001099000390000000001050433000000000019004b000037f40000413d000000180100002900000060011000390000000006010433000000001a060434001900000001001d00001bce00a0009c000045b20000213d0000000509a002100000003f0190003900001c0e01100197000000400500043d0000000008150019000000000058004b0000000001000039000000010100403900001bce0080009c000045b20000213d0000000100100190000045b20000c13d000000400080043f0000000008a5043600000000000a004b0000384c0000613d000000000a000019000000400b00043d00001bb400b0009c000045b20000213d000000a001b00039000000400010043f0000008001b0003900000000000104350000006001b0003900000000000104350000004001b0003900000000000104350000002001b00039000000000001043500000000000b04350000000001a800190000000000b10435000000200aa0003900000000009a004b000038390000413d000000000a06043300001bce00a0009c000045b20000213d000000050ba002100000003f01b0003900001c0e01100197000000400900043d000000000c19001900000000009c004b0000000001000039000000010100403900001bce00c0009c000045b20000213d0000000100100190000045b20000c13d0000004000c0043f000000000aa904360000001f0cb0018f00000000000b004b000038660000613d000000000bba001900000000010a0019000000004d04043c0000000001d104360000000000b1004b000038620000c13d00000000000c004b0000000001060433000000000001004b0000389a0000613d0000000004000019000000050b4002100000001901b00029000000000f010433000000001e0f04340000000500e0008c000045cc0000213d000000400d00043d00001bb400d0009c000045b20000213d000000600cf0003900000000010104330000004003f00039000000000303043300000000070c0433000000a00ff00039000000000f0f0433000000a002d00039000000400020043f00001ba702f00197000000800fd0003900000000002f04350000006002d0003900000000007204350000004002d00039000000000032043500001ba7011001970000002002d0003900000000001204350000000000ed04350000000001050433000000000041004b000045ba0000a13d0000000001b800190000000000d104350000000001050433000000000041004b000045ba0000a13d0000000001090433000000000041004b000045ba0000a13d0000000001ab001900000000020c0433000000000021043500000001044000390000000001060433000000000014004b0000386b0000413d000000400600043d00001c120060009c000045b20000213d000000170100002900001c1f041001970000001802000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000930435000000a0036000390000001a07000029000000000073043500000080036000390000000000430435000000600360003900000000002304350000004002600039000000000052043500000020026000390000001b03000029000000000032043500001ba7011001970000000000160435000000400100043d000000000301001900001c3a0010009c000045b20000213d0000008001300039000000400010043f00000014010000290000000001130436000200000001001d0000000000410435000000150100002900001c1f021001970000006001300039000900000001001d0000000000610435000600000003001d0000004001300039000100000001001d000000000021043500000016010000290000000021010434001500000002001d001400000001001d000000000001004b000039730000613d0000000a010000290000000001010433001100400010003d001200600010003d0000000002000019000038db0000013d0000000001010433000000000001004b000039700000c13d00000018020000290000000102200039000000140020006c000039730000813d00000016010000290000000001010433000000000021004b000045ba0000a13d001800000002001d000000050120021000000015011000290000000001010433000000200210003900000000020204330000000003010433000000000003004b000045ca0000c13d000000010020008c000045cc0000213d00000040031000390000000003030433000000000002004b000038f40000613d000000120200002900000000020204330000000004020433000000000043004b000038f90000413d000045d80000013d000000110200002900000000020204330000000004020433000000000043004b000045ee0000813d00000005033002100000000002230019000000200220003900000000020204330000000003020433000000050030008c000045cc0000213d00000040042000390000000005040433000000040030008c000000030300003900000002030060390000000000320435000000600210003900000000030204330000000000340435000045d20000413d00000080011000390000000001010433000000000005004b000038d40000613d001a00000001001d001700000005001d0000000003020433000000400100043d00000020020000390000000002210436000000000032043500001ba80010009c000045b20000213d0000004003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000101043b0000001a020000290000000032020434001900000003001d000000000002004b0000396e0000613d0000000003000019001b00000003001d00000005023002100000001905200029000000400200043d000000400420003900000020032000390000000005050433000000000051004b0000394d0000a13d000000000053043500000000001404350000004001000039000000000012043500001bd10020009c000045b20000213d0000006001200039000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f00000000020004140000395e0000013d000000000013043500000000005404350000004001000039000000000012043500001bd10020009c000045b20000213d0000006001200039000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000101043b0000001b0300002900000001033000390000001a020000290000000002020433000000000023004b000039320000413d000000170010006c000038d70000613d000000400100043d00001c6002000041000045f60000013d0000000a0100002900000000030104330000006001300039001700000001001d00000000010104330000000021010434000000000001004b000500000003001d001800800030003d000039980000613d0000000003000019000039820000013d0000000103300039000000000013004b000039980000813d0000000504300210000000000442001900000000040404330000000005040433000000050050008c000045cc0000213d000000030050008c0000397f0000a13d00000018050000290000000005050433000000040050008c000045cc0000213d000039930000c13d00000040044000390000000004040433000000000004004b0000397f0000613d000000400100043d0000002402100039000000000032043500001c6202000041000039b80000013d0000000501000029000000400d10003900000000010d04330000000021010434000000000001004b000039c00000613d0000000003000019000039a30000013d0000000103300039000000000013004b000039c00000813d0000000504300210000000000442001900000000040404330000000005040433000000050050008c000045cc0000213d000000030050008c000039a00000a13d00000018050000290000000005050433000000040050008c000045cc0000213d000039b40000c13d00000040044000390000000004040433000000000004004b000039a00000613d000000400100043d0000002402100039000000000032043500001c630200004100000000002104350000000402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001c36011001c700006e8d00010430002600050000002d000000400100043d000400000001001d00001c120010009c000045b20000213d00000001010000290000000002010433000000020100002900000000010104330000000405000029000000e003500039000000400030043f000000c00350003900000060040000390000000000430435000000a0035000390000000000430435000000400a50003900000000004a0435000000200e50003900000000004e043500000080035000390000000000030435000000600350003900000000000304350000000000050435000000400b00043d00001bb400b0009c000045b20000213d0000000504000029000000a0034000390000000003030433000000c0044000390000000004040433000000a005b00039000000400050043f0000008005b00039001500000005001d00000000004504350000006004b00039001400000004001d0000000000340435000000200cb0003900000000002c043500000000001b04350000004001b00039000000000001043500000000010d0433000000000401043300001bce0040009c000045b20000213d00000005014002100000003f0210003900001c0e03200197000000400200043d0000000003320019000000000023004b0000000005000039000000010500403900001bce0030009c000045b20000213d0000000100500190000045b20000c13d000000400030043f0000000003420436000000000004004b00003a150000613d0000000004000019000000400500043d00001c3a0050009c000045b20000213d0000008006500039000000400060043f0000006006500039000000000006043500000040065000390000000000060435000000200650003900000000000604350000000000050435000000000643001900000000005604350000002004400039000000000014004b00003a040000413d00000000002e043500000000010d04330000000002010433000000000002004b00120000000a001d00110000000b001d00100000000c001d00003ae40000613d000000000f00001900080000000d001d00070000000e001d0000000507f002100000000001710019000000200110003900000000060104330000000021060434001900000002001d000000050010008c000045cc0000213d000000000001004b00003a2f0000c13d00000018020000290000000002020433000000040020008c000045cc0000213d000045f10000c13d00000000030c043300000000020b04330000008004600039000000000504043300000060046000390000000004040433000000000054004b001a00000006001d00003a3c0000c13d000000000032004b00003a440000c13d001b00000004001d00003ac20000013d0000000006000415000000250660008a0000000506600210000000000032004b00003a590000c13d001b00000004001d000000000805001900003a830000013d00000000054200a9000000000004004b00003a4a0000613d00000000064500d9000000000026004b000045c00000c13d000000000003004b000045ac0000613d001b0000003500e10000001b063000b9000000000035004b00003a530000413d0000001b056000fa000000000035004b000045c00000c13d000000000002004b000045ac0000613d00000000022600d9000000000042004b00003ac20000613d000045c60000013d000000000907001900000000064200a9000000000004004b00003a600000613d00000000074600d9000000000027004b000045c00000c13d000000000003004b000045ac0000613d001b0000003600e10000001b073000b9000000000036004b00003a690000413d0000001b067000fa000000000036004b000045c00000c13d000000000002004b000045ac0000613d00000000062700d9000000000046004b000045c60000c13d00000000045200a9000000000005004b00003a740000613d00000000065400d9000000000026004b000045c00000c13d00000000063400d9000000000806001900000000063600a9000000000034004b00003a7c0000413d00000000048600d9000000000034004b000045c00000c13d00000000022600d90000000006000415000000240660008a0000000506600210000000000052004b0000000007090019000045c60000c13d0000000502600270000000000208001f0000001b0080006b00003ac20000613d001600000008001d000b00000007001d0000001501000029000000000201043300000014010000290000000003010433000c00000002001d000000000132004b000045c00000413d000d00000003001d000e00000001001d000f0000000f001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000000d06000029000000000161004b000000120a000029000000110b000029000000100c000029000000080d000029000000070e0000290000000f0f0000290000000e05000029000045c00000413d000000000315004b000045c00000413d0000001b023000b90000001b0000006b00003ab10000613d0000001b042000fa000000000034004b000045c00000c13d00000016031000b9000000160000006b00003ab70000613d00000016043000fa000000000014004b000045c00000c13d000000000032001a000045c00000413d0000000c0060006b000045ac0000613d0000001a010000290000000001010433000000050010008c0000000b07000029000045cc0000213d0000000002320019001b0000005200e1000000400200043d00001c3a0020009c000045b20000213d000000190300002900000000030304330000001a04000029000000400440003900000000040404330000008005200039000000400050043f00000060052000390000001b0600002900000000006504350000004005200039000000000045043500001ba70330019700000020042000390000000000340435000000000012043500000000010e043300000000030104330000000000f3004b000045ba0000a13d00000000031700190000002003300039000000000023043500000000010104330000000000f1004b000045ba0000a13d000000010ff0003900000000010d0433000000000201043300000000002f004b00003a200000413d00000017010000290000000001010433000000000401043300001bce0040009c000045b20000213d00000005014002100000003f0210003900001c0e03200197000000400200043d0000000003320019000000000023004b0000000005000039000000010500403900001bce0030009c000045b20000213d0000000100500190000045b20000c13d000000400030043f0000000003420436000000000004004b00003b0d0000613d0000000004000019000000400500043d00001bb40050009c000045b20000213d000000a006500039000000400060043f000000800650003900000000000604350000006006500039000000000006043500000040065000390000000000060435000000200650003900000000000604350000000000050435000000000643001900000000005604350000002004400039000000000014004b00003afa0000413d00000000002a0435000000170100002900000000030104330000000001030433000000000001004b00003bd10000613d000000000700001900000000020c043300000000010b0433000000050470021000000020094000390000000003390019000000000d0304330000008003d0003900000000040304330000006003d000390000000003030433000000000043004b00003b240000c13d000000000021004b00003b2c0000c13d000000000e03001900003baa0000013d0000000005000415000000230550008a0000000505500210000000000021004b00003b410000c13d000000000e030019000000000604001900003b680000013d00000000043100a9000000000003004b00003b320000613d00000000053400d9000000000015004b000045c00000c13d000000000002004b000045ac0000613d000000000e2400d900000000052e00a9000000000024004b00003b3b0000413d0000000004e500d9000000000024004b000045c00000c13d000000000001004b000045ac0000613d00000000011500d9000000000031004b00003baa0000613d000045c60000013d00000000053100a9000000000003004b00003b470000613d00000000063500d9000000000016004b000045c00000c13d000000000002004b000045ac0000613d000000000e2500d900000000062e00a9000000000025004b00003b500000413d0000000005e600d9000000000025004b000045c00000c13d000000000001004b000045ac0000613d00000000051600d9000000000035004b000045c60000c13d00000000034100a9000000000004004b00003b5b0000613d00000000054300d9000000000015004b000045c00000c13d00000000062300d900000000052600a9000000000023004b00003b620000413d00000000036500d9000000000023004b000045c00000c13d00000000011500d90000000005000415000000220550008a0000000505500210000000000041004b000045c60000c13d0000000501500270000000000106001f00000000006e004b00003baa0000613d0000001501000029000000000201043300000014010000290000000003010433000c00000002001d000000000132004b000045c00000413d000d00000003001d000e00000001001d000f00000006001d00160000000e001d00190000000d001d001a00000009001d001b00000007001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000000d08000029000000000181004b000000120a000029000000110b000029000000100c0000290000001b070000290000001a09000029000000190d00002900000016040000290000000f050000290000000e06000029000045c00000413d000000000316004b000045c00000413d0000000c0080006b000045c00000613d00000000024300a9000000000004004b00003b9c0000613d00000000044200d9000000000034004b000045c00000c13d00000000035100a9000000000005004b00003ba20000613d00000000045300d9000000000014004b000045c00000c13d000000000032001a000045c00000413d000000010160008a0000000002320019000000000021001a000045c00000413d0000000001210019000000000e6100d900000000320d0434000000050020008c000045cc0000213d000000400100043d00001bb40010009c000045b20000213d00000000030304330000004004d000390000000004040433000000a005d000390000000005050433000000a006100039000000400060043f00001ba7055001970000008006100039000000000056043500000060051000390000000000e504350000004005100039000000000045043500001ba70330019700000020041000390000000000340435000000000021043500000000020a04330000000003020433000000000073004b000045ba0000a13d000000000329001900000000001304350000000001020433000000000071004b000045ba0000a13d0000000107700039000000170100002900000000030104330000000001030433000000000017004b00003b140000413d000000090100002900000004020000290000000000210435000000400600043d00001c3b0060009c000045b20000213d0000002001600039000000400010043f000000000006043500000018010000290000000002010433000000040020008c000045cc0000213d00000009010000290000000001010433001b00000001001d00003cb50000c13d0000000a01000029000000000201043300000140012000390000000001010433001a00000002001d000000600220003900000000020204330000000002020433000000000012004b000046260000c13d0000001b010000290000004001100039001800000001001d0000000003010433000000004803043400001bce0080009c000045b20000213d00000005078002100000003f0170003900001c0e02100197000000400100043d0000000005210019000000000015004b0000000002000039000000010200403900001bce0050009c000045b20000213d0000000100200190000045b20000c13d0000000a02000029000000800220003900000000020204330000001b06000029000000200f60003900000000060f0433000000400050043f0000000005810436000000000008004b00003c1b0000613d0000000008000019000000400900043d00001c3a0090009c000045b20000213d000000800a9000390000004000a0043f000000600a90003900000000000a0435000000400a90003900000000000a0435000000200a90003900000000000a04350000000000090435000000000a85001900000000009a04350000002008800039000000000078004b00003c0a0000413d0000000007030433000000000007004b00003c430000613d000000000700001900000005087002100000000009840019000000000b09043300000000ca0b04340000000500a0008c000045cc0000213d000000400900043d00001c3a0090009c000045b20000213d000000000c0c0433000000400db00039000000000d0d0433000000600bb00039000000000b0b0433000000800e9000390000004000e0043f000000600e9000390000000000be0435000000400b9000390000000000db043500001ba70bc00197000000200c9000390000000000bc04350000000000a90435000000000a01043300000000007a004b000045ba0000a13d000000000885001900000000009804350000000008010433000000000078004b000045ba0000a13d00000001077000390000000008030433000000000087004b00003c1f0000413d0000001a030000290000000005030433000000400400043d000000440340003900000080070000390000000000730435000000200340003900001c660700004100000000007304350000002407400039000000000800041100000000008704350000000008060433000000a4074000390000000000870435000000c407400039000000000008004b00003c6b0000613d00000000090000190000002006600039000000000a06043300000000bc0a04340000000500c0008c000045cc0000213d000000000cc70436000000000b0b043300001ba70bb001970000000000bc0435000000400ba00039000000000b0b0433000000400c7000390000000000bc0435000000600aa00039000000000a0a0433000000600b7000390000000000ab043500000080077000390000000109900039000000000089004b00003c560000413d0000000006470049000000240660008a0000006408400039000000000068043500000000080104330000000006870436000000000008004b00003c890000613d00000000070000190000002001100039000000000901043300000000ab0904340000000500b0008c000045cc0000213d000000000bb60436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b6000390000000000ab043500000060099000390000000009090433000000600a60003900000000009a043500000080066000390000000107700039000000000087004b00003c740000413d0000000001460049000000240110008a0000008407400039000000000017043500000000720204340000000001260436000000000002004b00003c990000613d000000000600001900000000081600190000000009670019000000000909043300000000009804350000002006600039000000000026004b00003c920000413d000000000621001900000000000604350000001f0220003900001c2b0220019700000000024200490000000001120019000000200210008a00000000002404350000001f0110003900001c2b021001970000000001420019000000000021004b0000000002000039000000010200403900001bce0010009c000045b20000213d0000000100200190000045b20000c13d00001ba702500197000000400010043f00000000040404330000000001000414000000040020008c00160000000f001d00003d860000c13d0000000109000039000000010100003100003d970000013d0000000601000029000000000f01043300000005030000290000000041030434000000e00330003900000000030304330000000004040433000000020020008c00003cc30000c13d00000000050004150000001d0550008a0000000505500210001d00010000003d00003cca0000013d00000000050004150000001c0550008a0000000505500210000000030020008c001c00000000003d001c00010000603d000040460000c13d00001ba7024001970000000009000411000000000029004b0000000504500270000000000400003f000000010400c03f000040460000613d000000400800043d00001c3d0080009c000045b20000213d00001ba70a1001970000001b0400002900000040014000390000002004400039000000000b040433000000000c0104330000000a04000029000000800140003900000000070104330000000001040433000000a0041000390000000005040433000000c00110003900000000040104330000014001800039000000400010043f0000012001800039000000000031043500000100038000390000000000430435000000e0048000390000000000540435000000c0058000390000000000650435000000a006800039000000000076043500000080078000390000000000c70435000000600c8000390000000000bc0435000000400b8000390000000000ab0435000000200a80003900000000009a04350000000000f8043500001c3e09000041000000400e00043d00000000009e04350000000409e00039000000200d0000390000000000d9043500000000080804330000002409e00039000000000089043500000000080a043300001ba7088001970000004409e00039000000000089043500000000080b043300001ba7088001970000006409e00039000000000089043500000000090c04330000014008000039000000840ae0003900000000008a04350000016408e00039000000000a0904330000000000a80435001b0000000e001d0000018408e0003900000000000a004b00003d290000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c000045cc0000213d000000000ee80436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e8000390000000000de0435000000600cc00039000000000c0c0433000000600d8000390000000000cd04350000008008800039000000010bb000390000000000ab004b00003d140000413d0000001b0b0000290000000009b80049000000240a90008a0000000009070433000000a407b000390000000000a70435000000000a0904330000000007a8043600000000000a004b00003d4e0000613d00000000080000190000002009900039000000000b09043300000000cd0b04340000000500d0008c000045cc0000213d000000000dd70436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d7000390000000000cd0435000000600cb00039000000000c0c0433000000600d7000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c7000390000000000bc0435000000a00770003900000001088000390000000000a8004b00003d340000413d0000001b0c0000290000000008c70049000000240880008a0000000006060433000000c409c00039000000000089043500000000980604340000000006870436000000000008004b00003d600000613d0000000007000019000000000a670019000000000b790019000000000b0b04330000000000ba04350000002007700039000000000087004b00003d590000413d000000000786001900000000000704350000001f0780003900001c2b0770019700000000087600190000000006c80049000000240760008a0000000006050433000000e405c00039000000000075043500000000070604330000000005780436000000000007004b00003d750000613d00000000080000190000002006600039000000000906043300000000059504360000000108800039000000000078004b00003d6f0000413d00000000040404330000010406c00039000000000046043500000000030304330000012404c0003900000000003404350000014403c00039000000000101043300000000001304350000000001000414000000040020008c00003fff0000c13d0000000103000031000000200030008c00000020040000390000000004034019000040310000013d00001ba40030009c00001ba403008041000000400330021000001ba40040009c00001ba4040080410000006004400210000000000334019f00001ba40010009c00001ba401008041000000c001100210000000000113019f6e8b6e810000040f000000010920018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b0000008008000039001900600000003d00003dc60000613d00001bce0010009c000045b20000213d0000001f0210003900001c2b022001970000003f0220003900001c2b02200197000000400300043d0000000002230019001900000003001d000000000032004b0000000003000039000000010300403900001bce0020009c000045b20000213d0000000100300190000045b20000c13d000000400020043f0000001902000029000000000812043600001c2b021001980000001f0310018f0000000001280019000000030400036700003db90000613d000000000504034f0000000006080019000000005705043c0000000006760436000000000016004b00003db50000c13d000000000003004b00003dc60000613d000000000224034f0000000303300210000000000401043300000000043401cf000000000434022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000242019f0000000000210435001700000009001d001500000008001d0000001a01000029000000000101043300001ba701100197000000000010043f0000000401000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000201043b000000000102041a000000010310003a0000001704000029000045c00000613d000000000032041b0000001a02000029000000000202043300000060022002100014000000120143000000000004004b000046290000613d000000400100043d00001c670010009c000045b20000213d000000240210003900001c68030000410000000000320435000000440210003900000000030004140000006004000039000000000042043500001c69020000410000000000210435000000640210003900000000000204350000000402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001ba40030009c00001ba403008041000000c002300210000000000121019f00001c6a011001c700008006020000396e8b6e810000040f0000000100200190000046350000613d000000000101043b000000000001004b00000015070000290000463b0000613d000000400d00043d00001c6b02000041000000000f2d04360000000402d0003900000020030000390000000000320435000000190200002900000000030204330000002402d0003900000000003204350000004404d00039000000000003004b00003e180000613d000000000200001900000000054200190000000006270019000000000606043300000000006504350000002002200039000000000032004b00003e110000413d00000000023400190000000000020435000000000500041400001ba702100197000000040020008c00003e2a0000c13d0000000006000415000000210660008a00000005066002100000000005000415000000200550008a000000050550021000000003010003670000000102000031002000000000003d002100000000003d000000160e00002900003e4f0000013d00170000000f001d0000001f0130003900001c2b011001970000000001d10049000000000141001900001ba40010009c00001ba401008041000000600110021000001ba400d0009c00190000000d001d00001ba40300004100000000030d40190000004003300210000000000131019f00001ba40050009c00001ba405008041000000c003500210000000000131019f6e8b6e860000040f00000000060004150000001f0660008a000000050660021000000000050004150000001e0550008a00000005055002100000000003010019000000600330027000011ba40030019d0003000000010355001f00000000003d001e00000000003d0000000100200190000000160e00002900003fbd0000613d00001ba402300197000000190d000029000000170f00002900001c2b042001980000001f0720018f00000000034d001900003e590000613d000000000801034f00000000090d0019000000008a08043c0000000009a90436000000000039004b00003e550000c13d000000000007004b00003e660000613d000000000141034f0000000304700210000000000703043300000000074701cf000000000747022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000171019f00000000001304350000001f0120003900001c2b011001970000000003d10019000000000013004b0000000001000039000000010100403900001bce0030009c000045b20000213d0000000100100190000045b20000c13d000000400030043f00001c0f0020009c000045b80000213d000000400020008c000045b80000413d00000000010d043300001bce0010009c000045b80000213d0000000004d100190000000007d2001900001c0d017001970000001f0240003900001c0d08200197000000000918013f000000000018004b000000000800001900001c0d08004041000000000072004b000000000200001900001c0d0200804100001c0d0090009c000000000802c019000000000008004b000045b80000c13d000000002804043400001bce0080009c000045b20000213d00000005048002100000003f0440003900001c0e04400197000000000434001900001bce0040009c000045b20000213d000000400040043f000000000483043600000007088002100000000008820019000000000078004b000045b80000213d000000000082004b00003eb80000813d0000000009040019000000000a27004900001c0f00a0009c000045b80000213d0000008000a0008c000045b80000413d000000400a00043d00001c3a00a0009c000045b20000213d000000800ba000390000004000b0043f00000000bc0204340000000500c0008c000045b80000213d000000000cca0436000000000b0b043300001ba700b0009c000045b80000213d0000000000bc0435000000400b200039000000000b0b0433000000400ca000390000000000bc0435000000600b200039000000000b0b0433000000600ca000390000000000bc04350000000009a904360000008002200039000000000082004b00003e9a0000413d00000000020f043300001bce0020009c000045b80000213d0000000002d200190000001f08200039000000000078004b000000000900001900001c0d0900804100001c0d08800197000000000a18013f000000000018004b000000000100001900001c0d0100404100001c0d00a0009c000000000109c019000000000001004b000045b80000c13d000000008902043400001bce0090009c000045b20000213d00000005019002100000003f0110003900001c0e02100197000000400100043d0000000002210019000000000012004b000000000a000039000000010a00403900001bce0020009c000045b20000213d0000000100a00190000045b20000c13d000000400020043f0000000002910436000000a0099000c90000000009980019000000000079004b000045b80000213d000000000098004b00003f050000813d000000000a020019000000000b87004900001c0f00b0009c000045b80000213d000000a000b0008c000045b80000413d000000400b00043d00001bb400b0009c000045b20000213d000000a00cb000390000004000c0043f00000000cd0804340000000500d0008c000045b80000213d000000000ddb0436000000000c0c043300001ba700c0009c000045b80000213d0000000000cd0435000000400c800039000000000c0c0433000000400db000390000000000cd0435000000600cb00039000000600d800039000000000d0d04330000000000dc0435000000800c800039000000000c0c043300001ba700c0009c000045b80000213d000000800db000390000000000cd0435000000000aba0436000000a008800039000000000098004b00003ee10000413d0000000506600270000000000603001f0000000505500270000000000501001f0000001a050000290000004005500039000000000505043300000000050504330000000006030433000000000065004b00003fbd0000213d000000000005004b00003f450000613d000000000600001900000000070e04330000000008070433000000000068004b000045ba0000a13d0000000008030433000000000068004b000045ba0000a13d000000050960021000000000077900190000002007700039000000000b070433000000008a0b04340000000500a0008c000045cc0000213d0000000007940019000000000c0704330000000300a0008c0000004007b000390000004009c0003900003f2e0000a13d000000000d07043300000000000d004b00003f2e0000c13d000000020aa0008a0000000000ab0435000000000d0904330000000000d70435000000600dc00039000000000d0d0433000000600bb00039000000000b0b04330000000000db004b00003fbd0000213d00000000bc0c04340000000500c0008c000045cc0000213d0000000000ca004b00003fbd0000c13d0000000008080433000000000a0b043300000000088a013f00001ba70080019800003fbd0000c13d00000000080904330000000007070433000000000087004b00003fbd0000c13d0000000106600039000000000056004b00003f130000413d00000000003e0435000000000503043300001bce0050009c000045b20000213d00000005075002100000003f0670003900001c0e08600197000000400600043d0000000008860019000000000068004b0000000009000039000000010900403900001bce0080009c000045b20000213d0000000100900190000045b20000c13d000000400080043f00000000095604360000001f0870018f00000000050000310000000205500367000000000007004b00003f620000613d0000000007790019000000000a05034f00000000ab0a043c0000000009b90436000000000079004b00003f5e0000c13d000000000008004b0000001b07000029000000a00770003900000000006704350000000006030433000000000006004b00003f7a0000613d000000000600001900000000080704330000000009080433000000000069004b000045ba0000a13d0000000509600210000000000889001900000000099400190000000009090433000000600990003900000000090904330000002008800039000000000098043500000001066000390000000008030433000000000086004b00003f6a0000413d0000000003010433000000180400002900000000040404330000000067040434000000000073004b00003fbd0000213d000000000003004b00003fc80000613d000000000700001900003f870000013d0000000107700039000000000037004b00003fc80000813d0000000008010433000000000078004b000045ba0000a13d0000000008040433000000000078004b000045ba0000a13d00000005097002100000000008960019000000000808043300000000bd0804340000000500d0008c000045cc0000213d000000000992001900000000090904330000000300d0008c000000400a800039000000400c90003900003fa00000a13d000000000e0a043300000000000e004b00003fa00000c13d000000020dd0008a0000000000d80435000000000e0c04330000000000ea0435000000600e800039000000000e0e0433000000600f900039000000000f0f04330000000000ef004b00003fbd0000213d00000000ef0904340000000500f0008c000045cc0000213d0000000000fd004b00003fbd0000c13d000000000b0b0433000000000d0e0433000000000bbd013f00001ba700b0019800003fbd0000c13d000000000b0c0433000000000a0a04330000000000ba004b00003fbd0000c13d0000008008800039000000000808043300001ba70880019800003f840000613d0000008009900039000000000909043300001ba709900197000000000098004b00003f840000613d000000400100043d00001c6e02000041000000000021043500000004021000390000001403000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000000018030000290000000000130435000000000601043300001bce0060009c000045b20000213d00000005046002100000003f0340003900001c0e07300197000000400300043d0000000007730019000000000037004b0000000008000039000000010800403900001bce0070009c000045b20000213d0000000100800190000045b20000c13d000000400070043f00000000076304360000001f0640018f000000000004004b00003fe30000613d0000000004470019000000005805043c0000000007870436000000000047004b00003fdf0000c13d000000000006004b0000001b04000029000000c00440003900000000003404350000000003010433000000000003004b00003ffb0000613d000000000300001900000000050404330000000006050433000000000036004b000045ba0000a13d0000000506300210000000000556001900000000066200190000000006060433000000600660003900000000060604330000002005500039000000000065043500000001033000390000000005010433000000000053004b00003feb0000413d0000000601000029000000140200002900000000002104350000409b0000013d00190000000f001d0000000003c5004900001ba40030009c00001ba403008041000000600330021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000334019f00001ba40010009c00001ba401008041000000c001100210000000000131019f6e8b6e810000040f0000001b0c0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057c00190000401f0000613d000000000801034f00000000090c0019000000008a08043c0000000009a90436000000000059004b0000401b0000c13d000000000006004b0000402c0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000190f000029000046a60000613d0000001f01400039000000600210018f0000000001c20019000000000021004b0000000002000039000000010200403900001bce0010009c000045b20000213d0000000100200190000045b20000c13d000000400010043f000000200030008c000045b80000413d00000000020c043300001c3f00200198000045b80000c13d00001c400220019700001c3e0020009c000046770000c13d0000000601000029000000000f01043300000002010000290000000001010433000000000001004b0000409b0000613d001b00000001001d00000001010000290000000001010433001a00000001001d00190000000f001d0000000000f0043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000101043b000000000201041a0000008805200272000040690000613d000000100220027000001c1f022001970000001a06000029000000000065004b0000001b030000290000406c0000c13d0000000004020019000000000203001900000000030600190000407c0000013d0000001b050000290000001a03000029000040950000013d00000000046200a9000000000002004b000040720000613d00000000022400d9000000000062004b000045c00000c13d00000000023500a900000000033200d9000000000053004b000045c00000c13d000000000006004b000045a00000613d00000000036500a900000000066300d9000000000056004b000045c00000c13d000000000042001a000045c00000413d0000000002420019000000000032004b000045a30000213d000000000423019f00001c5a0040009c000040860000813d0000000005020019000040950000013d000000000003004b000045ac0000613d00000000050300190000000006020019000000000405001900000000504600d9000000000005004b00000000060400190000408a0000c13d00000000054200d900001c1f0050009c000045c00000213d00000000034300d900001c1f0030009c000045c00000213d0000008802300210000000100350021000001c4203300197000000000223019f00000001022001bf000000000021041b000000400100043d001a00000001001d00001ba80010009c000045b20000213d000000090100002900000000040104330000001a030000290000004001300039000000400010043f00000020023000390000006001000039001200000002001d00000000001204350000000000030435001400260000002d001100000004001d0000002001400039001900000001001d00000000010104330000000002010433000000000002004b0000414e0000613d000000140300002900000120023000390000000002020433001700000002001d000000000203043300161ba70020019b000000030200002900001ba709200197000000000a000019001800000009001d000040c90000013d0000001602000029000000000309001900000017060000290000001a070000296e8b46c00000040f00000018090000290000001b0a000029000000010aa0003900000019010000290000000001010433000000000201043300000000002a004b0000414e0000813d0000000502a002100000000001210019000000200110003900000000040104330000000012040434000000050020008c000045cc0000213d000000400300043d00001bb40030009c000045b20000213d0000006005400039000000000505043300000040044000390000000004040433000000000101043300001ba701100197000000a006300039000000400060043f000000800630003900000000009604350000006006300039000000000056043500000040063000390000000000460435000000200630003900000000001604350000000000230435000000000002004b000040f10000613d000000010020008c001b0000000a001d000040fe0000613d000000020020008c000040bc0000c13d0000001602000029000000000309001900000017060000290000001a070000296e8b48f10000040f000040c10000013d00000000004101a0000045d50000c13d000000000005004b000045db0000613d0000000001000414000000040090008c001500000005001d000041090000c13d00000001010000310000000102000039000000000001004b0000411c0000c13d000041430000013d000000000004004b000045d50000c13d00000016020000290000000003090019000000000405001900000017050000290000001a060000296e8b604a0000040f0000001b0a0000290000001809000029000040c30000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c70000800902000039000000000305001900000000040900190000000005000019001b0000000a001d6e8b6e810000040f0000001b0a0000290000001809000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000041430000613d00001bce0010009c000045b20000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000045b20000213d0000000100500190000045b20000c13d000000400040043f000000000613043600001c2b0410019800000000034600190000000305000367000041360000613d000000000705034f000000007807043c0000000006860436000000000036004b000041320000c13d0000001f01100190000041430000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b000040c30000c13d000000400100043d00000024021000390000001503000029000000000032043500001c4502000041000000000021043500000004021000390000000000920435000039bb0000013d00000011010000290000004001100039001900000001001d00000000010104330000000002010433000000000002004b000042090000613d0000000002000411001800000002001d00000000090000190000416b0000013d0000006001600039000000000501043300000080016000390000000002010433000000000103043300001ba70110019700001ba703200197000000180200002900000013060000290000001a070000296e8b48f10000040f0000001b090000290000000109900039000000190100002900000000010104330000000002010433000000000029004b000042090000813d00000005029002100000000001120019000000200110003900000000060104330000000031060434000000050010008c000045cc0000213d000000000001004b001b00000009001d000041900000c13d001700000003001d001500000006001d00000060016000390000000001010433001600000001001d00001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b000000160010006b0000001b090000290000001703000029000045f40000213d00000015060000290000000001060433000000050010008c000045cc0000213d00000040026000390000000004020433000000000001004b000041b20000613d000000010010008c000041a40000613d000000020010008c000041590000613d0000006001600039000000000501043300000080016000390000000002010433000000000103043300001ba70110019700001ba703200197000000180200002900000013060000290000001a070000296e8b46c00000040f000041640000013d000000000004004b000045d50000c13d0000006001600039000000000401043300000080016000390000000002010433000000000103043300001ba70110019700001ba703200197000000180200002900000013050000290000001a060000296e8b604a0000040f000041640000013d000000000103043300001ba70110019700000000004101a0000045d50000c13d00000060016000390000000003010433000000000003004b000045db0000613d0000008001600039000000000101043300001ba7041001970000000001000414000000040040008c001700000003001d001600000004001d000041c70000c13d00000001010000310000000102000039000000000001004b000041d60000c13d000041fd0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f0000001b09000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000041fd0000613d00001bce0010009c000045b20000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000045b20000213d0000000100500190000045b20000c13d000000400040043f000000000613043600001c2b0410019800000000034600190000000305000367000041f00000613d000000000705034f000000007807043c0000000006860436000000000036004b000041ec0000c13d0000001f01100190000041fd0000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b000041650000c13d000000400100043d00000024021000390000001703000029000000000032043500001c45020000410000000000210435000000040210003900000016030000290000000000320435000039bb0000013d000000120100002900000000010104330000000001010433000000000001004b000042eb0000613d0000001a010000290000000001010433001a00000001001d000000400100043d001b00000001001d000000200210003900001c4801000041001900000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000001b0400002900000060024000390000001a030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b0000001b04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c000045b20000213d0000001b02000029000000c001200039000000400010043f000000190100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000045b80000613d000000000101043b00001c4a02000041000000000020044300001ba701100197001b00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000045c90000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b000046060000613d0000001201000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b0000429e0000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c000045cc0000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b0000427f0000413d00000000040004140000001b02000029000000040020008c000042a70000c13d0000000103000031000000200030008c00000020040000390000000004034019000042d80000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f001b0000000b001d6e8b6e810000040f0000001b0b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000042c70000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000042c30000c13d000000000006004b000042d40000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000465d0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c000045b20000213d0000000100200190000045b20000c13d000000400010043f000000200030008c000045b80000413d00000000010b043300001c3f00100198000045b80000c13d00000060010000390000001202000029000000000012043500001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f0000000100200190000045c90000613d000000000101043b000000000001004b0000434f0000613d00001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f0000000100200190000045c90000613d000000000301043b000000000003004b000045db0000613d0000000001000414000000000200041100001ba704200197000000040040008c001b00000003001d001a00000004001d000043170000c13d00000001020000390000000101000031000000000001004b000043250000c13d0000434d0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b0000434d0000613d00001bce0010009c000045b20000213d0000001f0410003900001c2b044001970000003f0440003900001c2b05400197000000400400043d0000000005540019000000000045004b0000000006000039000000010600403900001bce0050009c000045b20000213d0000000100600190000045b20000c13d000000400050043f000000000614043600001c2b031001980000001f0410018f00000000013600190000000305000367000043400000613d000000000705034f000000007807043c0000000006860436000000000016004b0000433c0000c13d000000000004004b0000434d0000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000000002004b000046110000613d000000400100043d00001ba80010009c000045b20000213d0000004002100039000000400020043f0000000102000039000000000221043600000000030000310000000203300367000000000303043b0000000000320435000000060300002900000000030304330000000000320435000000140200002900000080022000390000000004020433000000040040008c000045cc0000213d0000000607000029000000000c0704330000000902000029000000000602043300001c6f05400197000000400d00043d000000140200002900000000f202043400001ba703200197000000020050008c000044290000c13d00000000020f043300001ba7022001970000000009000411000000000029004b000045390000613d00001c3d00d0009c000045b20000213d0000001404000029000000e004400039000000000504043300000040046000390000002006600039000000000a060433000000000b0404330000000a06000029000000800460003900000000080404330000000004060433000000a0064000390000000007060433000000c00440003900000000060404330000014004d00039000000400040043f0000012004d0003900000000005404350000010005d000390000000000650435000000e006d000390000000000760435000000c007d000390000000000170435000000a001d0003900000000008104350000008008d000390000000000b80435000000600bd000390000000000ab0435000000400ad0003900000000003a04350000002003d000390000000000930435001b0000000c001d0000000000cd043500001c4d09000041000000400e00043d00000000009e04350000000409e00039000000200c0000390000000000c9043500000000090d0433000000240ce0003900000000009c0435000000000303043300001ba7033001970000004409e00039000000000039043500000000030a043300001ba7033001970000006409e00039000000000039043500000000090b04330000014003000039000000840ae0003900000000003a04350000016403e00039000000000a0904330000000000a30435001a0000000e001d0000018403e0003900000000000a004b000043cb0000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c000045cc0000213d000000000ee30436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e3000390000000000de0435000000600cc00039000000000c0c0433000000600d3000390000000000cd04350000008003300039000000010bb000390000000000ab004b000043b60000413d0000001a0a0000290000000009a30049000000240990008a0000000008080433000000a40aa0003900000000009a043500000000090804330000000003930436000000000009004b000043f00000613d000000000a0000190000002008800039000000000b08043300000000cd0b04340000000500d0008c000045cc0000213d000000000dd30436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d3000390000000000cd0435000000600cb00039000000000c0c0433000000600d3000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c3000390000000000bc0435000000a003300039000000010aa0003900000000009a004b000043d60000413d0000001a0c0000290000000008c30049000000240880008a0000000001010433000000c409c00039000000000089043500000000980104340000000001830436000000000008004b000044020000613d0000000003000019000000000a130019000000000b390019000000000b0b04330000000000ba04350000002003300039000000000083004b000043fb0000413d000000000381001900000000000304350000001f0380003900001c2b0330019700000000013100190000000003c10049000000240830008a0000000003070433000000e407c00039000000000087043500000000070304330000000001710436000000000007004b000044170000613d00000000080000190000002003300039000000000903043300000000019104360000000108800039000000000078004b000044110000413d00000000030604330000010406c00039000000000036043500000000030504330000012405c0003900000000003504350000014403c00039000000000404043300000000004304350000000003000414000000040020008c000044f20000c13d0000000103000031000000200030008c000000200400003900000000040340190000001b02000029000045250000013d000000040040008c000045390000c13d001b0000000c001d0000000a0400002900000080044000390000000004040433000000400560003900000000050504330000002006600039000000000706043300001c6d0600004100000000006d04350000000406d00039000000a0080000390000000000860435000000a406d0003900000000080704330000000000860435000000c406d00039000000000008004b000044540000613d00000000090000190000002007700039000000000a07043300000000bc0a04340000000500c0008c000045cc0000213d000000000cc60436000000000b0b043300001ba70bb001970000000000bc0435000000400ba00039000000000b0b0433000000400c6000390000000000bc0435000000600aa00039000000000a0a0433000000600b6000390000000000ab043500000080066000390000000109900039000000000089004b0000443f0000413d0000000007d60049000000040770008a0000002408d00039000000000078043500000000070504330000000006760436000000000007004b000044770000613d00000000080000190000002005500039000000000905043300000000ab0904340000000500b0008c000045cc0000213d000000000bb60436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b6000390000000000ab0435000000600a900039000000000a0a0433000000600b6000390000000000ab04350000008009900039000000000909043300001ba709900197000000800a60003900000000009a0435000000a0066000390000000108800039000000000078004b0000445d0000413d0000000005d60049000000040550008a0000004407d00039000000000057043500000000750404340000000004560436000000000005004b000044870000613d000000000600001900000000084600190000000009670019000000000909043300000000009804350000002006600039000000000056004b000044800000413d000000000654001900000000000604350000001f0550003900001c2b0550019700000000045400190000000005d40049000000040550008a0000006406d00039000000000056043500000000050104330000000004540436000000000005004b0000001b080000290000449c0000613d00000000060000190000002001100039000000000701043300000000047404360000000106600039000000000056004b000044960000413d0000006001200210000000000181013f0000008402d0003900000000001204350000000001000414000000040030008c000044a80000c13d0000000103000031000000200030008c00000020040000390000000004034019000044dd0000013d00190000000f001d0000000002d4004900001ba40020009c00001ba402008041000000600220021000001ba400d0009c00001ba40400004100000000040d40190000004004400210000000000242019f00001ba40010009c00001ba401008041000000c001100210000000000112019f0000000002030019001a0000000d001d6e8b6e810000040f0000001a0d0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057d0019000044ca0000613d000000000801034f00000000090d0019000000008a08043c0000000009a90436000000000059004b000044c60000c13d000000000006004b000044d70000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000190f0000290000001b080000290000467c0000613d0000001f01400039000000600210018f0000000001d20019000000000021004b0000000002000039000000010200403900001bce0010009c000045b20000213d0000000100200190000045b20000c13d000000400010043f000000200030008c000045b80000413d00000000020d043300001c3f00200198000045b80000c13d00001c400220019700001c6d0020009c000046690000c13d000000000d010019000045380000013d00190000000f001d0000000001c1004900001ba40010009c00001ba401008041000000600110021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000141019f00001ba40030009c00001ba403008041000000c003300210000000000113019f6e8b6e810000040f0000001a0c0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057c0019000045120000613d000000000801034f00000000090c0019000000008a08043c0000000009a90436000000000059004b0000450e0000c13d000000000006004b0000451f0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000190f0000290000001b02000029000046880000613d0000001f01400039000000600110018f000000000dc1001900000000001d004b0000000001000039000000010100403900001bce00d0009c000045b20000213d0000000100100190000045b20000c13d0000004000d0043f000000200030008c000045b80000413d00000000010c043300001c3f00100198000045b80000c13d00001c400110019700001c4d0010009c0000466e0000c13d000000060700002900000009010000290000000004010433000000400140003900000000030104330000001401000029000000000101043300000000020f04330000002004400039000000000404043300000000050704330000004006d0003900000080070000390000000000760435000000030600002900001ba7066001970000002007d00039000000000067043500000000005d04350000008005d0003900000000060404330000000000650435000000a005d00039000000000006004b000045670000613d000000000700001900000020044000390000000008040433000000009a0804340000000500a0008c000045cc0000213d000000000aa50436000000000909043300001ba70990019700000000009a043500000040098000390000000009090433000000400a50003900000000009a0435000000600880003900000000080804330000006009500039000000000089043500000080055000390000000107700039000000000067004b000045520000413d0000000004d500490000006006d00039000000000046043500000000060304330000000004650436000000000006004b000045890000613d0000000005000019000000200330003900000000070304330000000089070434000000050090008c000045cc0000213d0000000009940436000000000808043300001ba7088001970000000000890435000000400870003900000000080804330000004009400039000000000089043500000060087000390000000008080433000000600940003900000000008904350000008007700039000000000707043300001ba70770019700000080084000390000000000780435000000a0044000390000000105500039000000000065004b0000456f0000413d00001ba70620019700001ba7051001970000000001d4004900001ba40010009c00001ba401008041000000600110021000001ba400d0009c00001ba40d0080410000004002d00210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bcd011001c70000800d02000039000000030300003900001c3c040000416e8b6e810000040f0000000100200190000045b80000613d000000000001042d0000000003000019000000000032004b000040810000a13d000000400100043d00001c200200004100000000002104350000000402100039000000190300002900003fc20000013d000000000005004b0000000003050019000037890000c13d00001c1401000041000000000010043f0000001201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d0001043000001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c6502000041000045f60000013d000000000001042f000000010020008c000045de0000a13d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c6102000041000045f60000013d000000400100043d00001c4e02000041000045f60000013d000000400100043d00001c5e02000041000045f60000013d000000400100043d00001c4602000041000045f60000013d000000400300043d001b00000003001d00001c5d01000041000000000013043500000004013000396e8b5fad0000040f0000001b02000029000000000121004900001ba40010009c00001ba401008041000000600110021000001ba40020009c00001ba4020080410000004002200210000000000121019f00006e8d00010430000000400100043d00001c5f02000041000045f60000013d000000400100043d00001c6402000041000045f60000013d000000400100043d00001c4702000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d0000002402100039000000000042043500001c350200004100000000002104350000000402100039000042070000013d000000400100043d00001c5c02000041000045f60000013d00001c4c0100004100000000001b04350000001a0100002900000000001304350000001b01000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d00010430000000400100043d00000024021000390000001b03000029000000000032043500001c4502000041000000000021043500000004021000390000001a03000029000042070000013d000000400100043d00001c5b02000041000045f60000013d000000400100043d00001c1e03000041000046220000013d000000400100043d00001c200300004100000000003104350000000403100039000000000023043500003fc30000013d000000400100043d00001c2102000041000045f60000013d6e8b27330000040f00001c6e01000041000000400200043d000000000012043500000004012000390000001403000029000000000031043500001ba40020009c00001ba402008041000000400120021000001c15011001c700006e8d0001043000030000000103550000000002010019000000600220027000011ba40020019d00001ba4022001970000463d0000013d0000000301000367000000010200003100001c2b052001980000001f0620018f000000400300043d0000000004530019000046480000613d000000000701034f0000000008030019000000007907043c0000000008980436000000000048004b000046440000c13d000000000006004b000046550000613d000000000151034f0000000305600210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500001ba40030009c00001ba403008041000000400130021000001ba40020009c00001ba4020080410000006002200210000000000112019f00006e8d000104300000001f0530018f00001ba606300198000000400200043d0000000004620019000046930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000046640000c13d000046930000013d00001c6e0200004100000000002104350000000402100039000000000082043500003fc30000013d00001c410100004100000000001d04350000000401d00039000000000021043500001ba400d0009c00001ba40d0080410000004001d0021000001c15011001c700006e8d0001043000001c4102000041000000000021043500000004021000390000000000f2043500003fc30000013d0000001f0530018f00001ba606300198000000400200043d0000000004620019000046930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000046830000c13d000046930000013d0000001f0530018f00001ba606300198000000400200043d0000000004620019000046930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000468f0000c13d000000000005004b000046a00000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d000104300000001f0530018f00001ba606300198000000400200043d0000000004620019000046b10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000046ad0000c13d000000000005004b000046be0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000045e90000013d000b000000000002000700000004001d000800000003001d000900000002001d000a00000001001d000600000005001d000000000005004b000048a30000613d0000000012070434000b00000001001d000000000062004b000047b00000613d0000000b0100002900000000010104330000000001010433000000000001004b000047b00000613d000400000002001d000100000006001d000200000007001d000000400100043d000500000001001d000000200210003900001c4801000041000300000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000048a00000613d000000000101043b0000000504000029000000600240003900000004030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000048a00000613d000000000101043b0000000504000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001c700040009c000048940000813d0000000502000029000000c001200039000000400010043f000000030100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000048a10000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000500000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000048a00000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b000048b50000613d0000000b01000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b000047610000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c0000489a0000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000047420000413d00000000040004140000000502000029000000040020008c0000476a0000c13d0000000103000031000000200030008c000000200400003900000000040340190000479b0000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f00050000000b001d6e8b6e810000040f000000050b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b00190000478a0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000047860000c13d000000000006004b000047970000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000048cd0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c000048940000213d0000000100200190000048940000c13d000000400010043f000000200030008c000048a10000413d00000000010b043300001c3f00100198000048a10000c13d00000060010000390000000b02000029000000000012043500000002070000290000000106000029000000000006004b0000483c0000613d000000000f060019000000000e0700190000000b0100002900000000010104330000000001010433000000010010003a000048eb0000413d000000010310003900001bce0030009c000048940000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c000048940000213d0000000100600190000048940000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c000048940000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000753001900000000006704350000002005500039000000000045004b000047cb0000413d000000000001004b000048160000613d00000000040000190000000b0500002900000000060504330000000005060433000000000045004b0000488e0000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c0000489a0000213d000000400600043d00001bd40060009c000048940000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b0000488e0000a13d000000000553001900000000006504350000000005020433000000000045004b0000488e0000a13d0000000104400039000000000014004b000047e30000413d000000400400043d00001bd40040009c000048940000213d000000c005400039000000400050043f000000a00540003900000006060000290000000000650435000000800540003900000007060000290000000000650435000000080500002900001ba70550019700000060064000390000000000560435000000090500002900001ba705500197000000400640003900000000005604350000000a0500002900001ba70550019700000020064000390000000000560435000000030500003900000000005404350000000005020433000000000015004b0000488e0000a13d0000000505100210000000000353001900000000004304350000000003020433000000000013004b0000488e0000a13d0000000b0100002900000000002104350000000000fe0435000000000001042d00001c4a0100004100000000001004430000000a010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000048a00000613d0000000a0200002900001ba703200197000000000101043b000000000001004b000048ab0000613d00001c4a010000410000000000100443000b00000003001d0000000400300443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000048a00000613d000000000101043b000000000001004b000048a10000613d000000400400043d0000008401400039000000a0020000390000000000210435000000640140003900000006020000290000000000210435000000440140003900000007020000290000000000210435000000080100002900001ba7011001970000002402400039000000000012043500001c71010000410000000000140435000000090100002900001ba70110019700000004024000390000000000120435000000a401400039000000000001043500000000010004140000000b02000029000000040020008c0000488a0000613d00001ba40040009c00001ba4030000410000000003044019000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001c72011001c7000b00000004001d6e8b6e810000040f0000000b040000290000000003010019000000600330027000011ba40030019d00030000000103550000000100200190000048c00000613d00001bce0040009c000048940000213d000000400040043f000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000000100001900006e8d00010430000000400100043d00001c4602000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00001c730200004100000000002104350000000402100039000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c4c0100004100000000001b0435000000040100002900000000001304350000000501000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d0001043000001ba4033001970000001f0530018f00001ba606300198000000400200043d0000000004620019000048d80000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000048c80000c13d000048d80000013d0000001f0530018f00001ba606300198000000400200043d0000000004620019000048d80000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000048d40000c13d000000000005004b000048e50000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000b000000000002000800000004001d000900000003001d000a00000002001d000b00000001001d000600000007001d00000000f2070434000000000062004b000700000006001d000049de0000613d00000000010f04330000000001010433000000000001004b000049de0000613d000300000002001d000100000005001d00040000000f001d000000400100043d000500000001001d000000200210003900001c4801000041000200000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000004ac50000613d000000000101043b0000000504000029000000600240003900000003030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000004ac50000613d000000000101043b0000000504000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001c700040009c00004ab90000813d0000000502000029000000c001200039000000400010043f000000020100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000004ac60000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000500000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000004ac50000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b00004ad80000613d0000000401000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b0000498f0000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00004abf0000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000049700000413d00000000040004140000000502000029000000040020008c000049980000c13d0000000103000031000000200030008c00000020040000390000000004034019000049c90000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f00050000000b001d6e8b6e810000040f000000050b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000049b80000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000049b40000c13d000000000006004b000049c50000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000004af00000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c00004ab90000213d000000010020019000004ab90000c13d000000400010043f000000200030008c00004ac60000413d00000000010b043300001c3f0010019800004ac60000c13d0000006001000039000000040f00002900000000001f043500000007060000290000000105000029000000000006004b00004a670000613d000000000e05001900000000010f04330000000001010433000000010010003a00004b0e0000413d000000010310003900001bce0030009c00004ab90000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c00004ab90000213d000000010060019000004ab90000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c00004ab90000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000753001900000000006704350000002005500039000000000045004b000049f70000413d000000000001004b00004a410000613d000000000400001900000000060f04330000000005060433000000000045004b00004ab30000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c00004abf0000213d000000400600043d00001bd40060009c00004ab90000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b00004ab30000a13d000000000553001900000000006504350000000005020433000000000045004b00004ab30000a13d0000000104400039000000000014004b00004a0f0000413d000000400400043d00001bd40040009c00004ab90000213d000000c005400039000000400050043f000000a0054000390000000000e50435000000800540003900000008060000290000000000650435000000090500002900001ba705500197000000600640003900000000005604350000000a0500002900001ba705500197000000400640003900000000005604350000000b0500002900001ba70550019700000020064000390000000000560435000000020500003900000000005404350000000005020433000000000015004b00004ab30000a13d0000000505100210000000000353001900000000004304350000000003020433000000000013004b00004ab30000a13d00000000002f0435000000060100002900000007020000290000000000210435000000000001042d000000010050008c00004ac80000c13d00001c4a0100004100000000001004430000000b010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000004ac50000613d0000000b0200002900001ba703200197000000000101043b000000000001004b00004ace0000613d00001c4a010000410000000000100443000b00000003001d0000000400300443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000004ac50000613d000000000101043b000000000001004b00004ac60000613d000000400400043d000000440140003900000008020000290000000000210435000000090100002900001ba7011001970000002402400039000000000012043500001c750100004100000000001404350000000a0100002900001ba7011001970000000402400039000000000012043500000000010004140000000b02000029000000040020008c00004aaf0000613d00001ba40040009c00001ba4030000410000000003044019000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001c76011001c7000b00000004001d6e8b6e810000040f0000000b040000290000000003010019000000600330027000011ba40030019d0003000000010355000000010020019000004ae30000613d00001bce0040009c00004ab90000213d000000400040043f000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000000100001900006e8d00010430000000400100043d00001c740200004100000000002104350000000402100039000000000052043500004ad30000013d000000400100043d00001c730200004100000000002104350000000402100039000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c4c0100004100000000001b0435000000030100002900000000001304350000000501000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d0001043000001ba4033001970000001f0530018f00001ba606300198000000400200043d000000000462001900004afb0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00004aeb0000c13d00004afb0000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900004afb0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00004af70000c13d000000000005004b00004b080000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d000104300023000000000002000100000003001d000001e00020043f000001400040043f001000000001001d0000000012010434000300000001001d00001c310020009c000059db0000813d00000005012002100000003f0310003900001c0e03300197000000400400043d0000000003340019001200000004001d000000000043004b0000000004000039000000010400403900001bce0030009c000059db0000213d0000000100400190000059db0000c13d000000400030043f00000012030000290000000002230436000f00000002001d0000001f0210018f000000000001004b00004b390000613d0000000f04000029000000000114001900000000030000310000000203300367000000003503043c0000000004540436000000000014004b00004b350000c13d000000000002004b0000001001000029000000000201043300001bce0020009c000059db0000213d0000000501200210000000400300043d000001600030043f0000003f0410003900001c0e044001970000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c000059db0000213d0000000100500190000059db0000c13d000000400040043f0000000000230435000000000002004b00004b5e0000613d0000000002000019000000400300043d00001ba80030009c000059db0000213d0000004004300039000000400040043f0000002004300039000000000004043500000000000304350000002002200039000001600400043d00000000044200190000000000340435000000000012004b00004b500000413d002300000000003d00000010010000290000000001010433000000000001004b000052940000613d000200000000001d001300000000001d0000000002000019000c00000002001d0000000502200210000b00000002001d00000003012000290000000005010433000001a00050043f000000400400043d00001c3a0040009c000059db0000213d000001400100043d0000000001010433000e00000001001d0000008001400039000000400010043f00000040014000390000000000010435000000200140003900000000000104350000000000040435000000400100043d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000900000004001d00000060024000390000000000120435000a00000005001d0000000012050434000800000001001d000000c0012000390000000001010433001100000001001d000d00000002001d000000a0012000390000000001010433001400000001001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000059fc0000613d000000000101043b0000001403000029000000000031004b00004ce60000413d000000110010006c00004ce60000813d0000000d0100002900000080011000390000000001010433000000040010008c00005a0c0000213d0000000a020000290000004002200039000000000202043300001c1f042001970000000802000029000000000202043300001c1f0320019700004e100000c13d000000010030008c00005a310000c13d000000010040008c00005a310000c13d000000400100043d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a00210003900000000003204350000004002100039000000000032043500000020021000390000000000320435000000800210003900000000000204350000006002100039000000000002043500000000000104350000000d0100002900000040011000390000000004010433000000005304043400001bce0030009c000059db0000213d00000005023002100000003f0120003900001c0e06100197000000400100043d0000000006610019001400000001001d000000000016004b0000000007000039000000010700403900001bce0060009c000059db0000213d0000000100700190000059db0000c13d000000400060043f00000014010000290000000006310436000000000003004b00004bf80000613d0000000003000019000000400700043d00001c3a0070009c000059db0000213d0000008008700039000000400080043f0000006008700039000000000008043500000040087000390000000000080435000000200870003900000000000804350000000000070435000000000836001900000000007804350000002003300039000000000023004b00004be70000413d000000000304043300001bce0030009c000059db0000213d00000005083002100000003f0280003900001c0e07200197000000400100043d0000000007710019001100000001001d000000000017004b0000000009000039000000010900403900001bce0070009c000059db0000213d0000000100900190000059db0000c13d000000400070043f0000001101000029000000000731043600000000030000310000000203300367000000000008004b00004c160000613d0000000009870019000000000a03034f000000000b07001900000000ac0a043c000000000bcb043600000000009b004b00004c120000c13d0000001f008001900000000008040433000000000008004b00004c480000613d00000000080000190000000509800210000000000a950019000000000d0a043300000000ec0d04340000000500c0008c00005a0c0000213d000000400b00043d00001c3a00b0009c000059db0000213d000000600ad00039000000000e0e0433000000400dd00039000000000d0d0433000000000f0a04330000008002b00039000000400020043f0000006002b000390000000000f204350000004002b000390000000000d2043500001ba702e00197000000200db0003900000000002d04350000000000cb043500000014010000290000000002010433000000000082004b000059d50000a13d00000000029600190000000000b2043500000014010000290000000002010433000000000082004b000059d50000a13d00000011010000290000000002010433000000000082004b000059d50000a13d000000000279001900000000090a0433000000000092043500000001088000390000000002040433000000000028004b00004c1b0000413d0000000d01000029000000600410003900000000050404330000000019050434000e00000001001d00001bce0090009c000059db0000213d00000005089002100000003f0480003900001c0e07400197000000400400043d0000000007740019000000000047004b000000000a000039000000010a00403900001bce0070009c000059db0000213d0000000100a00190000059db0000c13d000000400070043f0000000007940436000000000009004b00004c730000613d0000000009000019000000400a00043d00001bb400a0009c000059db0000213d000000a00ba000390000004000b0043f000000800ba0003900000000000b0435000000600ba0003900000000000b0435000000400ba0003900000000000b0435000000200ba0003900000000000b043500000000000a0435000000000b9700190000000000ab04350000002009900039000000000089004b00004c600000413d000000000905043300001bce0090009c000059db0000213d000000050a9002100000003f08a0003900001c0e0b800197000000400800043d000000000bb8001900000000008b004b000000000c000039000000010c00403900001bce00b0009c000059db0000213d0000000100c00190000059db0000c13d0000004000b0043f000000000998043600000000000a004b00004c8c0000613d000000000ba90019000000000c090019000000003d03043c000000000cdc04360000000000bc004b00004c880000c13d0000001f00a001900000000003050433000000000003004b00004cc00000613d0000000003000019000000050a3002100000000e02a00029000000000e02043300000000fd0e04340000000500d0008c00005a0c0000213d000000400c00043d00001bb400c0009c000059db0000213d000000600be0003900000000020f0433000000400fe00039000000000f0f043300000000060b0433000000a00ee00039000000000e0e0433000000a001c00039000000400010043f00001ba701e00197000000800ec0003900000000001e04350000006001c0003900000000006104350000004001c000390000000000f1043500001ba7012001970000002002c0003900000000001204350000000000dc04350000000001040433000000000031004b000059d50000a13d0000000001a700190000000000c104350000000001040433000000000031004b000059d50000a13d0000000001080433000000000031004b000059d50000a13d00000000019a001900000000020b0433000000000021043500000001033000390000000001050433000000000013004b00004c910000413d000000400600043d00001c120060009c000059db0000213d0000000d02000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000830435000000a00360003900000011050000290000000000530435000000800360003900000001050000390000000000530435000000600360003900000000002304350000004002600039000000000042043500000020026000390000001403000029000000000032043500001ba7011001970000000000160435000000400100043d00001c3a0010009c000059db0000213d0000008002100039000000400020043f00000001030000390000000002310436001400000002001d00000000003204350000000002030019000000000403001900004f650000013d000000400100043d0000000e0000006b00005a250000c13d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a00210003900000000003204350000004002100039000000000032043500000020021000390000000000320435000000800210003900000000000204350000006002100039000000000002043500000000000104350000000d0100002900000040011000390000000004010433000000005304043400001bce0030009c000059db0000213d00000005023002100000003f0120003900001c0e06100197000000400100043d0000000006610019001400000001001d000000000016004b0000000007000039000000010700403900001bce0060009c000059db0000213d0000000100700190000059db0000c13d000000400060043f00000014010000290000000006310436000000000003004b00004d250000613d0000000003000019000000400700043d00001c3a0070009c000059db0000213d0000008008700039000000400080043f0000006008700039000000000008043500000040087000390000000000080435000000200870003900000000000804350000000000070435000000000836001900000000007804350000002003300039000000000023004b00004d140000413d000000000304043300001bce0030009c000059db0000213d00000005083002100000003f0280003900001c0e07200197000000400100043d0000000007710019001100000001001d000000000017004b0000000009000039000000010900403900001bce0070009c000059db0000213d0000000100900190000059db0000c13d000000400070043f0000001101000029000000000731043600000000030000310000000203300367000000000008004b00004d430000613d0000000009870019000000000a03034f000000000b07001900000000ac0a043c000000000bcb043600000000009b004b00004d3f0000c13d0000001f008001900000000008040433000000000008004b00004d750000613d00000000080000190000000509800210000000000a950019000000000d0a043300000000ec0d04340000000600c0008c00005a0c0000813d000000400b00043d00001c3a00b0009c000059db0000213d000000600ad00039000000000e0e0433000000400dd00039000000000d0d0433000000000f0a04330000008002b00039000000400020043f0000006002b000390000000000f204350000004002b000390000000000d2043500001ba702e00197000000200db0003900000000002d04350000000000cb043500000014010000290000000002010433000000000082004b000059d50000a13d00000000029600190000000000b2043500000014010000290000000002010433000000000082004b000059d50000a13d00000011010000290000000002010433000000000082004b000059d50000a13d000000000279001900000000090a0433000000000092043500000001088000390000000002040433000000000028004b00004d480000413d0000000d01000029000000600410003900000000050404330000000019050434000e00000001001d00001bce0090009c000059db0000213d00000005089002100000003f0480003900001c0e07400197000000400400043d0000000007740019000000000047004b000000000a000039000000010a00403900001bce0070009c000059db0000213d0000000100a00190000059db0000c13d000000400070043f0000000007940436000000000009004b00004da00000613d0000000009000019000000400a00043d00001bb400a0009c000059db0000213d000000a00ba000390000004000b0043f000000800ba0003900000000000b0435000000600ba0003900000000000b0435000000400ba0003900000000000b0435000000200ba0003900000000000b043500000000000a0435000000000b9700190000000000ab04350000002009900039000000000089004b00004d8d0000413d000000000905043300001bce0090009c000059db0000213d000000050a9002100000003f08a0003900001c0e0b800197000000400800043d000000000bb8001900000000008b004b000000000c000039000000010c00403900001bce00b0009c000059db0000213d0000000100c00190000059db0000c13d0000004000b0043f000000000998043600000000000a004b00004db90000613d000000000ba90019000000000c090019000000003d03043c000000000cdc04360000000000bc004b00004db50000c13d0000001f00a001900000000003050433000000000003004b00004ded0000613d0000000003000019000000050a3002100000000e02a00029000000000e02043300000000fd0e04340000000500d0008c00005a0c0000213d000000400c00043d00001bb400c0009c000059db0000213d000000600be0003900000000020f0433000000400fe00039000000000f0f043300000000060b0433000000a00ee00039000000000e0e0433000000a001c00039000000400010043f00001ba701e00197000000800ec0003900000000001e04350000006001c0003900000000006104350000004001c000390000000000f1043500001ba7012001970000002002c0003900000000001204350000000000dc04350000000001040433000000000031004b000059d50000a13d0000000001a700190000000000c104350000000001040433000000000031004b000059d50000a13d0000000001080433000000000031004b000059d50000a13d00000000019a001900000000020b0433000000000021043500000001033000390000000001050433000000000013004b00004dbe0000413d000000400600043d00001c120060009c000059db0000213d0000000d02000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000830435000000a00360003900000011050000290000000000530435000000600360003900000000002304350000004002600039000000000042043500000020026000390000001403000029000000000032043500001ba701100197000000000016043500000080016000390000000000010435000000400100043d00001c3a0010009c000059db0000213d0000008002100039000000400020043f0000000002010436001400000002001d0000000000020435000000000200001900004f630000013d000000010230008a000000000042004b00005a310000813d000700000003001d000800000004001d000000000043004b00004e190000813d000000010010019000005a3a0000613d0000000d010000296e8b5a830000040f00000009020000290000000000120435000000000010043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000059f20000613d00000009060000290000000002060433000000000101043b000000000401041a0000ff000040019000004e330000613d000a00000002001d0000000e0000006b00004e3c0000613d00005a710000013d0000008807400270000000100140027000001c1f03100198000051000000613d000000000073004b000051000000413d000a00000002001d0000000e0000006b00005a740000c13d000000400100043d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a00210003900000000003204350000004002100039000000000032043500000020021000390000000000320435000000800210003900000000000204350000006002100039000000000002043500000000000104350000000d0100002900000040011000390000000005010433000000006405043400001bce0040009c000059db0000213d00000005034002100000003f0130003900001c0e02100197000000400100043d0000000007210019001400000001001d000000000017004b0000000002000039000000010200403900001bce0070009c000059db0000213d0000000100200190000059db0000c13d000000400070043f00000014010000290000000007410436000000000004004b00004e790000613d0000000004000019000000400800043d00001c3a0080009c000059db0000213d0000008002800039000000400020043f0000006002800039000000000002043500000040028000390000000000020435000000200280003900000000000204350000000000080435000000000247001900000000008204350000002004400039000000000034004b00004e680000413d000000000405043300001bce0040009c000059db0000213d00000005094002100000003f0290003900001c0e03200197000000400100043d0000000008310019001100000001001d000000000018004b0000000003000039000000010300403900001bce0080009c000059db0000213d0000000100300190000059db0000c13d000000400080043f0000001101000029000000000841043600000000030000310000000204300367000000000009004b00004e970000613d000000000a980019000000000b04034f000000000308001900000000bc0b043c0000000003c304360000000000a3004b00004e930000c13d0000001f009001900000000003050433000000000003004b00004ec90000613d0000000009000019000000050a9002100000000003a60019000000000e03043300000000fd0e04340000000500d0008c00005a0c0000213d000000400c00043d00001c3a00c0009c000059db0000213d000000600be0003900000000030f0433000000400ee00039000000000e0e0433000000000f0b04330000008002c00039000000400020043f0000006002c000390000000000f204350000004002c000390000000000e2043500001ba7023001970000002003c0003900000000002304350000000000dc043500000014010000290000000002010433000000000092004b000059d50000a13d0000000002a700190000000000c2043500000014010000290000000002010433000000000092004b000059d50000a13d00000011010000290000000002010433000000000092004b000059d50000a13d00000000028a001900000000030b0433000000000032043500000001099000390000000002050433000000000029004b00004e9c0000413d0000000d0100002900000060031000390000000006030433000000001a060434000e00000001001d00001bce00a0009c000059db0000213d0000000509a002100000003f0390003900001c0e03300197000000400500043d0000000008350019000000000058004b0000000003000039000000010300403900001bce0080009c000059db0000213d0000000100300190000059db0000c13d000000400080043f0000000008a5043600000000000a004b00004ef40000613d000000000a000019000000400b00043d00001bb400b0009c000059db0000213d000000a003b00039000000400030043f0000008003b0003900000000000304350000006003b0003900000000000304350000004003b0003900000000000304350000002003b00039000000000003043500000000000b04350000000003a800190000000000b30435000000200aa0003900000000009a004b00004ee10000413d000000000a06043300001bce00a0009c000059db0000213d000000050ba002100000003f03b0003900001c0e03300197000000400900043d000000000c39001900000000009c004b0000000003000039000000010300403900001bce00c0009c000059db0000213d0000000100300190000059db0000c13d0000004000c0043f000000000aa9043600000000000b004b00004f0d0000613d000000000cba001900000000030a0019000000004d04043c0000000003d304360000000000c3004b00004f090000c13d0000001f00b001900000000003060433000000000003004b00004f410000613d0000000004000019000000050b4002100000000e02b00029000000000f020433000000003e0f04340000000500e0008c00005a0c0000213d000000400d00043d00001bb400d0009c000059db0000213d000000600cf0003900000000020304330000004003f00039000000000303043300000000070c0433000000a00ff00039000000000f0f0433000000a001d00039000000400010043f00001ba701f00197000000800fd0003900000000001f04350000006001d0003900000000007104350000004001d00039000000000031043500001ba7012001970000002002d0003900000000001204350000000000ed04350000000001050433000000000041004b000059d50000a13d0000000001b800190000000000d104350000000001050433000000000041004b000059d50000a13d0000000001090433000000000041004b000059d50000a13d0000000001ab001900000000020c0433000000000021043500000001044000390000000001060433000000000014004b00004f120000413d000000400600043d00001c120060009c000059db0000213d0000000d02000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000930435000000a00360003900000011040000290000000000430435000000600360003900000000002304350000004002600039000000000052043500000020026000390000001403000029000000000032043500001ba701100197000000000016043500000080016000390000000000010435000000400100043d00001c3a0010009c000059db0000213d0000008002100039000000400020043f0000000a020000290000000003210436001400000003001d00000000000304350000000004000019000000000300001900000060091000390000000000690435000000400a10003900000000003a0435000000000004004b000050e50000613d0000000003020019000000120100002900000000010104330000000c0010006c000059d50000a13d0000000b020000290000000f012000290000000000310435000000400100043d00001ba80010009c000059db0000213d0000001402000029000000000202043300000000030a04330000004004100039000000400040043f000000200410003900000000003404350000000000210435000001600200043d00000000030204330000000c0030006c000059d50000a13d0000000b0220002900000020022000390000000000120435000001600100043d00000000010104330000000c0010006c000059d50000a13d000001a00200043d000000000302043300000040013000390000000001010433000001800010043f00000080033000390000000003030433000001c00030043f000000040030008c00005a0c0000213d000000010030008c00000000030000390000000103002039000000020000006b0000000004000039000000010400c03900000000003401a00000000205000029000000010500c039000200000005001d0000000003010433000000000003004b001400140000002d000e00000009001d000d0000000a001d000050430000613d000000000b0000190000000502b00210000000200c20003900000000011c00190000000002010433000000130000006b00004fb50000c13d0000000001020433000000050010008c00005a0c0000213d000000000001004b000000000100001900004fb40000c13d000001c00100043d000000040010008c0000000001000039000000010100c03900130001001001930000008001200039000000000e01043300000000040a043300000014030000290000000003030433000000000043004b00004fbf0000c13d000000600d20003900000000080d043300004fea0000013d00000000063e00a900000000000e004b00004fc50000613d0000000005e600d9000000000035004b000059e10000c13d000000000004004b000052820000613d00000000054600d900000000074500a9000000000046004b00004fce0000413d00000000065700d9000000000046004b000059e10000c13d000000000003004b000052820000613d00000000063700d90000000000e6004b000059f40000c13d000000600d20003900000000020d04330000000000e2004b0000000008020019000000000805601900004fe90000613d00000000063200a9000000000002004b00004fdf0000613d00000000072600d9000000000037004b000059e10000c13d00000000084600d900000000074800a9000000000046004b00004fe60000413d00000000068700d9000000000046004b000059e10000c13d00000000033700d9000000000023004b000059f40000c13d000000000e05001900000000008d04350000000000e104350000000000e8004b000050290000613d000001a00100043d0000000001010433000000c0021000390000000002020433000000a0011000390000000003010433000600000002001d000000000132004b000059e10000413d000700000003001d000800000001001d000900000008001d000a0000000e001d000b0000000d001d000c0000000c001d00110000000b001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000059fc0000613d000000000101043b0000000707000029000000000271004b0000000e090000290000000d0a000029000000110b0000290000000c0c0000290000000b0d0000290000000a0500002900000009040000290000000806000029000059e10000413d000000000326004b000059e10000413d00000000014300a9000000000004004b0000501d0000613d00000000044100d9000000000034004b000059e10000c13d00000000035200a9000000000005004b000050230000613d00000000045300d9000000000024004b000059e10000c13d000000000031001a000059e10000413d000000060070006b000052820000613d0000000001310019000000000e6100d90000000000ed043500000000010904330000002001100039000000000101043300000000020104330000000000b2004b000059d50000a13d00000000011c0019000000000101043300000060011000390000000000e104350000000001090433000000a001100039000000000101043300000000020104330000000000b2004b000059d50000a13d00000000011c001900000000020d04330000000000210435000000010bb00039000001800100043d000000000201043300000000002b004b00004fa40000413d000001a00200043d00000000010204330000006001100039000000000701043300000000b1070434000000000001004b000050eb0000613d000000000c000019000500000007001d00040000000b001d000000050dc002100000000001db001900000000040104330000008001400039000000000f01043300000000020a043300000014010000290000000001010433000000000021004b0000505c0000c13d000000600e40003900000000080e043300000000008e04350000000000f8004b0000508b0000c13d000050cb0000013d00000000051f00a900000000000f004b000050620000613d0000000003f500d9000000000013004b000059e10000c13d000000000002004b000052820000613d00000000032500d900000000062300a9000000000025004b0000506b0000413d00000000053600d9000000000025004b000059e10000c13d000000000001004b000052820000613d00000000051600d90000000000f5004b000059f40000c13d000000600e40003900000000040e04330000000000f4004b00000000080400190000000008036019000050870000613d00000000051400a9000000000004004b0000507c0000613d00000000064500d9000000000016004b000059e10000c13d00000000062500d9000000000806001900000000062600a9000000000025004b000050840000413d00000000058600d9000000000025004b000059e10000c13d00000000011600d9000000000041004b000059f40000c13d000000000f03001900000000008e04350000000000f8004b000050cb0000613d001100000008001d000001a00100043d0000000001010433000000c0021000390000000002020433000000a0011000390000000003010433000600000002001d000000000132004b000059e10000413d000700000003001d000800000001001d00090000000f001d000a0000000e001d000b0000000d001d000c0000000c001d00001c34010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000059fc0000613d000000000101043b0000000704000029000000000141004b0000000e090000290000000d0a0000290000000507000029000000040b0000290000000c0c0000290000000b0d0000290000000a0e00002900000009050000290000000806000029000059e10000413d000000000316004b000059e10000413d000000060040006b000059e10000613d00000011023000b9000000110000006b000050bd0000613d00000011042000fa000000000034004b000059e10000c13d00000000035100a9000000000005004b000050c30000613d00000000045300d9000000000014004b000059e10000c13d000000000032001a000059e10000413d000000010160008a0000000002320019000000000021001a000059e10000413d0000000001210019000000000f6100d90000000000fe043500000000010904330000004001100039000000000201043300000000010204330000000000c1004b000059d50000a13d0000002001d000390000000002210019000000000202043300000060022000390000000000f204350000000002090433000000c002200039000000000202043300000000030204330000000000c3004b000059d50000a13d000000000121001900000000020e04330000000000210435000000010cc00039000000000107043300000000001c004b0000504c0000413d000050eb0000013d000001a00100043d00000020011000390000000000010435000000000109043300000080011000390000000000010435000001e00200043d00000000030204330000002301000029000000000013004b000059d50000a13d00000005031002100000000002320019000000200220003900000000030904330000000000320435000001e00200043d0000000002020433000000000012004b000059d50000a13d002300010010003d000000010210003900000010010000290000000001010433000000000012004b00004b660000413d000052880000013d000000ff00400190000051050000613d00001c590040009c000051150000813d000051510000013d0000000a010000290000006001100039001100000003001d00000000030104330000000d01000029000000000101043300001ba701100197001400000007001d000e00000004001d6e8b5c900000040f0000000e0400002900000011030000290000001407000029000000090600002900001c590040009c000051510000413d0000000801000029000000010010008c0000511d0000c13d00000000050700190000000001350019000000000071004b000051240000a13d000051300000013d000000000017004b0000512a0000c13d000000000701001900000007050000290000000001350019000000000071004b000051300000213d000000000271019f00001c5a0020009c000051360000813d000700000005001d000800000007001d000051510000013d00000007057000b900000000071700a900000000031300a90000000001350019000000000071004b000051240000a13d000000000537004b000059e10000413d0000000001070019000000000271019f00001c5a0020009c000051270000413d000000000007004b000051400000613d00000000030700190000000004010019000000000203001900000000302400d9000000000003004b00000000040200190000513a0000c13d000051430000013d000000000001004b00000000020100190000527f0000613d0000000004050019000000000302001900000000203400d9000000000002004b0000000004030019000051440000c13d00000000013100d900001c1f0010009c000059e10000213d00000000013700d900001c1f0010009c000059e10000213d000800000001001d00070000003500e1000000400100043d00001c120010009c000059db0000213d0000000002060433000a00000002001d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a00210003900000000003204350000004002100039000000000032043500000020021000390000000000320435000000800210003900000000000204350000006002100039000000000002043500000000000104350000000d0100002900000040011000390000000005010433000000006405043400001bce0040009c000059db0000213d00000005034002100000003f0130003900001c0e02100197000000400100043d0000000007210019001400000001001d000000000017004b0000000002000039000000010200403900001bce0070009c000059db0000213d0000000100200190000059db0000c13d000000400070043f00000014010000290000000007410436000000000004004b000051900000613d0000000004000019000000400800043d00001c3a0080009c000059db0000213d0000008002800039000000400020043f0000006002800039000000000002043500000040028000390000000000020435000000200280003900000000000204350000000000080435000000000247001900000000008204350000002004400039000000000034004b0000517f0000413d000000000405043300001bce0040009c000059db0000213d00000005094002100000003f0290003900001c0e02200197000000400100043d0000000008210019001100000001001d000000000018004b0000000002000039000000010200403900001bce0080009c000059db0000213d0000000100200190000059db0000c13d000000400080043f0000001101000029000000000841043600000000020000310000000204200367000000000009004b000051ae0000613d000000000a980019000000000b04034f000000000208001900000000bc0b043c0000000002c204360000000000a2004b000051aa0000c13d0000001f009001900000000002050433000000000002004b000051e00000613d0000000009000019000000050a9002100000000002a60019000000000e020433000000002d0e04340000000500d0008c00005a0c0000213d000000400c00043d00001c3a00c0009c000059db0000213d000000600be000390000000002020433000000400ee00039000000000e0e0433000000000f0b04330000008003c00039000000400030043f0000006003c000390000000000f304350000004003c000390000000000e3043500001ba7022001970000002003c0003900000000002304350000000000dc043500000014010000290000000002010433000000000092004b000059d50000a13d0000000002a700190000000000c2043500000014010000290000000002010433000000000092004b000059d50000a13d00000011010000290000000002010433000000000092004b000059d50000a13d00000000028a001900000000030b0433000000000032043500000001099000390000000002050433000000000029004b000051b30000413d0000000d0100002900000060021000390000000006020433000000001a060434000e00000001001d00001bce00a0009c000059db0000213d0000000509a002100000003f0290003900001c0e02200197000000400500043d0000000008250019000000000058004b0000000002000039000000010200403900001bce0080009c000059db0000213d0000000100200190000059db0000c13d000000400080043f0000000008a5043600000000000a004b0000520b0000613d000000000a000019000000400b00043d00001bb400b0009c000059db0000213d000000a002b00039000000400020043f0000008002b0003900000000000204350000006002b0003900000000000204350000004002b0003900000000000204350000002002b00039000000000002043500000000000b04350000000002a800190000000000b20435000000200aa0003900000000009a004b000051f80000413d000000000a06043300001bce00a0009c000059db0000213d000000050ba002100000003f02b0003900001c0e02200197000000400900043d000000000c29001900000000009c004b0000000002000039000000010200403900001bce00c0009c000059db0000213d0000000100200190000059db0000c13d0000004000c0043f000000000aa9043600000000000b004b000052240000613d000000000cba001900000000020a0019000000004d04043c0000000002d204360000000000c2004b000052200000c13d0000001f00b001900000000002060433000000000002004b000052580000613d0000000004000019000000050b4002100000000e02b00029000000000f020433000000002e0f04340000000500e0008c00005a0c0000213d000000400d00043d00001bb400d0009c000059db0000213d000000600cf0003900000000020204330000004003f00039000000000303043300000000070c0433000000a00ff00039000000000f0f0433000000a001d00039000000400010043f00001ba701f00197000000800fd0003900000000001f04350000006001d0003900000000007104350000004001d00039000000000031043500001ba7012001970000002002d0003900000000001204350000000000ed04350000000001050433000000000041004b000059d50000a13d0000000001b800190000000000d104350000000001050433000000000041004b000059d50000a13d0000000001090433000000000041004b000059d50000a13d0000000001ab001900000000020c0433000000000021043500000001044000390000000001060433000000000014004b000052290000413d000000400600043d00001c120060009c000059db0000213d000000070100002900001c1f041001970000000d02000029000000000102043300000120022000390000000002020433000000e003600039000000400030043f000000c0036000390000000000930435000000a0036000390000001107000029000000000073043500000080036000390000000000430435000000600360003900000000002304350000004002600039000000000052043500000020026000390000001403000029000000000032043500001ba7011001970000000000160435000000400100043d00001c3a0010009c000059db0000213d0000008002100039000000400020043f0000000a020000290000000003210436001400000003001d0000000000430435000000080300002900001c1f0330019700004f650000013d000000000005004b0000000003050019000051490000c13d00001c1401000041000000000010043f0000001201000039000000040010043f00001c150100004100006e8d00010430000000130000006b000052950000613d0000000201000367000000000101043b00001c400110019700001c770010009c000052950000613d00001c780010009c000052950000613d000000400100043d00001c6402000041000059f60000013d000200000000001d00000001010000290000000021010434000d00000002001d000c00000001001d000000000001004b000053450000613d0000000002000019000052a40000013d0000000001010433000000000001004b000053420000c13d0000000e0200002900000001022000390000000c0020006c000053450000813d00000001010000290000000001010433000000000021004b000059d50000a13d000e00000002001d00000005012002100000000d0110002900000000010104330000000023010434000001e00400043d0000000005040433000000000053004b00005a090000813d00000005033002100000000003340019000000200330003900000000030304330000008004300039000000000404043300001c1f00400198000052a00000613d0000000004020433000000010040008c00005a0c0000213d00000040021000390000000002020433000000000004004b000052c60000613d000000400330003900000000030304330000000004030433000000000042004b000052cb0000413d00005a340000013d000000200330003900000000030304330000000004030433000000000042004b00005a3d0000813d00000005022002100000000002320019000000200220003900000000020204330000000003020433000000050030008c00005a0c0000213d00000040042000390000000005040433000000040030008c00000003030000390000000203006039000000000032043500000060021000390000000003020433000000000034043500005a120000413d00000080011000390000000001010433000000000005004b0000529d0000613d001300000001001d000b00000005001d0000000003020433000000400100043d00000020020000390000000002210436000000000032043500001ba80010009c000059db0000213d0000004003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000059f20000613d000000000101043b00000013020000290000000032020434001100000003001d000000000002004b000053400000613d0000000003000019001400000003001d00000005023002100000001105200029000000400200043d000000400420003900000020032000390000000005050433000000000051004b0000531f0000a13d000000000053043500000000001404350000004001000039000000000012043500001bd10020009c000059db0000213d0000006001200039000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f0000000002000414000053300000013d000000000013043500000000005404350000004001000039000000000012043500001bd10020009c000059db0000213d0000006001200039000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000059f20000613d000000000101043b0000001403000029000000010330003900000013020000290000000002020433000000000023004b000053040000413d0000000b0010006c000052a00000613d000000400100043d00001c6002000041000059f60000013d000001e00100043d0000000032010434000000000002004b0000539e0000613d00000000010000190000534e0000013d0000000101100039000000000021004b0000539e0000813d0000000504100210000000000543001900000000050504330000008006500039000000000606043300001c1f006001980000534b0000613d000000200650003900000000060604330000000076060434000000000006004b0000000304400029000053780000613d0000000008000019000053600000013d0000000108800039000000000068004b000053780000813d000000050980021000000000099700190000000009090433000000000a0904330000000500a0008c00005a0c0000213d0000000300a0008c0000535d0000a13d000000100a000029000000000a0a043300000000001a004b000059d50000a13d000000000a040433000000000a0a0433000000800aa00039000000000a0a04330000000400a0008c00005a0c0000213d000059fd0000c13d00000040099000390000000009090433000000000009004b0000535d0000613d000059fd0000013d000000400550003900000000050504330000000065050434000000000005004b0000534b0000613d0000000007000019000053820000013d0000000107700039000000000057004b0000534b0000813d0000000508700210000000000886001900000000080804330000000009080433000000050090008c00005a0c0000213d000000040090008c0000537f0000413d00000010090000290000000009090433000000000019004b000059d50000a13d0000000009040433000000000909043300000080099000390000000009090433000000040090008c00005a0c0000213d000053990000c13d00000040088000390000000008080433000000000008004b0000537f0000613d000000400200043d0000002403200039000000000073043500001c620300004100005a010000013d002100000000003d002200000000003d00000010010000290000000001010433000000000001004b00005a7a0000613d0000000005000019000053b70000013d00000011010000290000000000010435000001e00100043d0000000002010433000000000072004b000059d50000a13d0000000e011000290000000001010433000000800110003900000000000104350000002101000029002100010010003d000000010510003900000010010000290000000001010433000000000015004b000059d00000813d00000012010000290000000001010433000000000051004b000059d50000a13d00000005025002100000000f032000290000000001030433000000000001004b000053b00000613d002000200000003d000001400100043d00000020041000390000000001040433000000000001004b000054e00000613d000c00000004001d001100000003001d0000000301200029000a00000001001d0000000001010433000000000f010433001f0000000f001d000001e00300043d0000000004030433000000000054004b000059d50000a13d001300000005001d00001bce0050009c000059db0000213d0000003f0420003900001c0e04400197000000400600043d0000000004460019000000000064004b0000000005000039000000010500403900001bce0040009c000059db0000213d0000000100500190000059db0000c13d000e00200020003d0000000e033000290000000003030433000000400040043f000000130a0000290000000004a60436000000000002004b000053ef0000613d0000000005240019000000000700003100000002077003670000000008040019000000007907043c0000000008980436000000000058004b000053eb0000c13d0000001f0020019000000000000a004b000054020000613d000000000200001900000012050000290000000005050433000000000025004b000059d50000a13d0000000005060433000000000025004b000059d50000a13d000000050520021000000000074500190000000f055000290000000005050433000000000057043500000001022000390000000000a2004b000053f30000413d000000120200002900000000020204330000000000a2004b000059d50000a13d0000000002000415001400000002001d000000000401043300000080024000390000000002020433000000040020008c00005a0c0000213d000001400500043d00000000080504330000001105000029000000000d05043300000000050004150000001e0550008a0000000505500210000000020020008c0000541b0000613d00000000050004150000001d0550008a0000000505500210000000030020008c000055320000c13d0000002002400039000000000202043300001ba7022001970000000007000411000000000027004b0000000505500270000000000500003f000000010500c03f000055320000613d000800000008001d000000400800043d00001c3d0080009c000059db0000213d0000008001100039000000400530003900000020033000390000000009030433000000000a0504330000000007010433000000a0014000390000000005010433000000c001400039000000000b010433000000000c040433000000e00140003900000000030104330000014001800039000000400010043f0000012001800039000000000031043500000100038000390000000000b30435000000e0048000390000000000540435000000c0058000390000000000650435000000a006800039000000000076043500000080078000390000000000a70435000000600a80003900000000009a043500001ba709c00197000000400b80003900000000009b04350000002009800039000000000c0004110000000000c9043500090000000d001d0000000000d80435000000400e00043d00001c3e0c0000410000000000ce0435000000040ce00039000000200d0000390000000000dc04350000000008080433000000240ce0003900000000008c0435000000000809043300001ba7088001970000004409e00039000000000089043500000000080b043300001ba7088001970000006409e00039000000000089043500000000090a04330000008408e00039000001400a0000390000000000a804350000016408e00039000000000a0904330000000000a80435000b0000000e001d0000018408e0003900000000000a004b0000547f0000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c00005a0c0000213d000000000ee80436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e8000390000000000de0435000000600cc00039000000000c0c0433000000600d8000390000000000cd04350000008008800039000000010bb000390000000000ab004b0000546a0000413d0000000b0b0000290000000009b80049000000240a90008a0000000009070433000000a407b000390000000000a70435000000000a0904330000000007a8043600000000000a004b000054a40000613d00000000080000190000002009900039000000000b09043300000000cd0b04340000000500d0008c00005a0c0000213d000000000dd70436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d7000390000000000cd0435000000600cb00039000000000c0c0433000000600d7000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c7000390000000000bc0435000000a00770003900000001088000390000000000a8004b0000548a0000413d0000000b0c0000290000000008c70049000000240880008a0000000006060433000000c409c00039000000000089043500000000980604340000000006870436000000000008004b000054b60000613d0000000007000019000000000a670019000000000b790019000000000b0b04330000000000ba04350000002007700039000000000087004b000054af0000413d000000000786001900000000000704350000001f0780003900001c2b0770019700000000087600190000000006c80049000000240760008a0000000006050433000000e405c00039000000000075043500000000070604330000000005780436000000000007004b000000090a000029000054cc0000613d00000000080000190000002006600039000000000906043300000000059504360000000108800039000000000078004b000054c60000413d00000000040404330000010406c00039000000000046043500000000030304330000012404c0003900000000003404350000014403c00039000000000101043300000000001304350000000001000414000000040020008c000054e80000c13d00000000010004150000001c0110008a00000005011002100000000103000031000000200030008c000000200400003900000000040340190000551d0000013d0000000000030435000001e00100043d0000000003010433000000000053004b000059d50000a13d00000000011200190000002001100039000053ad0000013d000d0000000f001d0000000003c5004900001ba40030009c00001ba403008041000000600330021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000343019f00001ba40010009c00001ba401008041000000c001100210000000000131019f6e8b6e810000040f0000000b0c0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056c0019000055070000613d000000000701034f00000000080c0019000000007907043c0000000008980436000000000058004b000055030000c13d0000001f074001900000000d0f000029000000090a000029000055160000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f000300000001035500000000010004150000001b0110008a00000005011002100000000100200190000058cb0000613d0000001f02400039000000600420018f0000000002c40019000000000042004b0000000004000039000000010400403900001bce0020009c000059db0000213d0000000100400190000059db0000c13d000000400020043f000000200030008c000059f20000413d00000000030c043300001c3f00300198000059f20000c13d0000000501100270000000000103001f00001c400130019700001c3e0010009c00005a680000c13d0000000001000415000000140110006900000000010000020000008001f000390000000002010433000000040020008c00005a0c0000213d0000561b0000c13d000001e00100043d00000000020104330000001303000029000000000032004b000059d50000a13d00000010020000290000000002020433000000000032004b000059d50000a13d0000000002000415000700000002001d0000014002f0003900000000020204330000006003f0003900000000030304330000000003030433000000000023004b00005a370000c13d0000000e011000290000000001010433000b00000001001d0000004001100039000900000001001d0000000003010433000000004803043400001bce0080009c000059db0000213d00000005078002100000003f0170003900001c0e02100197000000400100043d0000000005210019000000000015004b0000000002000039000000010200403900001bce0050009c000059db0000213d0000000100200190000059db0000c13d000001400200043d0000000002020433000400000002001d0000000a020000290000000002020433000000800220003900000000020204330000000b060000290000002006600039001400000006001d0000000006060433000000400050043f0000000005810436000000000008004b000055820000613d0000000008000019000000400900043d00001c3a0090009c000059db0000213d000000800a9000390000004000a0043f000000600a90003900000000000a0435000000400a90003900000000000a0435000000200a90003900000000000a04350000000000090435000000000a85001900000000009a04350000002008800039000000000078004b000055710000413d0000000007030433000000000007004b000055aa0000613d000000000700001900000005087002100000000009840019000000000b09043300000000ca0b04340000000500a0008c00005a0c0000213d000000400900043d00001c3a0090009c000059db0000213d000000000c0c0433000000400db00039000000000d0d0433000000600bb00039000000000b0b0433000000800e9000390000004000e0043f000000600e9000390000000000be0435000000400b9000390000000000db043500001ba70bc00197000000200c9000390000000000bc04350000000000a90435000000000a01043300000000007a004b000059d50000a13d000000000885001900000000009804350000000008010433000000000078004b000059d50000a13d00000001077000390000000008030433000000000087004b000055860000413d00000000050f0433000000400400043d000000440340003900000080070000390000000000730435000000200340003900001c660700004100000000007304350000002407400039000000000800041100000000008704350000000008060433000000a4074000390000000000870435000000c407400039000000000008004b000055d10000613d00000000090000190000002006600039000000000a06043300000000bc0a04340000000500c0008c00005a0c0000213d000000000cc70436000000000b0b043300001ba70bb001970000000000bc0435000000400ba00039000000000b0b0433000000400c7000390000000000bc0435000000600aa00039000000000a0a0433000000600b7000390000000000ab043500000080077000390000000109900039000000000089004b000055bc0000413d0000000006470049000000240660008a0000006408400039000000000068043500000000080104330000000006870436000000000008004b000055ef0000613d00000000070000190000002001100039000000000901043300000000ab0904340000000500b0008c00005a0c0000213d000000000bb60436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b6000390000000000ab043500000060099000390000000009090433000000600a60003900000000009a043500000080066000390000000107700039000000000087004b000055da0000413d0000000001460049000000240110008a0000008407400039000000000017043500000000720204340000000001260436000000000002004b000055ff0000613d000000000600001900000000081600190000000009670019000000000909043300000000009804350000002006600039000000000026004b000055f80000413d000000000621001900000000000604350000001f0220003900001c2b0220019700000000024200490000000001210019000000200210008a00000000002404350000001f0110003900001c2b021001970000000001420019000000000021004b0000000002000039000000010200403900001bce0010009c000059db0000213d0000000100200190000059db0000c13d00001ba702500197000000400010043f00000000040404330000000001000414000000040020008c000d0000000f001d000056380000c13d000000010100003100000001090000390000564a0000013d000000120100002900000000010104330000001305000029000000000051004b000059d50000a13d000001600300043d0000000004030433000000000054004b000059d50000a13d000000110400002900000000060404330000000e03300029000000000303043300000000380304340000000007030433000001400300043d0000000003030433000000000003004b0000000109000039000058eb0000c13d0000002003f000390000000003030433000000020020008c000058dc0000c13d0000000004000415000000160440008a0000000504400210001600010000003d000058e40000013d00001ba40030009c00001ba403008041000000400330021000001ba40040009c00001ba4040080410000006004400210000000000334019f00001ba40010009c00001ba401008041000000c001100210000000000113019f6e8b6e810000040f0000000d0f000029000000010920018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b0000008008000039000a00600000003d000056780000613d00001bce0010009c000059db0000213d0000001f0210003900001c2b022001970000003f0220003900001c2b02200197000000400300043d0000000002230019000a00000003001d000000000032004b0000000003000039000000010300403900001bce0020009c000059db0000213d0000000100300190000059db0000c13d000000400020043f0000000a02000029000000000812043600001c2b03100198000000000238001900000003040003670000566b0000613d000000000504034f0000000006080019000000005705043c0000000006760436000000000026004b000056670000c13d0000001f01100190000056780000613d000000000334034f0000000301100210000000000402043300000000041401cf000000000414022f000000000303043b0000010001100089000000000313022f00000000011301cf000000000141019f0000000000120435000800000009001d000600000008001d00000000010f043300001ba701100197000000000010043f0000000401000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000d040000290000000100200190000059f20000613d000000000201043b000000000102041a000000010310003a0000000805000029000059e10000613d000000000032041b000000000204043300000060022002100005000000120143000000400100043d000000000005004b000056db0000613d00001c670010009c000059db0000213d000000240210003900001c68030000410000000000320435000000440210003900000000030004140000006004000039000000000042043500001c69020000410000000000210435000000640210003900000000000204350000000402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001ba40030009c00001ba403008041000000c002300210000000000121019f00001c6a011001c700008006020000396e8b6e810000040f000000010020019000005a400000613d000000000101043b000000000001004b000000060700002900005a460000613d000000400d00043d00001c6b02000041000000000f2d04360000000402d00039000000200300003900000000003204350000000a0200002900000000030204330000002402d0003900000000003204350000004404d00039000000000003004b0000000d0e000029000056ca0000613d000000000200001900000000054200190000000006270019000000000606043300000000006504350000002002200039000000000032004b000056c30000413d00000000023400190000000000020435000000000500041400001ba702100197000000040020008c000056f80000c13d00000000060004150000001a0660008a00000005066002100000000005000415000000190550008a000000050550021000000003010003670000000102000031001900000000003d001a00000000003d0000571d0000013d00001c120010009c000059db0000213d000000e002100039000000400020043f000000c00210003900000060030000390000000000320435000000a0021000390000000000320435000000400210003900000000003204350000002002100039000000000032043500000080021000390000000000020435000000600210003900000000000204350000000000010435000000040000006b000059e70000c13d000000000100041500000007011000690000000001000002000000120100002900000000010104330000001307000029000000000071004b000053a60000213d000059d50000013d00080000000f001d0000001f0130003900001c2b011001970000000001d10049000000000141001900001ba40010009c00001ba401008041000000600110021000001ba400d0009c000a0000000d001d00001ba40300004100000000030d40190000004003300210000000000131019f00001ba40050009c00001ba405008041000000c003500210000000000131019f6e8b6e860000040f0000000006000415000000180660008a00000005066002100000000005000415000000170550008a00000005055002100000000003010019000000600330027000011ba40030019d0003000000010355001800000000003d001700000000003d0000000100200190000059e70000613d00001ba4023001970000000d0e0000290000000a0d000029000000080f00002900001c2b0420019800000000034d0019000057260000613d000000000701034f00000000080d0019000000007907043c0000000008980436000000000038004b000057220000c13d0000001f07200190000057330000613d000000000141034f0000000304700210000000000703043300000000074701cf000000000747022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000171019f00000000001304350000001f0120003900001c2b011001970000000003d10019000000000013004b0000000001000039000000010100403900001bce0030009c000059db0000213d0000000100100190000059db0000c13d000000400030043f00001c0f0020009c000059f20000213d000000400020008c000059f20000413d00000000010d043300001bce0010009c000059f20000213d0000000004d100190000000007d2001900001c0d017001970000001f0240003900001c0d08200197000000000918013f000000000018004b000000000800001900001c0d08004041000000000072004b000000000200001900001c0d0200804100001c0d0090009c000000000802c019000000000008004b000059f20000c13d000000002804043400001bce0080009c000059db0000213d00000005048002100000003f0440003900001c0e04400197000000000434001900001bce0040009c000059db0000213d000000400040043f000000000483043600000007088002100000000008280019000000000078004b000059f20000213d000000000082004b000057850000813d0000000009040019000000000a27004900001c0f00a0009c000059f20000213d0000008000a0008c000059f20000413d000000400a00043d00001c3a00a0009c000059db0000213d000000800ba000390000004000b0043f00000000bc0204340000000500c0008c000059f20000213d000000000cca0436000000000b0b043300001ba700b0009c000059f20000213d0000000000bc0435000000400b200039000000000b0b0433000000400ca000390000000000bc0435000000600b200039000000000b0b0433000000600ca000390000000000bc04350000000009a904360000008002200039000000000082004b000057670000413d00000000020f043300001bce0020009c000059f20000213d0000000002d200190000001f08200039000000000078004b000000000900001900001c0d0900804100001c0d08800197000000000a18013f000000000018004b000000000100001900001c0d0100404100001c0d00a0009c000000000109c019000000000001004b000059f20000c13d000000008902043400001bce0090009c000059db0000213d00000005019002100000003f0110003900001c0e02100197000000400100043d0000000002210019000000000012004b000000000a000039000000010a00403900001bce0020009c000059db0000213d0000000100a00190000059db0000c13d000000400020043f0000000002910436000000a0099000c90000000009890019000000000079004b000059f20000213d000000000098004b000057d20000813d000000000a020019000000000b87004900001c0f00b0009c000059f20000213d000000a000b0008c000059f20000413d000000400b00043d00001bb400b0009c000059db0000213d000000a00cb000390000004000c0043f00000000cd0804340000000500d0008c000059f20000213d000000000ddb0436000000000c0c043300001ba700c0009c000059f20000213d0000000000cd0435000000400c800039000000000c0c0433000000400db000390000000000cd0435000000600cb00039000000600d800039000000000d0d04330000000000dc0435000000800c800039000000000c0c043300001ba700c0009c000059f20000213d000000800db000390000000000cd0435000000000aba0436000000a008800039000000000098004b000057ae0000413d0000000506600270000000000603001f0000000505500270000000000501001f0000004005e00039000000000505043300000000050504330000000006030433000000000065004b000059e70000213d000000000005004b000058120000613d0000000006000019000000140700002900000000070704330000000008070433000000000068004b000059d50000a13d0000000008030433000000000068004b000059d50000a13d000000050960021000000000077900190000002007700039000000000b070433000000008a0b04340000000500a0008c00005a0c0000213d0000000007490019000000000c0704330000000300a0008c0000004007b000390000004009c00039000057fb0000a13d000000000d07043300000000000d004b000057fb0000c13d000000020aa0008a0000000000ab0435000000000d0904330000000000d70435000000600dc00039000000000d0d0433000000600bb00039000000000b0b04330000000000db004b000059e70000213d00000000bc0c04340000000500c0008c00005a0c0000213d0000000000ca004b000059e70000c13d0000000008080433000000000a0b043300000000088a013f00001ba700800198000059e70000c13d00000000080904330000000007070433000000000087004b000059e70000c13d0000000106600039000000000056004b000057df0000413d00000014050000290000000000350435000000000503043300001bce0050009c000059db0000213d00000005075002100000003f0670003900001c0e08600197000000400600043d0000000008860019000000000068004b0000000009000039000000010900403900001bce0080009c000059db0000213d0000000100900190000059db0000c13d000000400080043f000000000856043600000000050000310000000205500367000000000007004b0000582f0000613d0000000009780019000000000a05034f00000000ab0a043c0000000008b80436000000000098004b0000582b0000c13d0000001f007001900000000b07000029000000a00770003900000000006704350000000006030433000000000006004b000058470000613d000000000600001900000000080704330000000009080433000000000069004b000059d50000a13d0000000509600210000000000889001900000000094900190000000009090433000000600990003900000000090904330000002008800039000000000098043500000001066000390000000008030433000000000086004b000058370000413d0000000003010433000000090400002900000000040404330000000067040434000000000073004b000059e70000213d000000000003004b0000588b0000613d0000000007000019000058540000013d0000000107700039000000000037004b0000588b0000813d0000000008010433000000000078004b000059d50000a13d0000000008040433000000000078004b000059d50000a13d00000005097002100000000008960019000000000808043300000000bd0804340000000500d0008c00005a0c0000213d000000000929001900000000090904330000000300d0008c000000400a800039000000400c9000390000586d0000a13d000000000e0a043300000000000e004b0000586d0000c13d000000020dd0008a0000000000d80435000000000e0c04330000000000ea0435000000600e800039000000000e0e0433000000600f900039000000000f0f04330000000000ef004b000059e70000213d00000000ef0904340000000500f0008c00005a0c0000213d0000000000fd004b000059e70000c13d000000000b0b0433000000000d0e0433000000000bbd013f00001ba700b00198000059e70000c13d000000000b0c0433000000000a0a04330000000000ba004b000059e70000c13d0000008008800039000000000808043300001ba708800198000058510000613d0000008009900039000000000909043300001ba709900197000000000098004b000058510000613d000059e70000013d00000009030000290000000000130435000000000601043300001bce0060009c000059db0000213d00000005046002100000003f0340003900001c0e07300197000000400300043d0000000007730019000000000037004b0000000008000039000000010800403900001bce0070009c000059db0000213d0000000100800190000059db0000c13d000000400070043f0000000006630436000000000004004b000058a50000613d0000000007460019000000005805043c0000000006860436000000000076004b000058a10000c13d0000001f004001900000000b04000029000000c00440003900000000003404350000000003010433000000000003004b0000001307000029000058be0000613d000000000300001900000000050404330000000006050433000000000036004b000059d50000a13d0000000506300210000000000556001900000000062600190000000006060433000000600660003900000000060604330000002005500039000000000065043500000001033000390000000005010433000000000053004b000058ae0000413d00000000010004150000000701100069000000000100000200000012010000290000000001010433000000000071004b000059d50000a13d000000110100002900000005020000290000000000210435000000000002004b000059510000c13d000053a80000013d000000080000006b00005a7d0000c13d000000000100041500000014011000690000000001000002000000120100002900000000010104330000001303000029000000000031004b000059d50000a13d00000011010000290000000000010435000001e00100043d0000000002010433000000000032004b000053ac0000213d000059d50000013d0000000004000415000000150440008a0000000504400210000000030020008c001500000000003d001500010000603d0000000009000019000058eb0000c13d00001ba7023001970000000003000411000000000032004b0000000009000039000000010900c0390000000502400270000000000209001f000000000008004b000059290000613d000b00000009001d000d00000008001d001400000007001d000a00000006001d000000000060043f0000000301000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f0000000100200190000059f20000613d000000000101043b000000000201041a000000880520027200000014060000290000590c0000613d000000100220027000001c1f02200197000000000065004b0000000d030000290000590e0000c13d0000000004020019000000000203001900000000030600190000000b070000290000591f0000013d0000000d050000290000594b0000013d00000000046200a9000000000002004b0000000b07000029000059150000613d00000000022400d9000000000062004b000059e10000c13d00000000023500a900000000033200d9000000000053004b000059e10000c13d000000000006004b000059320000613d00000000036500a900000000066300d9000000000056004b000059e10000c13d000000000042001a000059e10000413d0000000002420019000000000032004b0000001305000029000059360000a13d000000000007004b00005a740000c13d00000012010000290000000001010433000000000051004b000059d50000a13d00000011010000290000000000010435000001e00100043d0000000002010433000000000052004b000053ac0000213d000059d50000013d0000000003000019000000000032004b0000001305000029000059250000213d000000000423019f00001c5a0040009c0000593c0000813d000000000502001900000000060300190000594b0000013d000000000003004b000052820000613d00000000050300190000000006020019000000000405001900000000504600d9000000000005004b0000000006040019000059400000c13d00000000054200d900001c1f0050009c000059e10000213d00000000064300d900001c1f0060009c000059e10000213d0000008802600210000000100350021000001c4203300197000000000223019f00000001022001bf000000000021041b0000000c010000290000000001010433000000000001004b000059e10000613d000000010110008a0000000c020000290000000000120435000001e00100043d00000000030104330000002102000029000000000023004b000059d50000a13d00000012030000290000000003030433000000000023004b000059d50000a13d0000000502200210000000000121001900000020011000390000000001010433000000400310003900000000030304330000000f0620002900000020011000290000001f0700002900000020027000290000000002020433000000000501043300000000060604330000000004070433000001400100043d00000040011000390000000007010433000000400100043d00000040081000390000008009000039000000000098043500001ba707700197000000200810003900000000007804350000000000610435000000000705043300000080061000390000000000760435000000a006100039000000000007004b000059960000613d00000000080000190000002005500039000000000905043300000000ab0904340000000500b0008c00005a0c0000213d000000000bb60436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b6000390000000000ab043500000060099000390000000009090433000000600a60003900000000009a043500000080066000390000000108800039000000000078004b000059810000413d00000000051600490000006007100039000000000057043500000000050304330000000007560436000000000005004b000059b80000613d000000000600001900000020033000390000000008030433000000009a0804340000000500a0008c00005a0c0000213d000000000aa70436000000000909043300001ba70990019700000000009a043500000040098000390000000009090433000000400a70003900000000009a043500000060098000390000000009090433000000600a70003900000000009a04350000008008800039000000000808043300001ba70880019700000080097000390000000000890435000000a0077000390000000106600039000000000056004b0000599e0000413d00001ba70540019700001ba706200197000000000217004900001ba40020009c00001ba402008041000000600220021000001ba40010009c00001ba4010080410000004001100210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000121019f00001bcd011001c70000800d02000039000000030300003900001c3c040000416e8b6e810000040f0000000100200190000059f20000613d002200010000003d000053b00000013d000000220000002a00005a7a0000613d00000012010000290000000202000029000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c6e02000041000000000021043500000004021000390000000503000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d00010430000000000100001900006e8d00010430000000400100043d00001c6502000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000000001042f000000400200043d0000002403200039000000000083043500001c630300004100000000003204350000000403200039000000000013043500001ba40020009c00001ba402008041000000400120021000001c36011001c700006e8d000104300000000002020433000000010020008c00005a150000a13d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400100043d00001c6102000041000059f60000013d000000400300043d001400000003001d00001c5d01000041000000000013043500000004013000396e8b5fad0000040f0000001402000029000000000121004900001ba40010009c00001ba401008041000000600110021000001ba40020009c00001ba4020080410000004002200210000000000121019f00006e8d0001043000000024021000390000001104000029000000000042043500001c350200004100000000002104350000000402100039000000000032043500001ba40010009c00001ba401008041000000400110021000001c36011001c700006e8d00010430000000400100043d00001c5c02000041000059f60000013d000000400100043d00001c5e02000041000059f60000013d000000400100043d00001c2102000041000059f60000013d000000400100043d00001c5b02000041000059f60000013d000000400100043d00001c5f02000041000059f60000013d00030000000103550000000002010019000000600220027000011ba40020019d00001ba40220019700005a480000013d0000000301000367000000010200003100001c2b052001980000001f0620018f000000400300043d000000000453001900005a530000613d000000000701034f0000000008030019000000007907043c0000000008980436000000000048004b00005a4f0000c13d000000000006004b00005a600000613d000000000151034f0000000305600210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500001ba40020009c00001ba402008041000000600120021000001ba40030009c00001ba4030080410000004002300210000000000112019f00006e8d0001043000001c4101000041000000000012043500000004012000390000000000a1043500001ba40020009c00001ba402008041000000400120021000001c15011001c700006e8d00010430000000400100043d00001c1e0200004100005a760000013d000000400100043d00001c2002000041000000000021043500000004021000390000000a03000029000059ec0000013d000000400100043d00001c7902000041000059f60000013d000000400100043d00001c4102000041000000000021043500000004021000390000000000a20435000059ed0000013d000d0000000000020000014002100039000a00000002001d00000000030204330000006002100039000400000002001d00000000020204330000000002020433000000000032004b00005c880000413d000300000001001d0000000021010434000200000002001d00001ba701100197000000000010043f0000000201000039000000200010043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000000101043b00000003020000290000004002200039000900000002001d0000000002020433000000000302043300001c310030009c00005c790000813d00000005023002100000003f0420003900001c0e04400197000000400700043d0000000004470019000000000074004b0000000005000039000000010500403900001bce0040009c00005c790000213d000000010050019000005c790000c13d000000000101041a000100000001001d000000400040043f0000000001370436000700000001001d0000001f0320018f00000000010000310000000201100367000000000002004b00005ac20000613d00000007050000290000000002250019000000000401034f000000004604043c0000000005650436000000000025004b00005abe0000c13d000000000003004b0000000a02000029000000000302043300001bce0030009c00005c790000213d00000005023002100000003f0420003900001c0e04400197000000400600043d0000000004460019000000000064004b0000000005000039000000010500403900001bce0040009c00005c790000213d000000010050019000005c790000c13d000000400040043f0000000003360436000600000003001d0000001f0320018f000000000002004b00005adf0000613d00000006040000290000000002240019000000001501043c0000000004540436000000000024004b00005adb0000c13d000d00000007001d000800000006001d000000000003004b00001c100100004100000000001004430000000001000412000000040010044300000060010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005c870000613d000000000101043b000500000001001d000000090100002900000000010104330000000002010433000000000002004b00005b3e0000613d0000000004000019000b0005004002180000000b01100029000000200110003900000000010104330000000032010434000000060020008c00005c810000813d000c00000004001d0000000003030433000000400410003900000000040404330000006005100039000000000505043300000080011000390000000006010433000000400100043d000000c0071000390000000000670435000000a0061000390000000000560435000000800510003900000000004504350000004004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000005030000290000000000320435000000c003000039000000000031043500001c120010009c00005c790000213d000000e003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d0000000d0200002900000000020204330000000c04000029000000000042004b00005c730000a13d0000000b030000290000000702300029000000000101043b00000000001204350000000104400039000000090100002900000000010104330000000002010433000000000024004b00005af90000413d00001c100100004100000000001004430000000001000412000000040010044300000080010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005c870000613d000000000101043b000900000001001d0000000a010000290000000001010433000000000001004b0000000d0700002900005ba40000613d0000000004000019000000040100002900000000010104330000000002010433000000000042004b00005c730000a13d000b0005004002180000000b01100029000000200110003900000000010104330000000032010434000000050020008c00005c810000213d000c00000004001d0000000003030433000000a0041000390000000004040433000000400510003900000000050504330000006006100039000000000606043300000080011000390000000007010433000000400100043d000000c0081000390000000000780435000000a0071000390000000000670435000000800610003900000000005604350000004005100039000000000025043500001ba702400197000000e004100039000000000024043500001ba70230019700000060031000390000000000230435000000200210003900000009030000290000000000320435000000e003000039000000000031043500001c130010009c00005c790000213d0000010003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000080200002900000000020204330000000c04000029000000000042004b0000000d0700002900005c730000a13d0000000b030000290000000602300029000000000101043b000000000012043500000001044000390000000a010000290000000001010433000000000014004b00005b550000413d000000400100043d000000200210003900000003030000290000000003030433000d00000003001d00000002030000290000000003030433000c00000003001d0000000003070433000000000003004b000000000402001900005bb80000613d000000000500001900000000040200190000002007700039000000000607043300000000046404360000000105500039000000000035004b00005bb20000413d0000000003140049000000200430008a00000000004104350000001f0330003900001c2b043001970000000003140019000000000043004b0000000004000039000000010400403900001bce0030009c00005c790000213d000000010040019000005c790000c13d000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000400200043d0000002003200039000000000101043b000b00000001001d00000008070000290000000001070433000000000001004b000000000403001900005be90000613d000000000500001900000000040300190000002007700039000000000607043300000000046404360000000105500039000000000015004b00005be30000413d0000000001240049000000200410008a00000000004204350000001f0110003900001c2b041001970000000001240019000000000041004b0000000004000039000000010400403900001bce0010009c00005c790000213d000000010040019000005c790000c13d000000400010043f00001ba40030009c00001ba4030080410000004001300210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000000101043b000a00000001001d000000030100002900000080011000390000000001010433000900000001001d000000040010008c00005c810000213d000000030200002900000120012000390000000001010433000200000001001d00000100012000390000000001010433000400000001001d000000e0012000390000000001010433000500000001001d000000c0012000390000000001010433000600000001001d000000a0012000390000000001010433000700000001001d000000400100043d000800000001001d00001c1001000041000000000010044300000000010004120000000400100443000000a0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005c870000613d0000000d0200002900001ba7022001970000000c0300002900001ba703300197000000000401043b0000000806000029000001800160003900000001050000290000000000510435000001600160003900000002050000290000000000510435000001400160003900000004050000290000000000510435000001200160003900000005050000290000000000510435000001000160003900000006050000290000000000510435000000e00160003900000007050000290000000000510435000000c00160003900000009050000290000000000510435000000a0016000390000000a05000029000000000051043500000080016000390000000b0500002900000000005104350000006001600039000000000031043500000040016000390000000000210435000000200160003900000000004104350000018002000039000000000026043500001c160060009c00005c790000213d000001a002600039000000400020043f00001ba40010009c00001ba4010080410000004001100210000000000206043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005c7f0000613d000000000101043b000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000400100043d00001c4f02000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000a000000000002000002000030043f00001ba7041001970000000003000411000000000034004b00005f580000613d000900000002001d000400000001001d000300000004001d00001c1001000041000000000010044300000000010004120000000400100443000000e0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005f670000613d000000000101043b000a00000001001d00001bd2010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f000000010020019000005f670000613d000000000201043b00001c10010000410000000000100443000000000100041200000004001004430000000a0020006c000000400100003900005cc90000c13d00000100010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005d200000c13d00005f670000013d000800000002001d000000400200043d000a00000002001d0000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005f670000613d0000000a020000290000002002200039000000000101043b000700000002001d000000000012043500001c10010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005f670000613d000000000101043b0000000a020000290000004002200039000000000012043500001c100100004100000000001004430000000001000412000000040010044300000020010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000005f670000613d000000000101043b0000000a04000029000000a0024000390000000003000410000000000032043500000080024000390000000803000029000000000032043500000060024000390000000000120435000000a001000039000000000014043500001c700040009c00005f610000813d0000000a02000029000000c001200039000000400010043f000000070100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000000000401043b000000400100043d000000420210003900000009030000290000000000320435000000200210003900001c7a030000410000000000320435000000420300003900000000003104350000002203100039000100000004001d000000000043043500001c3a0010009c00005f610000213d0000008003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000000000401043b000002000500043d0000000001050433000003450210008a00001c850020009c000200000004001d00005d4c0000813d000a00000005001d00005e890000013d0000001d021000390000001e00200190000a00000005001d000000040200002900005e8a0000c13d000000010110018f000000410210015f0000001f01200039000000600110018f0000003f03100039000000e00330018f000000400400043d0000000003340019000a00000004001d000000000043004b0000000004000039000000010400403900001bce0030009c00005f610000213d000000010040019000005f610000c13d000000400030043f0000000a030000290000000003230436000000000413001900000000010000310000000201100367000000000501034f0000000006030019000000005705043c0000000006760436000000000046004b00005d690000c13d0000000004000019000002000500043d0000000006050433000000000046004b00005f590000a13d0000000a060000290000000006060433000000000046004b00005f590000a13d0000000006340019000000000706043300001c7b0770019700000000055400190000002005500039000000000505043300001c7c05500197000000000557019f00000000005604350000000104400039000000000024004b00005d6e0000413d000002000300043d0000000034030434000000000624004b00005f590000a13d0000000105200039000000000054004b00005f590000a13d00000002072001bf000000000074004b00005f590000a13d00001c7e0060009c00005f610000213d00001c2b086001970000003f0480003900001c0e04400197000000400a00043d00000000094a001900080000000a001d0000000000a9004b0000000004000039000000010400403900001bce0090009c00005f610000213d000000010040019000005f610000c13d000000000423001900000000040404330000000005530019000000000505043300000000037300190000000003030433000000050a600270000000400090043f000000080700002900060000000a001d0000000007a70436000700000007001d000000000008004b00005db00000613d00000007090000290000000007890019000000000801034f000000008a08043c0000000009a90436000000000079004b00005dac0000c13d000000200060008c00005dea0000413d0000000302200039000000200600003900000000070000190000000508700210000000000007004b00005dbb0000613d00000000097800d9000000200090008c00005f680000c13d000000000028001a00005f680000413d000000400a00043d00001ba800a0009c00005f610000213d000000000b2800190000004009a00039000000400090043f00000000096a0436000000000c01043b0000000000c90435000000000c000019000000000dbc0019000002000e00043d000000000f0e04330000000000df004b00005f590000a13d000000000f0a04330000000000cf004b00005f590000a13d000000000ded0019000000000e9c0019000000000f0e043300001c7b0ff00197000000200dd00039000000000d0d043300001c7c0dd00197000000000ddf019f0000000000de04350000001f00c0008c000000010cc0003900005dc70000413d000000000a0a043300001c0f00a0009c00005f5f0000213d0000002000a0008c00005f5f0000413d000000080a000029000000000a0a043300000000007a004b00005f590000a13d0000000708800029000000000909043300000000009804350000000107700039000000060070006c00005db50000413d00000008010000290000000001010433000000000001004b00005e370000613d000000e801400270000000f00250027000001c7d011001970000ff000220018f000000000112019f000000f80230027000050000002101a30000000008000019000000090600002900000005018002100000000704100029000000400100043d000000400310003900000020021000390000000004040433000000ff0080008c000900000008001d00005e150000213d000000010580020f000000050050018000005e150000613d000000000042043500000000006304350000004003000039000000000031043500001bd10010009c00005f610000213d0000006003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400005e260000013d000000000062043500000000004304350000004003000039000000000031043500001bd10010009c00005f610000213d0000006003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d0000000908000029000000000601043b000000010880003900000008010000290000000001010433000000000018004b00005df70000413d00005e380000013d0000000906000029000900000006001d0000000601000029000000000010043f000000200000043f000000000100041400001ba40010009c00001ba401008041000000c00110021000001c17011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000000000101043b000000000301041a000000400100043d000000400210003900000009040000290000000000420435000000200210003900000000003204350000004003000039000000000031043500001bd10010009c00005f610000213d0000006003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000000000201043b000000400100043d00000042031000390000000000230435000000200210003900001c7a0300004100000000003204350000002203100039000000010400002900000000004304350000004203000039000000000031043500001c3a0010009c00005f610000213d0000008003100039000000400030043f00001ba40020009c00001ba4020080410000004002200210000000000101043300001ba40010009c00001ba4010080410000006001100210000000000121019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000005f5f0000613d000002000500043d000000000401043b0000000402000029000900000005001d000800000004001d00001c4a0100004100000000001004430000000400200443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000005f670000613d000000000101043b000000000001004b000000020300002900005ebe0000613d000000400b00043d0000002401b000390000004002000039000000000021043500001c7f0100004100000000001b04350000000401b000390000000000310435000000090100002900000000370104340000004401b0003900000000007104350000006401b00039000000000007004b00005eb30000613d000000000400001900000000051400190000000006430019000000000606043300000000006504350000002004400039000000000074004b00005eac0000413d0000000003710019000000000003043500000000030004140000000302000029000000040020008c00005ece0000c13d0000000103000031000000200030008c0000002004000039000000000403401900005f020000013d0000000a030000290000000012030434000000400020008c00005f170000613d000000410020008c00005f9b0000c13d00000060023000390000000002020433000000f80220027000000000050300190000001d0320008a00001c860030009c00005fa30000a13d0000004003500039000000000303043300005f1c0000013d0000001f0570003900001c2b045001970000000004b40049000000000114001900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40400004100000000040b40190000004004400210000000000141019f00001ba40030009c00001ba403008041000000c003300210000000000131019f000a0000000b001d6e8b6e860000040f0000000a0b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b001900005ef10000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b00005eed0000c13d000000000006004b00005efe0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000005f7d0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c00005f610000213d000000010020019000005f610000c13d000000400010043f000000200030008c00005f5f0000413d00000000020b043300001c3f0020019800005f5f0000c13d00001c400220019700001c7f0020009c00005f580000613d00001c800200004100005f9d0000013d0000004002300039000000000202043300001c0f03200197000000ff022002700000001b022000390000000001010433000000400400043d00000060054000390000000000350435000000400340003900000000001304350000002001400039000000000021043500000008010000290000000000140435000000000000043f00001ba40040009c00001ba4040080410000004001400210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001c82011001c700000001020000396e8b6e860000040f0000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0540018f000000200440019000005f410000613d000000000601034f0000000007000019000000006806043c0000000007870436000000000047004b00005f3d0000c13d000000000005004b00005f4e0000613d000000000641034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000100000003001f0003000000010355000000010020019000005f6e0000613d000000000100043d00001ba701100198000000030200002900005f7a0000613d000000000021004b00005f7a0000c13d000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000001042f00001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d000104300000001f0530018f00001ba606300198000000400200043d000000000462001900005f880000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00005f750000c13d00005f880000013d000000400100043d00001c830200004100005f9d0000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900005f880000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00005f840000c13d000000000005004b00005f950000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d00010430000000400100043d00001c8402000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00001c810300004100000000003104350000000403100039000000000023043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d00010430000000020020008c00005fb10000813d0000000001210436000000000001042d00001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000300000000000200001c1001000041000000000010044300000000010004120000000400100443000000e0010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000060410000613d000000000101043b000300000001001d00001bd2010000410000000000100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001bd3011001c70000800b020000396e8b6e860000040f0000000100200190000060410000613d000000000201043b00001c1001000041000000000010044300000000010004120000000400100443000000030020006c00005fe70000c13d00000100010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f00000001002001900000603f0000c13d000060410000013d000200000002001d000000400100043d000300000001001d00000040010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000060410000613d00000003020000290000002002200039000000000101043b000100000002001d000000000012043500001c10010000410000000000100443000000000100041200000004001004430000002400000443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000060410000613d000000000101043b00000003020000290000004002200039000000000012043500001c100100004100000000001004430000000001000412000000040010044300000020010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000060410000613d000000000101043b0000000304000029000000a0024000390000000003000410000000000032043500000080024000390000000203000029000000000032043500000060024000390000000000120435000000a001000039000000000014043500001c700040009c000060420000813d0000000302000029000000c001200039000000400010043f000000010100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f0000000100200190000060480000613d000000000101043b000000000001042d000000000001042f00001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d00010430000000000100001900006e8d00010430000a000000000002000600000003001d000700000002001d000800000004001d000000000004004b0000625c0000613d0000000023060434000a00000002001d000000000053004b000900000001001d0000613a0000613d0000000a0200002900000000020204330000000002020433000000000002004b0000613a0000613d000400000003001d000100000005001d000200000006001d000000400100043d000500000001001d000000200210003900001c4801000041000300000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000062590000613d000000000101043b0000000504000029000000600240003900000004030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f0000000100200190000062590000613d000000000101043b0000000504000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001c700040009c0000624d0000813d0000000502000029000000c001200039000000400010043f000000030100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f00000001002001900000625a0000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000500000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000062590000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b000062840000613d0000000a01000029000000000201043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b000060ea0000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c000062530000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000060cb0000413d00000000040004140000000502000029000000040020008c000060f30000c13d0000000103000031000000200030008c00000020040000390000000004034019000061240000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f00050000000b001d6e8b6e810000040f000000050b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000061130000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b0000610f0000c13d000000000006004b000061200000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000062a20000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c0000624d0000213d00000001002001900000624d0000c13d000000400010043f000000200030008c0000625a0000413d00000000010b043300001c3f001001980000625a0000c13d00000060010000390000000a020000290000000000120435000000090100002900000002060000290000000105000029000000000005004b000061c50000613d000000000f050019000000000e0600190000000a0100002900000000010104330000000001010433000000010010003a000062c00000413d000000010310003900001bce0030009c0000624d0000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c0000624d0000213d00000001006001900000624d0000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c0000624d0000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000753001900000000006704350000002005500039000000000045004b000061550000413d000000000001004b000061a00000613d00000000040000190000000a0500002900000000060504330000000005060433000000000045004b000062470000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c000062530000213d000000400600043d00001bd40060009c0000624d0000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b000062470000a13d000000000553001900000000006504350000000005020433000000000045004b000062470000a13d0000000104400039000000000014004b0000616d0000413d000000400400043d00001bd40040009c0000624d0000213d000000c005400039000000400050043f000000a00540003900000008060000290000000000650435000000060500002900001ba70550019700000060064000390000000000560435000000070500002900001ba70550019700000040064000390000000000560435000000090500002900001ba7055001970000002006400039000000000056043500000001050000390000000000540435000000800540003900000000000504350000000005020433000000000015004b000062470000a13d0000000505100210000000000353001900000000004304350000000003020433000000000013004b000062470000a13d0000000a0100002900000000002104350000000000fe0435000000000001042d00001c4a0200004100000000002004430000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f0000000100200190000062590000613d000000400200043d000000000101043b000000000001004b000062640000613d000000640120003900000008030000290000000000310435000000200120003900001c7503000041000000000031043500000064030000390000000000320435000000060300002900001ba70c30019700000044032000390000000000c30435000000070300002900001ba70b30019700000024032000390000000000b3043500001bb40020009c0000624d0000213d000000a003200039000000400030043f000000000302043300000000040004140000000902000029000000040020008c0000621c0000c13d00000001040000310000000002000019000000000004004b000062330000613d00001bce0040009c0000624d0000213d0000001f0140003900001c2b011001970000003f0110003900001c2b03100197000000400100043d0000000003310019000000000013004b0000000006000039000000010600403900001bce0030009c0000624d0000213d00000001006001900000624d0000c13d000000400030043f000000000341043600001c2b054001980000001f0640018f000000000453001900000003070003670000620e0000613d000000000807034f0000000009030019000000008a08043c0000000009a90436000000000049004b0000620a0000c13d000000000006004b000062350000613d000000000557034f0000000306600210000000000704043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f0000000000540435000062350000013d00001ba40010009c00001ba401008041000000400110021000001ba40030009c00001ba4030080410000006003300210000000000113019f00001ba40040009c00001ba404008041000000c003400210000000000131019f000a0000000b001d00070000000c001d6e8b6e810000040f000000070c0000290000000a0b000029000000010220015f0003000000010355000000600110027000011ba40010019d00001ba404100197000000000004004b000061f20000c13d0000006001000039000000800300003900000001002001900000626f0000c13d0000000001010433000000200010008c000062460000413d00001c0f0010009c0000625a0000213d000000200010008c0000625a0000413d0000000001030433000000000001004b0000000002000039000000010200c039000000000021004b0000625a0000c13d000000000001004b0000628f0000613d000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000000001042f000000000100001900006e8d00010430000000400100043d00001c4602000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d0001043000001c73010000410000000000120435000000090100002900001ba7011001970000000403200039000000000013043500001ba40020009c00001ba402008041000000400120021000001c15011001c700006e8d00010430000000400100043d00000084021000390000000803000029000000000032043500000044021000390000000000c2043500000024021000390000000000b2043500001c89020000410000000000210435000000090200002900001ba702200197000000040310003900000000002304350000006402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001c8a011001c700006e8d0001043000001c4c0100004100000000001b0435000000040100002900000000001304350000000501000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d00010430000000400100043d00000064021000390000000803000029000000000032043500000044021000390000000000c2043500000024021000390000000000b2043500001c87020000410000000000210435000000090200002900001ba7022001970000000403100039000000000023043500001ba40010009c00001ba401008041000000400110021000001c88011001c700006e8d000104300000001f0530018f00001ba606300198000000400200043d0000000004620019000062ad0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000062a90000c13d000000000005004b000062ba0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d0001043000001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430001d000000000002000100000006001d001400000005001d000200000004001d001c00000003001d000900000002001d000600000001001d0000000012010434000500000001001d00001c310020009c00006d2b0000813d00000005012002100000003f0310003900001c0e03300197000000400400043d0000000003340019000400000004001d000000000043004b0000000004000039000000010400403900001bce0030009c00006d2b0000213d000000010040019000006d2b0000c13d000000400030043f00000004030000290000000002230436000300000002001d0000001f0210018f000000000001004b000062ed0000613d0000000304000029000000000114001900000000030000310000000203300367000000003503043c0000000004540436000000000014004b000062e90000c13d000000000002004b000000400100043d001300000001001d00001ba80010009c00006d2b0000213d00000013020000290000004001200039000000400010043f000000200e200039000000600100003900000000001e043500000000000204350000001c010000290000000021010434001b00000002001d000000000001004b00120000000e001d000063b70000613d0000000009000019000063100000013d000000000503043300000080017000390000000003010433000000000108043300001ba70110019700001ba70330019700000013070000296e8b46c00000040f000000120e0000290000001d0900002900000001099000390000001c010000290000000001010433000000000019004b000063b70000813d00000005019002100000001b011000290000000006010433000000005706043400000060037000390000000002030433000000000002004b0000630b0000613d0000000081070434000000060010008c00006d310000813d000000000001004b001d00000009001d0000633c0000c13d001900000002001d001500000006001d001600000005001d001700000008001d001800000003001d001a00000007001d00001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000190010006b0000001a0700002900006e070000213d0000000001070433000000120e0000290000001d090000290000001803000029000000170800002900000016050000290000001506000029000000050010008c00006d310000213d00000040027000390000000004020433000000000001004b000063530000613d00000040026000390000000006020433000000000205043300001ba702200197000000010010008c000063670000613d000000020010008c000063010000c13d000000000503043300000080017000390000000003010433000000000108043300001ba70110019700001ba70330019700000013070000296e8b48f10000040f000063090000013d000000000108043300001ba70110019700000000004101a000006d4c0000c13d0000000003030433000000000003004b00006d490000613d0000008001700039000000000101043300001ba7041001970000000001000414000000040040008c001a00000003001d001900000004001d000063750000c13d00000001010000310000000102000039000000000001004b000063850000c13d000063ac0000013d000000000004004b00006d4c0000c13d000000000403043300000080017000390000000003010433000000000108043300001ba70110019700001ba703300197000000000506001900000013060000296e8b604a0000040f0000001d09000029000000120e0000290000630b0000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f0000001d09000029000000120e000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000063ac0000613d00001bce0010009c00006d2b0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c00006d2b0000213d000000010050019000006d2b0000c13d000000400040043f000000000613043600001c2b04100198000000000346001900000003050003670000639f0000613d000000000705034f000000007807043c0000000006860436000000000036004b0000639b0000c13d0000001f01100190000063ac0000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b0000630b0000c13d000000400100043d00000024021000390000001a03000029000000000032043500001c450200004100000000002104350000000402100039000000190300002900006d5c0000013d00000009010000290000000021010434000a00000002001d000000000001004b000069e20000613d000000140200002900181ba70020019b0000000004000019000063c60000013d000000090100002900000000010104330000000b040000290000000104400039000000000014004b000069e20000813d00000005024002100000000a0320002900000000050304330000008003500039000000000303043300001c1f00300198000063c30000613d000c00000005001d00000004010000290000000001010433000b00000004001d000000000041004b00006d250000a13d000000030120002900000001030000390000000000310435000000060100002900000000010104330000000b0010006c00006d250000a13d0000000c0100002900000020011000390000000001010433001b00000001001d0000000001010433001600000001001d000000000001004b000069c60000613d00000005012000290000000c02000029001500a00020003d00000000010104330000000001010433001000000001001d000f01200010003d0000000004000019000063f50000013d00000000002e043500000013010000290000000000f104350000001d040000290000001a030000290000001c0100002900000000003104350000000104400039000000160040006c000069c60000813d0000001b010000290000000001010433001d00000004001d000000000041004b00006d250000a13d0000001501000029000000000101043300000000020104330000001d0020006c00006d250000a13d0000001d04000029000000050240021000000020032000390000001b023000290000000002020433000000600520003900000000011300190000000003010433001c00000005001d0000000001050433000000000001004b000063f00000613d001a00000003001d000000400100043d00001bb40010009c00006d2b0000213d000000a003100039000000400030043f0000008003100039000000000003043500000060031000390000000000030435000000400310003900000000000304350000002003100039000000000003043500000000000104350000000041020434000000050010008c00006d310000213d000000400600043d00001bb40060009c00006d2b0000213d0000001c05000029000000000305043300000040022000390000000007020433000000000204043300001ba705200197000000a002600039000000400020043f0000008002600039000000180400002900000000004204350000006002600039000000000032043500000040026000390000000000720435000000200260003900000000005204350000000000160435000000000001004b001700000003001d000065840000613d0000000f02000029000000000f0204330000001002000029000000000202043300141ba70020019b000000010010008c001900000005001d000064e00000613d000000020010008c001100000007001d000065900000c13d000000130100002900000000020104330000000000f2004b000066b20000613d00000000010e04330000000001010433000000000001004b000066b20000613d000800000002001d000e0000000f001d000000400100043d000d00000001001d000000200210003900001c4801000041000700000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000000d04000029000000600240003900000008030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000000d04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c00006d2b0000213d0000000d02000029000000c001200039000000400010043f000000070100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006d470000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000d00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400a00043d0000002404a000390000000403a00039000000000101043b000000000001004b00006d680000613d000000120e00002900000000020e043300001c4b0100004100000000001a043500000020010000390000000000130435000000000302043300000000003404350000004401a00039000000000003004b000064d70000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00006d310000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b000064b80000413d00000000040004140000000d02000029000000040020008c0000666d0000c13d0000000103000031000000200030008c000000200400003900000000040340190000669e0000013d000000000007004b00006d4c0000c13d000000000003004b00006d490000613d000000130100002900000000020104330000000000f2004b000068c60000613d00000000010e04330000000001010433000000000001004b000068c60000613d000d00000002001d000e0000000f001d000000400100043d001100000001001d000000200210003900001c4801000041000800000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000110400002900000060024000390000000d030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000001104000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c00006d2b0000213d0000001102000029000000c001200039000000400010043f000000080100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006d470000613d000000000101043b00001c4a02000041000000000020044300001ba701100197001100000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400a00043d0000002404a000390000000403a00039000000000101043b000000000001004b00006d980000613d000000120e00002900000000020e043300001c4b0100004100000000001a043500000020010000390000000000130435000000000302043300000000003404350000004401a00039000000000003004b0000657b0000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00006d310000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b0000655c0000413d00000000040004140000001102000029000000040020008c000068810000c13d0000000103000031000000200030008c00000020040000390000000004034019000068b20000013d00000000007501a000006d4c0000c13d000000000003004b00006d490000613d0000000001000414000000040040008c000066320000c13d00000001010000310000000102000039000000000001004b000066410000c13d000066680000013d000000000003004b00006d490000613d000000130100002900000000020104330000000000f2004b000067b60000613d00000000010e04330000000001010433000000000001004b000067b60000613d000800000002001d000e0000000f001d000000400100043d000d00000001001d000000200210003900001c4801000041000700000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000000d04000029000000600240003900000008030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000000d04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c00006d2b0000213d0000000d02000029000000c001200039000000400010043f000000070100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006d470000613d000000000101043b00001c4a02000041000000000020044300001ba701100197000d00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400a00043d0000002404a000390000000403a00039000000000101043b000000000001004b00006d680000613d000000120e00002900000000020e043300001c4b0100004100000000001a043500000020010000390000000000130435000000000302043300000000003404350000004401a00039000000000003004b000066290000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00006d310000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b0000660a0000413d00000000040004140000000d02000029000000040020008c000067710000c13d0000000103000031000000200030008c00000020040000390000000004034019000067a20000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f000000120e000029000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b000066680000613d00001bce0010009c00006d2b0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c00006d2b0000213d000000010050019000006d2b0000c13d000000400040043f000000000613043600001c2b04100198000000000346001900000003050003670000665b0000613d000000000705034f000000007807043c0000000006860436000000000036004b000066570000c13d0000001f01100190000066680000613d000000000445034f0000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000000002004b0000001d040000290000001a03000029000063f00000c13d00006d540000013d0000000001a1004900001ba40010009c00001ba401008041000000600110021000001ba400a0009c00001ba40300004100000000030a40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f000d0000000a001d6e8b6e810000040f0000000d0a0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056a00190000668c0000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000066880000c13d0000001f07400190000066990000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000120e00002900006dd10000613d0000001f01400039000000600210018f0000000001a20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000010a043300001c3f0010019800006d470000c13d000000600100003900000000001e043500000017030000290000000e0f00002900000000000f004b0000672a0000613d00000000010e04330000000001010433000000010010003a00006e470000413d000000010310003900001bce0030009c00006d2b0000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c00006d2b0000213d000000010060019000006d2b0000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c00006d2b0000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000735001900000000006704350000002005500039000000000045004b000066ca0000413d000000000001004b000067140000613d000000000400001900000000060e04330000000005060433000000000045004b00006d250000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c00006d310000213d000000400600043d00001bd40060009c00006d2b0000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b00006d250000a13d000000000535001900000000006504350000000005020433000000000045004b00006d250000a13d0000000104400039000000000014004b000066e20000413d000000400400043d00001bd40040009c00006d2b0000213d000000c005400039000000400050043f000000a0054000390000001706000029000000000065043500000080054000390000001106000029000000000065043500000060054000390000001806000029000000000065043500000040054000390000001406000029000000000065043500000020054000390000001906000029000000000065043500000002050000390000682d0000013d000000010030008c00006d6e0000c13d00001c4a01000041000000000010044300000019010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b00006d620000613d00001c4a01000041000000000010044300000019010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b000000120e000029000000180400002900006d470000613d000000400500043d0000004401500039000000110200002900000000002104350000002401500039000000000041043500001c7501000041000000000015043500000004015000390000001402000029000000000021043500000000010004140000001902000029000000040020008c0000687d0000613d00001ba40050009c00001ba4030000410000000003054019000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001c76011001c7001900000005001d6e8b6e810000040f0000001905000029000000120e0000290000000003010019000000600330027000011ba40030019d000300000001035500000001002001900000687d0000c13d00006da30000013d0000000001a1004900001ba40010009c00001ba401008041000000600110021000001ba400a0009c00001ba40300004100000000030a40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f000d0000000a001d6e8b6e810000040f0000000d0a0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000067900000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b0000678c0000c13d0000001f074001900000679d0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000120e00002900006ddd0000613d0000001f01400039000000600210018f0000000001a20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000010a043300001c3f0010019800006d470000c13d000000600100003900000000001e043500000019050000290000000e0f00002900000000000f004b000068320000613d00000000010e04330000000001010433000000010010003a00006e470000413d000000010310003900001bce0030009c00006d2b0000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c00006d2b0000213d000000010060019000006d2b0000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c00006d2b0000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000735001900000000006704350000002005500039000000000045004b000067ce0000413d000000000001004b000068180000613d000000000400001900000000060e04330000000005060433000000000045004b00006d250000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c00006d310000213d000000400600043d00001bd40060009c00006d2b0000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b00006d250000a13d000000000535001900000000006504350000000005020433000000000045004b00006d250000a13d0000000104400039000000000014004b000067e60000413d000000400400043d00001bd40040009c00006d2b0000213d000000c005400039000000400050043f000000a00540003900000017060000290000000000650435000000800540003900000011060000290000000000650435000000600540003900000018060000290000000000650435000000400540003900000014060000290000000000650435000000200540003900000019060000290000000000650435000000030500003900000000005404350000000005020433000000000015004b000069400000213d00006d250000013d00001c4a0100004100000000001004430000000400500443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b00006d620000613d00001c4a01000041000000000010044300000019010000290000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b000000120e000029000000180400002900006d470000613d000000400500043d0000008401500039000000a00200003900000000002104350000006401500039000000170200002900000000002104350000004401500039000000110200002900000000002104350000002401500039000000000041043500001c71010000410000000000150435000000040150003900000014020000290000000000210435000000a401500039000000000001043500000000010004140000001902000029000000040020008c0000687d0000613d00001ba40050009c00001ba4030000410000000003054019000000400330021000001ba40010009c00001ba401008041000000c001100210000000000131019f00001c72011001c7001900000005001d6e8b6e810000040f0000001905000029000000120e0000290000000003010019000000600330027000011ba40030019d0003000000010355000000010020019000006db00000613d00001bce0050009c00006d2b0000213d000000400050043f000063ee0000013d0000000001a1004900001ba40010009c00001ba401008041000000600110021000001ba400a0009c00001ba40300004100000000030a40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f00110000000a001d6e8b6e810000040f000000110a0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000068a00000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b0000689c0000c13d0000001f07400190000068ad0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000120e00002900006de90000613d0000001f01400039000000600210018f0000000001a20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000010a043300001c3f0010019800006d470000c13d000000600100003900000000001e043500000019050000290000000e0f00002900000000000f004b000069470000613d00000000010e04330000000001010433000000010010003a00006e470000413d000000010310003900001bce0030009c00006d2b0000213d00000005043002100000003f0240003900001c0e05200197000000400200043d0000000005520019000000000025004b0000000006000039000000010600403900001bce0050009c00006d2b0000213d000000010060019000006d2b0000c13d000000400050043f00000000033204360000000005000019000000400600043d00001bd40060009c00006d2b0000213d000000c007600039000000400070043f000000a0076000390000000000070435000000800760003900000000000704350000006007600039000000000007043500000040076000390000000000070435000000200760003900000000000704350000000000060435000000000735001900000000006704350000002005500039000000000045004b000068de0000413d000000000001004b000069280000613d000000000400001900000000060e04330000000005060433000000000045004b00006d250000a13d00000005054002100000000006650019000000200660003900000000080604330000000097080434000000030070008c00006d310000213d000000400600043d00001bd40060009c00006d2b0000213d0000000009090433000000400a800039000000000a0a0433000000600b800039000000000b0b0433000000800c800039000000000c0c0433000000a0088000390000000008080433000000c00d6000390000004000d0043f000000a00d60003900000000008d043500000080086000390000000000c8043500001ba708b00197000000600b60003900000000008b043500001ba708a00197000000400a60003900000000008a043500001ba7089001970000002009600039000000000089043500000000007604350000000007020433000000000047004b00006d250000a13d000000000535001900000000006504350000000005020433000000000045004b00006d250000a13d0000000104400039000000000014004b000068f60000413d000000400400043d00001bd40040009c00006d2b0000213d000000c005400039000000400050043f000000a0054000390000001706000029000000000065043500000060054000390000001806000029000000000065043500000040054000390000001406000029000000000065043500000020054000390000001906000029000000000065043500000001050000390000000000540435000000800540003900000000000504350000000005020433000000000015004b00006d250000a13d0000000505100210000000000353001900000000004304350000000003020433000000000013004b000063eb0000213d00006d250000013d00001c4a0100004100000000001004430000000400500443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400200043d000000000101043b000000000001004b00006d780000613d000000640120003900000017030000290000000000310435000000440120003900000018030000290000000000310435000000200120003900001c750300004100000000003104350000002403200039000000140400002900000000004304350000006403000039000000000032043500001bb40020009c000000120e00002900006d2b0000213d000000a003200039000000400030043f000000000302043300000000040004140000001902000029000000040020008c000069720000c13d00000001040000310000000002000019000069840000013d00001ba40010009c00001ba401008041000000400110021000001ba40030009c00001ba4030080410000006003300210000000000113019f00001ba40040009c00001ba404008041000000c003400210000000000131019f6e8b6e810000040f000000120e000029000000010220015f0003000000010355000000600110027000011ba40010019d00001ba404100197000000000004004b00000080010000390000006003000039000069b00000613d00001bce0040009c00006d2b0000213d0000001f0140003900001c2b011001970000003f0110003900001c2b01100197000000400300043d0000000001130019000000000031004b0000000005000039000000010500403900001bce0010009c00006d2b0000213d000000010050019000006d2b0000c13d000000400010043f000000000143043600001c2b0640019800000000056100190000000307000367000069a30000613d000000000807034f0000000009010019000000008a08043c0000000009a90436000000000059004b0000699f0000c13d0000001f04400190000069b00000613d000000000667034f0000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000000010020019000006d820000c13d0000000002030433000000200020008c0000001d040000290000001a03000029000063f00000413d00001c0f0020009c00006d470000213d000000200020008c00006d470000413d0000000001010433000000000001004b0000000002000039000000010200c039000000000021004b00006d470000c13d000000000001004b0000001d040000290000001a03000029000063f00000c13d00006dbd0000013d0000000c04000029000000400140003900000000010104330000000023010434000000000003004b000063c00000613d000000c004400039000000000300001900000005053002100000000006520019000000000606043300000060066000390000000007060433000000000007004b00006d370000c13d00000000070404330000000008070433000000000038004b00006d250000a13d000000000575001900000020055000390000000005050433000000000056043500000001033000390000000005010433000000000053004b000069ce0000413d000063c00000013d00000000010e04330000000001010433000000000001004b00006ac30000613d00000013010000290000000001010433001c00000001001d000000400100043d001d00000001001d000000200210003900001c4801000041001b00000002001d000000000012043500001c100100004100000000001004430000000001000412000000040010044300000120010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000001d0400002900000060024000390000001c030000290000000000320435000000400240003900001ba701100197000000000012043500001c100100004100000000001004430000000001000412000000040010044300000160010000390000002400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c11011001c700008005020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b0000001d04000029000000a00240003900001c4903000041000000000032043500000080024000390000000000120435000000a001000039000000000014043500001bd40040009c00006d2b0000213d0000001d02000029000000c001200039000000400010043f0000001b0100002900001ba40010009c00001ba4010080410000004001100210000000000202043300001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006d470000613d000000000101043b00001c4a02000041000000000020044300001ba701100197001d00000001001d0000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c700008002020000396e8b6e860000040f000000010020019000006d460000613d000000400b00043d0000002404b000390000000403b00039000000000101043b000000000001004b00006e270000613d0000001208000029000000000208043300001c4b0100004100000000001b043500000020010000390000000000130435000000000302043300000000003404350000004401b00039000000000003004b00006a760000613d0000000004000019000000200220003900000000050204330000000067050434000000040070008c00006d310000813d0000000007710436000000000606043300001ba70660019700000000006704350000004006500039000000000606043300001ba706600197000000400710003900000000006704350000006006500039000000000606043300001ba706600197000000600710003900000000006704350000008006500039000000000606043300000080071000390000000000670435000000a0055000390000000005050433000000a0061000390000000000560435000000c0011000390000000104400039000000000034004b00006a570000413d00000000040004140000001d02000029000000040020008c00006a7f0000c13d0000000103000031000000200030008c0000002004000039000000000403401900006ab10000013d0000000001b1004900001ba40010009c00001ba401008041000000600110021000001ba400b0009c00001ba40300004100000000030b40190000004003300210000000000131019f00001ba40040009c00001ba404008041000000c003400210000000000131019f001d0000000b001d6e8b6e810000040f0000001d0b0000290000000003010019000000600330027000001ba403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b001900006a9f0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b00006a9b0000c13d000000000006004b00006aac0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000120800002900006e3b0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000010b043300001c3f0010019800006d470000c13d0000006001000039000000000018043500001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f000000010020019000006d460000613d000000000101043b000000000001004b000000000f00041100006b290000613d00001c6c01000041000000000010044300000000010004100000000400100443000000000100041400001ba40010009c00001ba401008041000000c00110021000001c27011001c70000800a020000396e8b6e860000040f000000010020019000006d460000613d000000000301043b000000000003004b000000000f00041100006d490000613d000000000100041400001ba704f00197000000040040008c001d00000003001d001c00000004001d00006af00000c13d00000001020000390000000101000031000000000001004b00006aff0000c13d00006b270000013d00001ba40010009c00001ba401008041000000c00110021000001bcd011001c7000080090200003900000000050000196e8b6e810000040f000000000f000411000000010220018f0003000000010355000000600110027000011ba40010019d00001ba401100197000000000001004b00006b270000613d00001bce0010009c00006d2b0000213d0000001f0310003900001c2b033001970000003f0330003900001c2b04300197000000400300043d0000000004430019000000000034004b0000000005000039000000010500403900001bce0040009c00006d2b0000213d000000010050019000006d2b0000c13d000000400040043f000000000613043600001c2b031001980000001f0410018f0000000001360019000000030500036700006b1a0000613d000000000705034f000000007807043c0000000006860436000000000016004b00006b160000c13d000000000004004b00006b270000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000000002004b00006e320000613d000000010000006b00006d230000613d00000009010000290000000001010433000000000001004b00006d230000613d0000000201000029001b00200010003d000000000800001900006b380000013d000000010880003900000009010000290000000001010433000000000018004b00006d230000813d00000005018002100000000a0210002900000000040204330000008002400039000000000202043300001c1f0020019800006b330000613d00000006020000290000000002020433000000000082004b00006d250000a13d00000002020000290000000002020433000000000082004b00006d250000a13d001d00000008001d00000005021000290000000006020433000000000506043300000080025000390000000002020433000000040020008c00006d310000213d0000001b01100029000000000d01043300001c6f08200197000000007104043400001ba703100197000000020080008c00006c110000c13d0000002001500039000000000101043300001ba70210019700000000002f004b0000001d0800002900006b330000613d000000400900043d00001c3d0090009c00006d2b0000213d000000e001500039000000000801043300000080016000390000004004400039000000000a070433000000000b040433000000000c010433000000a0015000390000000006010433000000c00150003900000000050104330000014001900039000000400010043f0000012001900039000000000081043500000100049000390000000000540435000000e0059000390000000000650435000000c00690003900000002070000290000000000760435000000a0079000390000000000c7043500000080089000390000000000b80435000000600b9000390000000000ab0435000000400a90003900000000003a043500000020039000390000000000f30435001c0000000d001d0000000000d90435000000400e00043d00001c4d0c0000410000000000ce0435000000040ce00039000000200d0000390000000000dc04350000000009090433000000240ce0003900000000009c0435000000000303043300001ba7033001970000004409e00039000000000039043500000000030a043300001ba7033001970000006409e00039000000000039043500000000090b04330000008403e00039000001400a0000390000000000a304350000016403e00039000000000a0904330000000000a30435001a0000000e001d0000018403e0003900000000000a004b00006bb30000613d000000000b0000190000002009900039000000000c09043300000000de0c04340000000500e0008c00006d310000213d000000000ee30436000000000d0d043300001ba70dd001970000000000de0435000000400dc00039000000000d0d0433000000400e3000390000000000de0435000000600cc00039000000000c0c0433000000600d3000390000000000cd04350000008003300039000000010bb000390000000000ab004b00006b9e0000413d0000001a0a0000290000000009a30049000000240990008a0000000008080433000000a40aa0003900000000009a043500000000090804330000000003930436000000000009004b00006bd80000613d000000000a0000190000002008800039000000000b08043300000000cd0b04340000000500d0008c00006d310000213d000000000dd30436000000000c0c043300001ba70cc001970000000000cd0435000000400cb00039000000000c0c0433000000400d3000390000000000cd0435000000600cb00039000000000c0c0433000000600d3000390000000000cd0435000000800bb00039000000000b0b043300001ba70bb00197000000800c3000390000000000bc0435000000a003300039000000010aa0003900000000009a004b00006bbe0000413d0000001a0c0000290000000008c30049000000240880008a0000000007070433000000c409c00039000000000089043500000000870704340000000003730436000000000007004b00006bea0000613d0000000009000019000000000a390019000000000b980019000000000b0b04330000000000ba04350000002009900039000000000079004b00006be30000413d000000000873001900000000000804350000001f0770003900001c2b0770019700000000037300190000000007c30049000000240770008a0000000006060433000000e408c00039000000000078043500000000070604330000000003730436000000000007004b00006bff0000613d00000000080000190000002006600039000000000906043300000000039304360000000108800039000000000078004b00006bf90000413d00000000050504330000010406c00039000000000056043500000000040404330000012405c0003900000000004504350000014404c00039000000000101043300000000001404350000000001000414000000040020008c00006cd90000c13d0000000103000031000000200030008c000000200400003900000000040340190000001c0500002900006d0a0000013d000000040020008c0000001d0800002900006b330000c13d001c0000000d001d00000080026000390000000002020433000000400440003900000000040404330000000006070433000000400c00043d00001c6d0500004100000000005c04350000000405c00039000000a0070000390000000000750435000000a405c0003900000000070604330000000000750435000000c405c00039000000000007004b00006c3c0000613d00000000080000190000002006600039000000000906043300000000ab0904340000000500b0008c00006d310000213d000000000bb50436000000000a0a043300001ba70aa001970000000000ab0435000000400a900039000000000a0a0433000000400b5000390000000000ab043500000060099000390000000009090433000000600a50003900000000009a043500000080055000390000000108800039000000000078004b00006c270000413d0000000006c50049000000040660008a0000002407c00039000000000067043500000000060404330000000005650436000000000006004b00006c5f0000613d000000000700001900000020044000390000000008040433000000009a0804340000000500a0008c00006d310000213d000000000aa50436000000000909043300001ba70990019700000000009a043500000040098000390000000009090433000000400a50003900000000009a043500000060098000390000000009090433000000600a50003900000000009a04350000008008800039000000000808043300001ba70880019700000080095000390000000000890435000000a0055000390000000107700039000000000067004b00006c450000413d0000000004c50049000000040440008a0000004406c00039000000000046043500000000640204340000000002450436000000000004004b00006c6f0000613d000000000500001900000000072500190000000008560019000000000808043300000000008704350000002005500039000000000045004b00006c680000413d000000000542001900000000000504350000001f0440003900001c2b0440019700000000024200190000000004c20049000000040440008a0000006405c000390000000000450435000000020600002900000000040604330000000002420436000000000004004b0000001c0900002900006c850000613d00000000050000190000002006600039000000000706043300000000027204360000000105500039000000000045004b00006c7f0000413d0000006001100210000000000191013f0000008404c0003900000000001404350000000001000414000000040030008c00006c910000c13d0000000103000031000000200030008c0000002004000039000000000403401900006cc40000013d0000000002c2004900001ba40020009c00001ba402008041000000600220021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000242019f00001ba40010009c00001ba401008041000000c001100210000000000112019f0000000002030019001a0000000c001d6e8b6e810000040f0000001a0c0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056c001900006cb10000613d000000000701034f00000000080c0019000000007907043c0000000008980436000000000058004b00006cad0000c13d0000001f0740019000006cbe0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000000f0004110000001c0900002900006e0f0000613d0000001f01400039000000600210018f0000000001c20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000020c043300001c3f0020019800006d470000c13d00001c400220019700001c6d0020009c0000001d0800002900006b330000613d00006e0a0000013d0000000003c3004900001ba40030009c00001ba403008041000000600330021000001ba400c0009c00001ba40400004100000000040c40190000004004400210000000000343019f00001ba40010009c00001ba401008041000000c001100210000000000131019f6e8b6e810000040f0000001a0c0000290000000003010019000000600330027000001ba403300197000000200030008c00000020040000390000000004034019000000200640019000000000056c001900006cf70000613d000000000701034f00000000080c0019000000007907043c0000000008980436000000000058004b00006cf30000c13d0000001f0740019000006d040000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000000000f0004110000001c0500002900006e1b0000613d0000001f01400039000000600210018f0000000001c20019000000000021004b0000000002000039000000010200403900001bce0010009c00006d2b0000213d000000010020019000006d2b0000c13d000000400010043f000000200030008c00006d470000413d00000000020c043300001c3f0020019800006d470000c13d00001c400220019700001c4d0020009c0000001d0800002900006b330000613d00001c410200004100000000002104350000000402100039000000000052043500006d730000013d0000000401000029000000000001042d00001c1401000041000000000010043f0000003201000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000004101000039000000040010043f00001c150100004100006e8d0001043000001c1401000041000000000010043f0000002101000039000000040010043f00001c150100004100006e8d00010430000000400100043d000000440210003900000000007204350000002402100039000000000032043500001c8b02000041000000000021043500000004021000390000000b03000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c76011001c700006e8d00010430000000000001042f000000000100001900006e8d00010430000000400100043d00001c460200004100006d4e0000013d000000400100043d00001c4e02000041000000000021043500001ba40010009c00001ba401008041000000400110021000001bd6011001c700006e8d00010430000000400100043d00000024021000390000001703000029000000000032043500001c4502000041000000000021043500000004021000390000001803000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c36011001c700006e8d00010430000000400100043d00001c730200004100000000002104350000000402100039000000190300002900006d720000013d00001c4c0100004100000000001a0435000000080100002900000000001304350000000d0100002900006d9d0000013d000000400100043d00001c740200004100000000002104350000000402100039000000000032043500001ba40010009c00001ba401008041000000400110021000001c15011001c700006e8d0001043000001c7301000041000000000012043500000004012000390000001903000029000000000031043500001ba40020009c00001ba402008041000000400120021000001c15011001c700006e8d00010430000000400100043d00000084021000390000001703000029000000000032043500000044021000390000001803000029000000000032043500000024021000390000001403000029000000000032043500001c890200004100000000002104350000000402100039000000190300002900000000003204350000006402100039000000000002043500001ba40010009c00001ba401008041000000400110021000001c8a011001c700006e8d0001043000001c4c0100004100000000001a04350000000d0100002900000000001304350000001101000029000000000014043500001ba400a0009c00001ba40a0080410000004001a0021000001c36011001c700006e8d0001043000001ba4033001970000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006dab0000c13d00006df40000013d00001ba4033001970000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006db80000c13d00006df40000013d000000400100043d00000064021000390000001703000029000000000032043500000044021000390000001803000029000000000032043500000024021000390000001403000029000000000032043500001c8702000041000000000021043500000004021000390000001903000029000000000032043500001ba40010009c00001ba401008041000000400110021000001c88011001c700006e8d000104300000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006dd80000c13d00006df40000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006de40000c13d00006df40000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006df00000c13d000000000005004b00006e010000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000001ba40020009c00001ba4020080410000004002200210000000000112019f00006e8d00010430000000400100043d00001c470200004100006d4e0000013d00001c6e0200004100000000002104350000000402100039000000000092043500006d730000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006e160000c13d00006df40000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006e220000c13d00006df40000013d00001c4c0100004100000000001b04350000001c0100002900000000001304350000001d01000029000000000014043500001ba400b0009c00001ba40b0080410000004001b0021000001c36011001c700006e8d00010430000000400100043d00000024021000390000001d03000029000000000032043500001c4502000041000000000021043500000004021000390000001c0300002900006d5c0000013d0000001f0530018f00001ba606300198000000400200043d000000000462001900006df40000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00006e420000c13d00006df40000013d00001c1401000041000000000010043f0000001101000039000000040010043f00001c150100004100006e8d00010430000000000001042f00001ba40010009c00001ba401008041000000400110021000001ba40020009c00001ba4020080410000006002200210000000000112019f000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001bcd011001c700008010020000396e8b6e860000040f000000010020019000006e610000613d000000000101043b000000000001042d000000000100001900006e8d0001043000000000050100190000000000200443000000050030008c00006e710000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b00006e690000413d00001ba40030009c00001ba4030080410000006001300210000000000200041400001ba40020009c00001ba402008041000000c002200210000000000112019f00001c8c011001c700000000020500196e8b6e860000040f000000010020019000006e800000613d000000000101043b000000000001042d000000000001042f00006e84002104210000000102000039000000000001042d0000000002000019000000000001042d00006e89002104230000000102000039000000000001042d0000000002000019000000000001042d00006e8b0000043200006e8c0001042e00006e8d000104300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffbf536561706f7274000000000000000000000000000000000000000000000000000200000000000000000000000000000000000007000000000000000000000000312e36000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000030000000000000000000000004f666665724974656d280000000000000000000000000000000000000000000075696e7438206974656d547970652c00000000000000000000000000000000006164647265737320746f6b656e2c00000000000000000000000000000000000075696e74323536206964656e7469666965724f7243726974657269612c00000075696e74323536207374617274416d6f756e742c00000000000000000000000075696e7432353620656e64416d6f756e740000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff5f436f6e73696465726174696f6e4974656d28000000000000000000000000000075696e7432353620656e64416d6f756e742c00000000000000000000000000006164647265737320726563697069656e74000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffe9f6e2c00000000000000000000000000000000000000000000000000000000000075696e7438206f72646572547970652c0000000000000000000000000000000075696e7432353620737461727454696d652c000000000000000000000000000075696e7432353620656e6454696d652c0000000000000000000000000000000062797465733332207a6f6e65486173682c0000000000000000000000000000004f72646572436f6d706f6e656e7473280000000000000000000000000000000061646472657373206f6666657265722c0000000000000000000000000000000075696e743235362073616c742c0000000000000000000000000000000000000061646472657373207a6f6e652c000000000000000000000000000000000000006279746573333220636f6e647569744b65792c000000000000000000000000004f666665724974656d5b5d206f666665722c000000000000000000000000000075696e7432353620636f756e7465720000000000000000000000000000000000436f6e73696465726174696f6e4974656d5b5d20636f6e73696465726174696f000000000000000000000000000000000000000000000000fffffffffffffd9f454950373132446f6d61696e2800000000000000000000000000000000000000737472696e67206e616d652c0000000000000000000000000000000000000000737472696e672076657273696f6e2c000000000000000000000000000000000075696e7432353620636861696e49642c000000000000000000000000000000006164647265737320766572696679696e67436f6e747261637400000000000000000000000000000000000000000000000000000000000000fffffffffffffd1f0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff325d5b325d5b325d5b325d5b325d20747265652900000000000000000000000042756c6b4f72646572284f72646572436f6d706f6e656e74735b325d5b325d5b000000000000000000000000000000000000000000000000ffffffffffffff9f9a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b0200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff3f0a96ad390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000003ca2711d29384747a8f61d60aad3c450405f7aaff5613541dee28df2d6986d32ada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7dbf8e29b89f29ed9b529c154a63038ffca562f8d7cd1e2545dda53a1b582dde30abbb5caa7dda850e60932de0934eb1f9d0f59695050f761dc64e443e5030a56953c6f6856e13104584dd0797ca2b2779202dc2597c6066a42e0d8fe990b0024d101e368776582e57ab3d116ffe2517c0a585cd5b23174b01e275c2d8329c3d83a02eb7ff164c884e5e2c336dc85f81c6a93329d8e9adf214b32729b894de2af139c9d33c18e050dda0aeb9a8086fb16fc12d5d64536780e1da7405a800b0b9f61c19f71958cdd8f081b4c31f7caf5c010b29d12950be2fa1c95070dc47e30b55ca74fab2fece9a1d58234a274220ad05ca096a92ef6a1ca1750b9d90c948955c7ff98d9d4e55d876c5cfac10b43c04039522f3ddfb0ea9bfe70c68cfb5c7cc14bed7be92d41c56f9e59ac7a6272185299b815ddfabc3f25deb51fe55fe2f9e8ad1d97d1ef5eaa37a4ee5fbf234e6f6d64eb511eb562221cd7edfbdde0848da05896c3f349c4da741c19b37fec49ed2e44d738e775a21d9c9860a69d67a3dae53bb98d87cc12922b83759626c5f07d72266da9702d19ffad6a514c73a89002f5fe6ae19322608dd1f8a8d56aab48ed9c28be489b689f4b6c91268563efc85f20e6b5b04cbae4fcb1a9d78e7b2dfc51a36933d023cf6e347e03d517b472a852590d1eb68309202b7106b891e109739dbbd334a1817fe5d6202c939e75cf5e35ca91da3eed3ecef6ebaa6e5023c057ec2c75150693fd0dac5c90f4a142f9879fde8eee9a1392aa395c7002308119a58f2582777a75e54e0c1d5d5437bd2e8bf6222c3939feff011e53ab8c35ca3370aad54c5df1fc2938cd62543174fa6e7d858770efca7572ac20f5ae84db0e2940674f7eca0a4726fa1060ffc2d18cef54b203d5a4f867d3d458dabecad65f6201ceeaba0096df2d0c491cc32e6ea4e6435001780987079d291feebf21c2230e69add0f283cee0b8be492ca8050b4185a2ff7193bd8cff538aba49a9c374c806d277181e9651624b3e31111bc0624574f8bca1d5d6a3f098a0bc373f808c619b1bb4028208721b3c4f8d6bc8a874d659814eb761d51df90cba8de7637ca3e8fe1e3511d1dc2f23487d05dbdecb781860c21ac1c54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f80000000200000000000000000000000000000340000001000000000000000000a61be9f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000220000000000000000000000000000000000000000000000000000000000000000000000000a900866a00000000000000000000000000000000000000000000000000000000f07ec37200000000000000000000000000000000000000000000000000000000f47b773f00000000000000000000000000000000000000000000000000000000f47b774000000000000000000000000000000000000000000000000000000000fb0f3ee100000000000000000000000000000000000000000000000000000000fd9f1e1000000000000000000000000000000000000000000000000000000000f07ec37300000000000000000000000000000000000000000000000000000000f2d12b1200000000000000000000000000000000000000000000000000000000e7acab2300000000000000000000000000000000000000000000000000000000e7acab2400000000000000000000000000000000000000000000000000000000ed98a57400000000000000000000000000000000000000000000000000000000a900866b00000000000000000000000000000000000000000000000000000000b3a34c4c0000000000000000000000000000000000000000000000000000000079df72bc0000000000000000000000000000000000000000000000000000000088147731000000000000000000000000000000000000000000000000000000008814773200000000000000000000000000000000000000000000000000000000a81744040000000000000000000000000000000000000000000000000000000079df72bd0000000000000000000000000000000000000000000000000000000087201b410000000000000000000000000000000000000000000000000000000046423aa60000000000000000000000000000000000000000000000000000000046423aa7000000000000000000000000000000000000000000000000000000005b34b9660000000000000000000000000000000000000000000000000000000006fdde0380000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e0200000200000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff1f000000000000000000000000000000000000000000000000fffffffffffffeff4e487b71000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffe5f0200000000000000000000000000000000000040000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000002000000000000000000000000000000000000200000000000000000000000006bacc01dbe442496068f7d234edd811f1a5f833243e0aec824f86ab861f3c90dfed398fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000022000000000000000001a515574000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffff10fda3e1000000000000000000000000000000000000000000000000000000002165628a00000000000000000000000000000000000000000000000000000000f280791efe782edcf06ce15c8f4dff17601db3b88eb3805a0db7d77faf757f047fa8a98700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000220000000000000000042cbb15ccdc3cad6266b0e7a08c0454b23bf29dc2df74b6f3c209e9336465bd180b41246c05cbb406f874e82aa2faf7db11bba9792fe09929e56ef1eee2c2da30200000200000000000000000000000000000024000000000000000000000000721c20121297512b72821b97f5326877ea8ecf4bb9948fea5bfcb6453074d37f00000000000000000000000000000000000000800000022000000000000000000000000000000000000000000000000000000000000002600000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff40ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000fffffffffffffea0000000000000000000000000000000000000000000000000ffffffffffffffe00000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ffffffffffffff60000000000000000000000000000000000000000000000000fffffffffffffdff796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d9553913221ccfeb700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7000000000000000000000000000000000000000000000000ffffffffffffff20000000000000000000000000000000000000000000000000fffffffffffffffe000000000000000000000000000000000000000000000000ffffffffffffff7f000000000000000000000000000000000000000000000000ffffffffffffffdf9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31000000000000000000000000000000000000000000000000fffffffffffffebf01e4d72a0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000fb5014fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffff0000ee9e0e63000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000010001bc806b960000000000000000000000000000000000000000000000000000000091b3e514000000000000000000000000000000000000000000000000000000008ffff980000000000000000000000000000000000000000000000000000000002020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4701806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b834ce34aa2000000000000000000000000000000000000000000000000000000001cf99b260000000000000000000000000000000000000000000000000000000017b1f942000000000000000000000000000000000000000000000000000000006ab37ce700000000000000000000000000000000000000000000000000000000466aa6160000000000000000000000000000000000000000000000000000000039f3e3fd00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1000000000000000000000000000000000000000000000000ffffffffffffffa07fda727900000000000000000000000000000000000000000000000000000000375c24c1000000000000000000000000000000000000000000000000000000004b9f2d36e1b4c93de62cc077b00b1a91d84b6c31b4a14e012718dcca230689e7bced929d0000000000000000000000000000000000000000000000000000000098e9db6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff8000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000a11b63ff000000000000000000000000000000000000000000000000000000005a052b3200000000000000000000000000000000000000000000000000000000133c37c6000000000000000000000000000000000000000000000000000000006088d7de00000000000000000000000000000000000000000000000000000000bfb3f8ce0000000000000000000000000000000000000000000000000000000009bde3390000000000000000000000000000000000000000000000000000000094eb6af600000000000000000000000000000000000000000000000000000000a8930e9a00000000000000000000000000000000000000000000000000000000d69293320000000000000000000000000000000000000000000000000000000012d3f5a300000000000000000000000000000000000000000000000000000000c63cf089000000000000000000000000000000000000000000000000000000009891976500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7b01000057a627b91c5eda3bbb2ea057376bba86242bfc8b7d1b705328ea56a6709c4d535bdea7cd8a978f128b93471df48c7dbab89d703809115bdc118c235bfd0200000000000000000000000000000000000084000000000000000000000000e5c5e9a3000000000000000000000000000000000000000000000000000000009cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f39f4dd92ce000000000000000000000000000000000000000000000000000000009397928500000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000ffffffffffffff40f242432a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c40000000000000000000000005f15d6720000000000000000000000000000000000000000000000000000000069f958270000000000000000000000000000000000000000000000000000000023b872dd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000a817440400000000000000000000000000000000000000000000000000000000f2d12b1200000000000000000000000000000000000000000000000000000000d5da9a1b00000000000000000000000000000000000000000000000000000000190100000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000001fffffffffffffffff1626ba7e000000000000000000000000000000000000000000000000000000004f7fb80d000000000000000000000000000000000000000000000000000000001f003d0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000815e1d64000000000000000000000000000000000000000000000000000000008baa579f00000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd1efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd98891923000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000000000000000000f486bc870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000a5f54208000000000000000000000000000000000000000000000000000000000200000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036cf21cf339d50a423dd7cd2323b399e4a1b9dbe2136b230750aea542b93d229
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001972ddfa941670a9f5fa2a0094f4490347b99d7b
-----Decoded View---------------
Arg [0] : conduitController (address): 0x1972ddFa941670A9F5fa2A0094f4490347B99D7B
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001972ddfa941670a9f5fa2a0094f4490347b99d7b
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.