Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 3816023 | 325 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
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 Name:
ERC1155MInitializableV1_0_2
Compiler Version
v0.8.24+commit.e11b9ed9
ZkSolc Version
v1.5.11
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.22;
import {
ERC1155SupplyUpgradeable,
ERC1155Upgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol";
import {ERC2981} from "solady/src/tokens/ERC2981.sol";
import {Ownable} from "solady/src/auth/Ownable.sol";
import {ReentrancyGuard} from "solady/src/utils/ReentrancyGuard.sol";
import {MerkleProofLib} from "solady/src/utils/MerkleProofLib.sol";
import {SafeTransferLib} from "solady/src/utils/ext/zksync/SafeTransferLib.sol";
import {MintStageInfo1155} from "contracts/common/Structs.sol";
import {MINT_FEE_RECEIVER} from "contracts/utils/Constants.sol";
import {IERC1155M} from "contracts/nft/erc1155m/interfaces/IERC1155M.sol";
import {ERC1155MStorage} from "contracts/nft/erc1155m/ERC1155MStorage.sol";
import {AuthorizedMinterControl} from "contracts/common/AuthorizedMinterControl.sol";
/// @title ERC1155MInitializableV1_0_2
/// @notice An initializable ERC1155 contract with multi-stage minting, royalties, and authorized minters
/// @dev Implements ERC1155, ERC2981, Ownable, ReentrancyGuard, and custom minting logic
/// @dev ZKsync compatible version
contract ERC1155MInitializableV1_0_2 is
IERC1155M,
ERC1155SupplyUpgradeable,
Ownable,
ReentrancyGuard,
ERC1155MStorage,
ERC2981,
AuthorizedMinterControl
{
/*==============================================================
= INITIALIZERS =
==============================================================*/
/// @dev Disables initializers for the implementation contract.
constructor() {
_disableInitializers();
}
/// @notice Initializes the contract
/// @param name_ The name of the token collection
/// @param symbol_ The symbol of the token collection
/// @param initialOwner The address of the initial owner
/// @param mintFee The mint fee for the contract
function initialize(string calldata name_, string calldata symbol_, address initialOwner, uint256 mintFee)
external
initializer
{
if (initialOwner == address(0)) {
revert InitialOwnerCannotBeZero();
}
name = name_;
symbol = symbol_;
__ERC1155_init("");
_initializeOwner(initialOwner);
_mintFee = mintFee;
}
/*==============================================================
= META =
==============================================================*/
/// @notice Returns the contract name and version
/// @return The contract name and version as strings
function contractNameAndVersion() public pure returns (string memory, string memory) {
return ("ERC1155MInitializable", "1.0.2");
}
/// @notice Gets the contract URI
/// @return The contract URI
function contractURI() external view returns (string memory) {
return _contractURI;
}
/*==============================================================
= MODIFIERS =
==============================================================*/
/// @dev Modifier to check if there's enough supply for minting
/// @param tokenId The ID of the token to mint
/// @param qty The quantity to mint
modifier hasSupply(uint256 tokenId, uint256 qty) {
if (_maxMintableSupply[tokenId] > 0 && totalSupply(tokenId) + qty > _maxMintableSupply[tokenId]) {
revert NoSupplyLeft();
}
_;
}
/*==============================================================
= PUBLIC WRITE METHODS =
==============================================================*/
/// @notice Mints tokens for the caller
/// @param tokenId The ID of the token to mint
/// @param qty The quantity to mint
/// @param limit The minting limit for the caller (used in merkle proofs)
/// @param proof The merkle proof for allowlist minting
function mint(uint256 tokenId, uint32 qty, uint32 limit, bytes32[] calldata proof)
external
payable
virtual
nonReentrant
{
_mintInternal(msg.sender, tokenId, qty, limit, proof);
}
/// @notice Allows authorized minters to mint tokens for a specified address
/// @param to The address to mint tokens for
/// @param tokenId The ID of the token to mint
/// @param qty The quantity to mint
/// @param limit The minting limit for the recipient (used in merkle proofs)
/// @param proof The merkle proof for allowlist minting
function authorizedMint(address to, uint256 tokenId, uint32 qty, uint32 limit, bytes32[] calldata proof)
external
payable
onlyAuthorizedMinter
{
_mintInternal(to, tokenId, qty, limit, proof);
}
/*==============================================================
= PUBLIC VIEW METHODS =
==============================================================*/
/// @notice Gets the stage info, total minted, and stage minted for a specific stage
/// @param stage The stage number
/// @return The stage info, total minted by the caller, and stage minted by the caller
function getStageInfo(uint256 stage)
external
view
override
returns (MintStageInfo1155 memory, uint256[] memory, uint256[] memory)
{
if (stage >= _mintStages.length) {
revert InvalidStage();
}
uint256[] memory walletMinted = totalMintedByAddress(msg.sender);
uint256[] memory stageMinted = _totalMintedByStage(stage);
return (_mintStages[stage], walletMinted, stageMinted);
}
/// @notice Gets the number of minting stages
/// @return The number of minting stages
function getNumberStages() external view override returns (uint256) {
return _mintStages.length;
}
/// @notice Gets the active stage based on a given timestamp
/// @param timestamp The timestamp to check
/// @return The active stage number
function getActiveStageFromTimestamp(uint256 timestamp) public view returns (uint256) {
for (uint256 i = 0; i < _mintStages.length; i++) {
if (timestamp >= _mintStages[i].startTimeUnixSeconds && timestamp < _mintStages[i].endTimeUnixSeconds) {
return i;
}
}
revert InvalidStage();
}
/// @notice Gets the mint fee
/// @return The mint fee
function getMintFee() external view returns (uint256) {
return _mintFee;
}
/// @notice Gets the mint currency address
/// @return The address of the mint currency
function getMintCurrency() external view returns (address) {
return _mintCurrency;
}
/// @notice Gets the maximum mintable supply for a specific token ID
/// @param tokenId The ID of the token
/// @return The maximum mintable supply
function getMaxMintableSupply(uint256 tokenId) external view override returns (uint256) {
return _maxMintableSupply[tokenId];
}
/// @notice Gets the global wallet limit for a specific token ID
/// @param tokenId The ID of the token
/// @return The global wallet limit
function getGlobalWalletLimit(uint256 tokenId) external view override returns (uint256) {
return _globalWalletLimit[tokenId];
}
/// @notice Gets the total minted tokens for each token ID by a specific address
/// @param account The address to check
/// @return An array of total minted tokens for each token ID
function totalMintedByAddress(address account) public view virtual override returns (uint256[] memory) {
uint256[] memory totalMinted = new uint256[](_numTokens);
uint256 numStages = _mintStages.length;
for (uint256 token = 0; token < _numTokens; token++) {
for (uint256 stage = 0; stage < numStages; stage++) {
totalMinted[token] += _stageMintedCountsPerTokenPerWallet[stage][token][account];
}
}
return totalMinted;
}
/// @notice Checks if the contract is setup locked
/// @return Whether the contract is setup locked
function isSetupLocked() external view returns (bool) {
return _setupLocked;
}
/// @notice Checks if the contract is transferable
/// @return Whether the contract is transferable
function isTransferable() public view returns (bool) {
return _transferable;
}
/// @notice Checks if the contract supports a given interface
/// @param interfaceId The interface identifier
/// @return True if the contract supports the interface, false otherwise
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC2981, ERC1155Upgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId)
|| ERC1155Upgradeable.supportsInterface(interfaceId);
}
/*==============================================================
= ADMIN OPERATIONS =
==============================================================*/
/// @notice Sets up the contract with initial parameters
/// @param uri_ The URI for token metadata
/// @param maxMintableSupply Array of maximum mintable supply for each token ID
/// @param globalWalletLimit Array of global wallet limits for each token ID
/// @param mintCurrency The address of the mint currency
/// @param fundReceiver The address to receive funds
/// @param royaltyReceiver The address to receive royalties
/// @param royaltyFeeNumerator The royalty fee numerator
function setup(
string calldata uri_,
uint256[] memory maxMintableSupply,
uint256[] memory globalWalletLimit,
address mintCurrency,
address fundReceiver,
MintStageInfo1155[] calldata initialStages,
address royaltyReceiver,
uint96 royaltyFeeNumerator
) external onlyOwner {
if (_setupLocked) {
revert ContractAlreadySetup();
}
if (maxMintableSupply.length != globalWalletLimit.length) {
revert InvalidLimitArgsLength();
}
for (uint256 i = 0; i < globalWalletLimit.length; i++) {
if (maxMintableSupply[i] > 0 && globalWalletLimit[i] > maxMintableSupply[i]) {
revert GlobalWalletLimitOverflow();
}
}
_setupLocked = true;
_numTokens = globalWalletLimit.length;
_maxMintableSupply = maxMintableSupply;
_globalWalletLimit = globalWalletLimit;
_transferable = true;
_mintCurrency = mintCurrency;
_fundReceiver = fundReceiver;
_setURI(uri_);
if (initialStages.length > 0) {
_setStages(initialStages);
}
if (royaltyReceiver != address(0)) {
setDefaultRoyalty(royaltyReceiver, royaltyFeeNumerator);
_royaltyBps = royaltyFeeNumerator;
_royaltyRecipient = royaltyReceiver;
}
}
/// @notice Sets the mint fee
/// @param mintFee The new mint fee to set
function setMintFee(uint256 mintFee) external onlyOwner {
_mintFee = mintFee;
emit SetMintFee(mintFee);
}
/// @notice Sets the minting stages
/// @param newStages An array of new minting stages
function setStages(MintStageInfo1155[] calldata newStages) external onlyOwner {
_setStages(newStages);
}
/// @notice Sets the minting stages
/// @param newStages An array of new minting stages
function _setStages(MintStageInfo1155[] calldata newStages) internal {
delete _mintStages;
for (uint256 i = 0; i < newStages.length; i++) {
if (i >= 1) {
if (newStages[i].startTimeUnixSeconds < newStages[i - 1].endTimeUnixSeconds + 1) {
revert InsufficientStageTimeGap();
}
}
_assertValidStartAndEndTimestamp(newStages[i].startTimeUnixSeconds, newStages[i].endTimeUnixSeconds);
_assertValidStageArgsLength(newStages[i]);
_mintStages.push(
MintStageInfo1155({
price: newStages[i].price,
walletLimit: newStages[i].walletLimit,
merkleRoot: newStages[i].merkleRoot,
maxStageSupply: newStages[i].maxStageSupply,
startTimeUnixSeconds: newStages[i].startTimeUnixSeconds,
endTimeUnixSeconds: newStages[i].endTimeUnixSeconds
})
);
emit UpdateStage(
i,
newStages[i].price,
newStages[i].walletLimit,
newStages[i].merkleRoot,
newStages[i].maxStageSupply,
newStages[i].startTimeUnixSeconds,
newStages[i].endTimeUnixSeconds
);
}
}
/// @notice Sets the URI for token metadata
/// @param newURI The new URI to set
function setURI(string calldata newURI) external onlyOwner {
_setURI(newURI);
}
/// @notice Sets whether tokens are transferable
/// @param transferable True if tokens should be transferable, false otherwise
function setTransferable(bool transferable) external onlyOwner {
if (_transferable == transferable) revert TransferableAlreadySet();
_transferable = transferable;
emit SetTransferable(transferable);
}
/// @notice Sets the default royalty for the contract
/// @param receiver The address to receive royalties
/// @param feeNumerator The royalty fee numerator
function setDefaultRoyalty(address receiver, uint96 feeNumerator) public onlyOwner {
super._setDefaultRoyalty(receiver, feeNumerator);
_royaltyBps = feeNumerator;
_royaltyRecipient = receiver;
emit DefaultRoyaltySet(receiver, feeNumerator);
}
/// @notice Sets the royalty for a specific token
/// @param tokenId The ID of the token
/// @param receiver The address to receive royalties
/// @param feeNumerator The royalty fee numerator
function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) public onlyOwner {
super._setTokenRoyalty(tokenId, receiver, feeNumerator);
emit TokenRoyaltySet(tokenId, receiver, feeNumerator);
}
/// @notice Sets the maximum mintable supply for a specific token
/// @param tokenId The ID of the token
/// @param maxMintableSupply The new maximum mintable supply
function setMaxMintableSupply(uint256 tokenId, uint256 maxMintableSupply) external virtual onlyOwner {
if (tokenId >= _numTokens) {
revert InvalidTokenId();
}
if (_maxMintableSupply[tokenId] != 0 && maxMintableSupply > _maxMintableSupply[tokenId]) {
revert CannotIncreaseMaxMintableSupply();
}
if (maxMintableSupply < totalSupply(tokenId)) {
revert NewSupplyLessThanTotalSupply();
}
_maxMintableSupply[tokenId] = maxMintableSupply;
emit SetMaxMintableSupply(tokenId, maxMintableSupply);
}
/// @notice Sets the global wallet limit for a specific token
/// @param tokenId The ID of the token
/// @param globalWalletLimit The new global wallet limit
function setGlobalWalletLimit(uint256 tokenId, uint256 globalWalletLimit) external onlyOwner {
if (tokenId >= _numTokens) {
revert InvalidTokenId();
}
if (_maxMintableSupply[tokenId] > 0 && globalWalletLimit > _maxMintableSupply[tokenId]) {
revert GlobalWalletLimitOverflow();
}
_globalWalletLimit[tokenId] = globalWalletLimit;
emit SetGlobalWalletLimit(tokenId, globalWalletLimit);
}
/// @notice Withdraws the contract's balance
function withdraw() external onlyOwner {
(bool success,) = MINT_FEE_RECEIVER.call{value: _totalMintFee}("");
if (!success) revert TransferFailed();
_totalMintFee = 0;
uint256 remainingValue = address(this).balance;
(success,) = _fundReceiver.call{value: remainingValue}("");
if (!success) revert WithdrawFailed();
emit Withdraw(_totalMintFee + remainingValue);
}
/// @notice Withdraws ERC20 tokens from the contract
/// @dev Can only be called by the owner
function withdrawERC20() external onlyOwner {
if (_mintCurrency == address(0)) revert WrongMintCurrency();
uint256 totalFee = _totalMintFee;
uint256 remaining = SafeTransferLib.balanceOf(_mintCurrency, address(this));
if (remaining < totalFee) revert InsufficientBalance();
_totalMintFee = 0;
uint256 totalAmount = totalFee + remaining;
SafeTransferLib.safeTransfer(_mintCurrency, MINT_FEE_RECEIVER, totalFee);
SafeTransferLib.safeTransfer(_mintCurrency, _fundReceiver, remaining);
emit WithdrawERC20(_mintCurrency, totalAmount);
}
/// @notice Allows the owner to mint tokens
/// @param to The address to mint tokens to
/// @param tokenId The ID of the token to mint
/// @param qty The quantity of tokens to mint
function ownerMint(address to, uint256 tokenId, uint32 qty) external onlyOwner hasSupply(tokenId, qty) {
_mint(to, tokenId, qty, "");
}
/// @notice Adds an authorized minter
/// @param minter The address to add as an authorized minter
function addAuthorizedMinter(address minter) external override onlyOwner {
_addAuthorizedMinter(minter);
}
/// @notice Removes an authorized minter
/// @param minter The address to remove as an authorized minter
function removeAuthorizedMinter(address minter) external override onlyOwner {
_removeAuthorizedMinter(minter);
}
/// @notice Sets the contract URI
/// @param contractUri The new contract URI
function setContractURI(string calldata contractUri) external onlyOwner {
_contractURI = contractUri;
emit ContractURIUpdated();
}
/*==============================================================
= INTERNAL HELPERS =
==============================================================*/
/// @dev Internal function to handle minting logic
/// @param to The address to mint tokens for
/// @param tokenId The ID of the token to mint
/// @param qty The quantity to mint
/// @param limit The minting limit for the recipient (used in merkle proofs)
/// @param proof The merkle proof for allowlist minting
function _mintInternal(address to, uint256 tokenId, uint32 qty, uint32 limit, bytes32[] calldata proof)
internal
hasSupply(tokenId, qty)
{
uint256 stageTimestamp = block.timestamp;
uint256 activeStage = getActiveStageFromTimestamp(stageTimestamp);
MintStageInfo1155 memory stage = _mintStages[activeStage];
// Check value if minting with ETH
if (_mintCurrency == address(0) && msg.value < (stage.price[tokenId] + _mintFee) * qty) {
revert NotEnoughValue();
}
// Check stage supply if applicable
if (stage.maxStageSupply[tokenId] > 0) {
if (_stageMintedCountsPerToken[activeStage][tokenId] + qty > stage.maxStageSupply[tokenId]) {
revert StageSupplyExceeded();
}
}
// Check global wallet limit if applicable
if (_globalWalletLimit[tokenId] > 0) {
if (_totalMintedByTokenByAddress(to, tokenId) + qty > _globalWalletLimit[tokenId]) {
revert WalletGlobalLimitExceeded();
}
}
// Check wallet limit for stage if applicable, limit == 0 means no limit enforced
if (stage.walletLimit[tokenId] > 0) {
if (_stageMintedCountsPerTokenPerWallet[activeStage][tokenId][to] + qty > stage.walletLimit[tokenId]) {
revert WalletStageLimitExceeded();
}
}
// Check merkle proof if applicable, merkleRoot == 0x00...00 means no proof required
if (stage.merkleRoot[tokenId] != 0) {
if (!MerkleProofLib.verify(proof, stage.merkleRoot[tokenId], keccak256(abi.encodePacked(to, limit)))) {
revert InvalidProof();
}
// Verify merkle proof mint limit
if (limit > 0 && _stageMintedCountsPerTokenPerWallet[activeStage][tokenId][to] + qty > limit) {
revert WalletStageLimitExceeded();
}
}
if (_mintCurrency != address(0)) {
// ERC20 mint payment
SafeTransferLib.safeTransferFrom(
_mintCurrency, msg.sender, address(this), (stage.price[tokenId] + _mintFee) * qty
);
}
_totalMintFee += _mintFee * qty;
_stageMintedCountsPerTokenPerWallet[activeStage][tokenId][to] += qty;
_stageMintedCountsPerToken[activeStage][tokenId] += qty;
_mint(to, tokenId, qty, "");
}
/// @dev Calculates the total minted tokens for a specific address and token ID
/// @param account The address to check
/// @param tokenId The ID of the token
/// @return The total number of tokens minted for the given address and token ID
function _totalMintedByTokenByAddress(address account, uint256 tokenId) internal view virtual returns (uint256) {
uint256 totalMinted = 0;
uint256 numStages = _mintStages.length;
for (uint256 i = 0; i < numStages; i++) {
totalMinted += _stageMintedCountsPerTokenPerWallet[i][tokenId][account];
}
return totalMinted;
}
/// @dev Calculates the total minted tokens for a given stage
/// @param stage The stage number
/// @return An array of total minted tokens for each token ID in the given stage
function _totalMintedByStage(uint256 stage) internal view virtual returns (uint256[] memory) {
uint256[] memory totalMinted = new uint256[](_numTokens);
for (uint256 token = 0; token < _numTokens; token++) {
totalMinted[token] += _stageMintedCountsPerToken[stage][token];
}
return totalMinted;
}
/// @dev Validates the start and end timestamps for a stage
/// @param start The start timestamp
/// @param end The end timestamp
function _assertValidStartAndEndTimestamp(uint256 start, uint256 end) internal pure {
if (start >= end) revert InvalidStartAndEndTimestamp();
}
/// @dev Validates the length of stage arguments
/// @param stageInfo The stage information to validate
function _assertValidStageArgsLength(MintStageInfo1155 calldata stageInfo) internal view {
if (
stageInfo.price.length != _numTokens || stageInfo.walletLimit.length != _numTokens
|| stageInfo.merkleRoot.length != _numTokens || stageInfo.maxStageSupply.length != _numTokens
) {
revert InvalidStageArgsLength();
}
}
/// @dev Overrides the _beforeTokenTransfer function to add custom logic
/// @param operator The address performing the transfer
/// @param from The address transferring the tokens
/// @param to The address receiving the tokens
/// @param ids The IDs of the tokens being transferred
/// @param amounts The quantities of the tokens being transferred
/// @param data Additional data with no specified format
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
// If the transfer is not from a mint or burn, revert if not transferable
if (from != address(0) && to != address(0) && !_transferable) {
revert NotTransferable();
}
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
/// @dev Overriden to prevent double-initialization of the owner.
function _guardInitializeOwner() internal pure virtual override returns (bool) {
return true;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)
pragma solidity ^0.8.0;
import "../ERC1155Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of ERC1155 that adds tracking of total supply per id.
*
* Useful for scenarios where Fungible and Non-fungible tokens have to be
* clearly identified. Note: While a totalSupply of 1 might mean the
* corresponding is an NFT, there is no guarantees that no other token with the
* same id are not going to be minted.
*/
abstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {
function __ERC1155Supply_init() internal onlyInitializing {
}
function __ERC1155Supply_init_unchained() internal onlyInitializing {
}
mapping(uint256 => uint256) private _totalSupply;
/**
* @dev Total amount of tokens in with a given id.
*/
function totalSupply(uint256 id) public view virtual returns (uint256) {
return _totalSupply[id];
}
/**
* @dev Indicates whether any token exist with a given id, or not.
*/
function exists(uint256 id) public view virtual returns (bool) {
return ERC1155SupplyUpgradeable.totalSupply(id) > 0;
}
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
if (from == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] += amounts[i];
}
}
if (to == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 supply = _totalSupply[id];
require(supply >= amount, "ERC1155: burn amount exceeds totalSupply");
unchecked {
_totalSupply[id] = supply - amount;
}
}
}
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Simple ERC2981 NFT Royalty Standard implementation.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC2981.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/common/ERC2981.sol)
abstract contract ERC2981 {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The royalty fee numerator exceeds the fee denominator.
error RoyaltyOverflow();
/// @dev The royalty receiver cannot be the zero address.
error RoyaltyReceiverIsZeroAddress();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The default royalty info is given by:
/// ```
/// let packed := sload(_ERC2981_MASTER_SLOT_SEED)
/// let receiver := shr(96, packed)
/// let royaltyFraction := xor(packed, shl(96, receiver))
/// ```
///
/// The per token royalty info is given by.
/// ```
/// mstore(0x00, tokenId)
/// mstore(0x20, _ERC2981_MASTER_SLOT_SEED)
/// let packed := sload(keccak256(0x00, 0x40))
/// let receiver := shr(96, packed)
/// let royaltyFraction := xor(packed, shl(96, receiver))
/// ```
uint256 private constant _ERC2981_MASTER_SLOT_SEED = 0xaa4ec00224afccfdb7;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ERC2981 */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Checks that `_feeDenominator` is non-zero.
constructor() {
require(_feeDenominator() != 0, "Fee denominator cannot be zero.");
}
/// @dev Returns the denominator for the royalty amount.
/// Defaults to 10000, which represents fees in basis points.
/// Override this function to return a custom amount if needed.
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
/// @dev Returns true if this contract implements the interface defined by `interfaceId`.
/// See: https://eips.ethereum.org/EIPS/eip-165
/// This function call must use less than 30000 gas.
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
let s := shr(224, interfaceId)
// ERC165: 0x01ffc9a7, ERC2981: 0x2a55205a.
result := or(eq(s, 0x01ffc9a7), eq(s, 0x2a55205a))
}
}
/// @dev Returns the `receiver` and `royaltyAmount` for `tokenId` sold at `salePrice`.
function royaltyInfo(uint256 tokenId, uint256 salePrice)
public
view
virtual
returns (address receiver, uint256 royaltyAmount)
{
uint256 feeDenominator = _feeDenominator();
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, tokenId)
mstore(0x20, _ERC2981_MASTER_SLOT_SEED)
let packed := sload(keccak256(0x00, 0x40))
receiver := shr(96, packed)
if iszero(receiver) {
packed := sload(mload(0x20))
receiver := shr(96, packed)
}
let x := salePrice
let y := xor(packed, shl(96, receiver)) // `feeNumerator`.
// Overflow check, equivalent to `require(y == 0 || x <= type(uint256).max / y)`.
// Out-of-gas revert. Should not be triggered in practice, but included for safety.
returndatacopy(returndatasize(), returndatasize(), mul(y, gt(x, div(not(0), y))))
royaltyAmount := div(mul(x, y), feeDenominator)
}
}
/// @dev Sets the default royalty `receiver` and `feeNumerator`.
///
/// Requirements:
/// - `receiver` must not be the zero address.
/// - `feeNumerator` must not be greater than the fee denominator.
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
uint256 feeDenominator = _feeDenominator();
/// @solidity memory-safe-assembly
assembly {
feeNumerator := shr(160, shl(160, feeNumerator))
if gt(feeNumerator, feeDenominator) {
mstore(0x00, 0x350a88b3) // `RoyaltyOverflow()`.
revert(0x1c, 0x04)
}
let packed := shl(96, receiver)
if iszero(packed) {
mstore(0x00, 0xb4457eaa) // `RoyaltyReceiverIsZeroAddress()`.
revert(0x1c, 0x04)
}
sstore(_ERC2981_MASTER_SLOT_SEED, or(packed, feeNumerator))
}
}
/// @dev Sets the default royalty `receiver` and `feeNumerator` to zero.
function _deleteDefaultRoyalty() internal virtual {
/// @solidity memory-safe-assembly
assembly {
sstore(_ERC2981_MASTER_SLOT_SEED, 0)
}
}
/// @dev Sets the royalty `receiver` and `feeNumerator` for `tokenId`.
///
/// Requirements:
/// - `receiver` must not be the zero address.
/// - `feeNumerator` must not be greater than the fee denominator.
function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator)
internal
virtual
{
uint256 feeDenominator = _feeDenominator();
/// @solidity memory-safe-assembly
assembly {
feeNumerator := shr(160, shl(160, feeNumerator))
if gt(feeNumerator, feeDenominator) {
mstore(0x00, 0x350a88b3) // `RoyaltyOverflow()`.
revert(0x1c, 0x04)
}
let packed := shl(96, receiver)
if iszero(packed) {
mstore(0x00, 0xb4457eaa) // `RoyaltyReceiverIsZeroAddress()`.
revert(0x1c, 0x04)
}
mstore(0x00, tokenId)
mstore(0x20, _ERC2981_MASTER_SLOT_SEED)
sstore(keccak256(0x00, 0x40), or(packed, feeNumerator))
}
}
/// @dev Sets the royalty `receiver` and `feeNumerator` for `tokenId` to zero.
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, tokenId)
mstore(0x20, _ERC2981_MASTER_SLOT_SEED)
sstore(keccak256(0x00, 0x40), 0)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The caller is not authorized to call the function.
error Unauthorized();
/// @dev The `newOwner` cannot be the zero address.
error NewOwnerIsZeroAddress();
/// @dev The `pendingOwner` does not have a valid handover request.
error NoHandoverRequest();
/// @dev Cannot double-initialize.
error AlreadyInitialized();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ownership is transferred from `oldOwner` to `newOwner`.
/// This event is intentionally kept the same as OpenZeppelin's Ownable to be
/// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
/// despite it not being as lightweight as a single argument event.
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
/// @dev An ownership handover to `pendingOwner` has been requested.
event OwnershipHandoverRequested(address indexed pendingOwner);
/// @dev The ownership handover to `pendingOwner` has been canceled.
event OwnershipHandoverCanceled(address indexed pendingOwner);
/// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;
/// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;
/// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The owner slot is given by:
/// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`.
/// It is intentionally chosen to be a high value
/// to avoid collision with lower slots.
/// The choice of manual storage layout is to enable compatibility
/// with both regular and upgradeable contracts.
bytes32 internal constant _OWNER_SLOT =
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;
/// The ownership handover slot of `newOwner` is given by:
/// ```
/// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
/// let handoverSlot := keccak256(0x00, 0x20)
/// ```
/// It stores the expiry timestamp of the two-step ownership handover.
uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Override to return true to make `_initializeOwner` prevent double-initialization.
function _guardInitializeOwner() internal pure virtual returns (bool guard) {}
/// @dev Initializes the owner directly without authorization guard.
/// This function must be called upon initialization,
/// regardless of whether the contract is upgradeable or not.
/// This is to enable generalization to both regular and upgradeable contracts,
/// and to save gas in case the initial owner is not the caller.
/// For performance reasons, this function will not check if there
/// is an existing owner.
function _initializeOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
if sload(ownerSlot) {
mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.
revert(0x1c, 0x04)
}
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Store the new value.
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
} else {
/// @solidity memory-safe-assembly
assembly {
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Store the new value.
sstore(_OWNER_SLOT, newOwner)
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
}
}
/// @dev Sets the owner directly without authorization guard.
function _setOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
}
} else {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.
sstore(ownerSlot, newOwner)
}
}
}
/// @dev Throws if the sender is not the owner.
function _checkOwner() internal view virtual {
/// @solidity memory-safe-assembly
assembly {
// If the caller is not the stored owner, revert.
if iszero(eq(caller(), sload(_OWNER_SLOT))) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Returns how long a two-step ownership handover is valid for in seconds.
/// Override to return a different value if needed.
/// Made internal to conserve bytecode. Wrap it in a public function if needed.
function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
return 48 * 3600;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC UPDATE FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Allows the owner to transfer the ownership to `newOwner`.
function transferOwnership(address newOwner) public payable virtual onlyOwner {
/// @solidity memory-safe-assembly
assembly {
if iszero(shl(96, newOwner)) {
mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
revert(0x1c, 0x04)
}
}
_setOwner(newOwner);
}
/// @dev Allows the owner to renounce their ownership.
function renounceOwnership() public payable virtual onlyOwner {
_setOwner(address(0));
}
/// @dev Request a two-step ownership handover to the caller.
/// The request will automatically expire in 48 hours (172800 seconds) by default.
function requestOwnershipHandover() public payable virtual {
unchecked {
uint256 expires = block.timestamp + _ownershipHandoverValidFor();
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to `expires`.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), expires)
// Emit the {OwnershipHandoverRequested} event.
log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
}
}
/// @dev Cancels the two-step ownership handover to the caller, if any.
function cancelOwnershipHandover() public payable virtual {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), 0)
// Emit the {OwnershipHandoverCanceled} event.
log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
}
}
/// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
/// Reverts if there is no existing ownership handover requested by `pendingOwner`.
function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
let handoverSlot := keccak256(0x0c, 0x20)
// If the handover does not exist, or has expired.
if gt(timestamp(), sload(handoverSlot)) {
mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
revert(0x1c, 0x04)
}
// Set the handover slot to 0.
sstore(handoverSlot, 0)
}
_setOwner(pendingOwner);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC READ FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the owner of the contract.
function owner() public view virtual returns (address result) {
/// @solidity memory-safe-assembly
assembly {
result := sload(_OWNER_SLOT)
}
}
/// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
function ownershipHandoverExpiresAt(address pendingOwner)
public
view
virtual
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
// Compute the handover slot.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
// Load the handover slot.
result := sload(keccak256(0x0c, 0x20))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* MODIFIERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Marks a function as only callable by the owner.
modifier onlyOwner() virtual {
_checkOwner();
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Reentrancy guard mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Unauthorized reentrant call.
error Reentrancy();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Equivalent to: `uint72(bytes9(keccak256("_REENTRANCY_GUARD_SLOT")))`.
/// 9 bytes is large enough to avoid collisions with lower slots,
/// but not too large to result in excessive bytecode bloat.
uint256 private constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* REENTRANCY GUARD */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Guards a function from reentrancy.
modifier nonReentrant() virtual {
/// @solidity memory-safe-assembly
assembly {
if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
mstore(0x00, 0xab143c06) // `Reentrancy()`.
revert(0x1c, 0x04)
}
sstore(_REENTRANCY_GUARD_SLOT, address())
}
_;
/// @solidity memory-safe-assembly
assembly {
sstore(_REENTRANCY_GUARD_SLOT, codesize())
}
}
/// @dev Guards a view function from read-only reentrancy.
modifier nonReadReentrant() virtual {
/// @solidity memory-safe-assembly
assembly {
if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
mstore(0x00, 0xab143c06) // `Reentrancy()`.
revert(0x1c, 0x04)
}
}
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Gas optimized verification of proof of inclusion for a leaf in a Merkle tree.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol)
library MerkleProofLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* MERKLE PROOF VERIFICATION OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`.
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf)
internal
pure
returns (bool isValid)
{
/// @solidity memory-safe-assembly
assembly {
if mload(proof) {
// Initialize `offset` to the offset of `proof` elements in memory.
let offset := add(proof, 0x20)
// Left shift by 5 is equivalent to multiplying by 0x20.
let end := add(offset, shl(5, mload(proof)))
// Iterate over proof elements to compute root hash.
for {} 1 {} {
// Slot of `leaf` in scratch space.
// If the condition is true: 0x20, otherwise: 0x00.
let scratch := shl(5, gt(leaf, mload(offset)))
// Store elements to hash contiguously in scratch space.
// Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes.
mstore(scratch, leaf)
mstore(xor(scratch, 0x20), mload(offset))
// Reuse `leaf` to store the hash to reduce stack operations.
leaf := keccak256(0x00, 0x40)
offset := add(offset, 0x20)
if iszero(lt(offset, end)) { break }
}
}
isValid := eq(leaf, root)
}
}
/// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`.
function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf)
internal
pure
returns (bool isValid)
{
/// @solidity memory-safe-assembly
assembly {
if proof.length {
// Left shift by 5 is equivalent to multiplying by 0x20.
let end := add(proof.offset, shl(5, proof.length))
// Initialize `offset` to the offset of `proof` in the calldata.
let offset := proof.offset
// Iterate over proof elements to compute root hash.
for {} 1 {} {
// Slot of `leaf` in scratch space.
// If the condition is true: 0x20, otherwise: 0x00.
let scratch := shl(5, gt(leaf, calldataload(offset)))
// Store elements to hash contiguously in scratch space.
// Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes.
mstore(scratch, leaf)
mstore(xor(scratch, 0x20), calldataload(offset))
// Reuse `leaf` to store the hash to reduce stack operations.
leaf := keccak256(0x00, 0x40)
offset := add(offset, 0x20)
if iszero(lt(offset, end)) { break }
}
}
isValid := eq(leaf, root)
}
}
/// @dev Returns whether all `leaves` exist in the Merkle tree with `root`,
/// given `proof` and `flags`.
///
/// Note:
/// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length`
/// will always return false.
/// - The sum of the lengths of `proof` and `leaves` must never overflow.
/// - Any non-zero word in the `flags` array is treated as true.
/// - The memory offset of `proof` must be non-zero
/// (i.e. `proof` is not pointing to the scratch space).
function verifyMultiProof(
bytes32[] memory proof,
bytes32 root,
bytes32[] memory leaves,
bool[] memory flags
) internal pure returns (bool isValid) {
// Rebuilds the root by consuming and producing values on a queue.
// The queue starts with the `leaves` array, and goes into a `hashes` array.
// After the process, the last element on the queue is verified
// to be equal to the `root`.
//
// The `flags` array denotes whether the sibling
// should be popped from the queue (`flag == true`), or
// should be popped from the `proof` (`flag == false`).
/// @solidity memory-safe-assembly
assembly {
// Cache the lengths of the arrays.
let leavesLength := mload(leaves)
let proofLength := mload(proof)
let flagsLength := mload(flags)
// Advance the pointers of the arrays to point to the data.
leaves := add(0x20, leaves)
proof := add(0x20, proof)
flags := add(0x20, flags)
// If the number of flags is correct.
for {} eq(add(leavesLength, proofLength), add(flagsLength, 1)) {} {
// For the case where `proof.length + leaves.length == 1`.
if iszero(flagsLength) {
// `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`.
isValid := eq(mload(xor(leaves, mul(xor(proof, leaves), proofLength))), root)
break
}
// The required final proof offset if `flagsLength` is not zero, otherwise zero.
let proofEnd := add(proof, shl(5, proofLength))
// We can use the free memory space for the queue.
// We don't need to allocate, since the queue is temporary.
let hashesFront := mload(0x40)
// Copy the leaves into the hashes.
// Sometimes, a little memory expansion costs less than branching.
// Should cost less, even with a high free memory offset of 0x7d00.
leavesLength := shl(5, leavesLength)
for { let i := 0 } iszero(eq(i, leavesLength)) { i := add(i, 0x20) } {
mstore(add(hashesFront, i), mload(add(leaves, i)))
}
// Compute the back of the hashes.
let hashesBack := add(hashesFront, leavesLength)
// This is the end of the memory for the queue.
// We recycle `flagsLength` to save on stack variables (sometimes save gas).
flagsLength := add(hashesBack, shl(5, flagsLength))
for {} 1 {} {
// Pop from `hashes`.
let a := mload(hashesFront)
// Pop from `hashes`.
let b := mload(add(hashesFront, 0x20))
hashesFront := add(hashesFront, 0x40)
// If the flag is false, load the next proof,
// else, pops from the queue.
if iszero(mload(flags)) {
// Loads the next proof.
b := mload(proof)
proof := add(proof, 0x20)
// Unpop from `hashes`.
hashesFront := sub(hashesFront, 0x20)
}
// Advance to the next flag.
flags := add(flags, 0x20)
// Slot of `a` in scratch space.
// If the condition is true: 0x20, otherwise: 0x00.
let scratch := shl(5, gt(a, b))
// Hash the scratch space and push the result onto the queue.
mstore(scratch, a)
mstore(xor(scratch, 0x20), b)
mstore(hashesBack, keccak256(0x00, 0x40))
hashesBack := add(hashesBack, 0x20)
if iszero(lt(hashesBack, flagsLength)) { break }
}
isValid :=
and(
// Checks if the last value in the queue is same as the root.
eq(mload(sub(hashesBack, 0x20)), root),
// And whether all the proofs are used, if required.
eq(proofEnd, proof)
)
break
}
}
}
/// @dev Returns whether all `leaves` exist in the Merkle tree with `root`,
/// given `proof` and `flags`.
///
/// Note:
/// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length`
/// will always return false.
/// - Any non-zero word in the `flags` array is treated as true.
/// - The calldata offset of `proof` must be non-zero
/// (i.e. `proof` is from a regular Solidity function with a 4-byte selector).
function verifyMultiProofCalldata(
bytes32[] calldata proof,
bytes32 root,
bytes32[] calldata leaves,
bool[] calldata flags
) internal pure returns (bool isValid) {
// Rebuilds the root by consuming and producing values on a queue.
// The queue starts with the `leaves` array, and goes into a `hashes` array.
// After the process, the last element on the queue is verified
// to be equal to the `root`.
//
// The `flags` array denotes whether the sibling
// should be popped from the queue (`flag == true`), or
// should be popped from the `proof` (`flag == false`).
/// @solidity memory-safe-assembly
assembly {
// If the number of flags is correct.
for {} eq(add(leaves.length, proof.length), add(flags.length, 1)) {} {
// For the case where `proof.length + leaves.length == 1`.
if iszero(flags.length) {
// `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`.
// forgefmt: disable-next-item
isValid := eq(
calldataload(
xor(leaves.offset, mul(xor(proof.offset, leaves.offset), proof.length))
),
root
)
break
}
// The required final proof offset if `flagsLength` is not zero, otherwise zero.
let proofEnd := add(proof.offset, shl(5, proof.length))
// We can use the free memory space for the queue.
// We don't need to allocate, since the queue is temporary.
let hashesFront := mload(0x40)
// Copy the leaves into the hashes.
// Sometimes, a little memory expansion costs less than branching.
// Should cost less, even with a high free memory offset of 0x7d00.
calldatacopy(hashesFront, leaves.offset, shl(5, leaves.length))
// Compute the back of the hashes.
let hashesBack := add(hashesFront, shl(5, leaves.length))
// This is the end of the memory for the queue.
// We recycle `flagsLength` to save on stack variables (sometimes save gas).
flags.length := add(hashesBack, shl(5, flags.length))
// We don't need to make a copy of `proof.offset` or `flags.offset`,
// as they are pass-by-value (this trick may not always save gas).
for {} 1 {} {
// Pop from `hashes`.
let a := mload(hashesFront)
// Pop from `hashes`.
let b := mload(add(hashesFront, 0x20))
hashesFront := add(hashesFront, 0x40)
// If the flag is false, load the next proof,
// else, pops from the queue.
if iszero(calldataload(flags.offset)) {
// Loads the next proof.
b := calldataload(proof.offset)
proof.offset := add(proof.offset, 0x20)
// Unpop from `hashes`.
hashesFront := sub(hashesFront, 0x20)
}
// Advance to the next flag offset.
flags.offset := add(flags.offset, 0x20)
// Slot of `a` in scratch space.
// If the condition is true: 0x20, otherwise: 0x00.
let scratch := shl(5, gt(a, b))
// Hash the scratch space and push the result onto the queue.
mstore(scratch, a)
mstore(xor(scratch, 0x20), b)
mstore(hashesBack, keccak256(0x00, 0x40))
hashesBack := add(hashesBack, 0x20)
if iszero(lt(hashesBack, flags.length)) { break }
}
isValid :=
and(
// Checks if the last value in the queue is same as the root.
eq(mload(sub(hashesBack, 0x20)), root),
// And whether all the proofs are used, if required.
eq(proofEnd, proof.offset)
)
break
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EMPTY CALLDATA HELPERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns an empty calldata bytes32 array.
function emptyProof() internal pure returns (bytes32[] calldata proof) {
/// @solidity memory-safe-assembly
assembly {
proof.length := 0
}
}
/// @dev Returns an empty calldata bytes32 array.
function emptyLeaves() internal pure returns (bytes32[] calldata leaves) {
/// @solidity memory-safe-assembly
assembly {
leaves.length := 0
}
}
/// @dev Returns an empty calldata bool array.
function emptyFlags() internal pure returns (bool[] calldata flags) {
/// @solidity memory-safe-assembly
assembly {
flags.length := 0
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import {SingleUseETHVault} from "./SingleUseETHVault.sol";
/// @notice Library for force safe transferring ETH and ERC20s in ZKsync.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/SafeTransferLib.sol)
library SafeTransferLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev A single use ETH vault has been created for `to`, with `amount`.
event SingleUseETHVaultCreated(address indexed to, uint256 amount, address vault);
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ETH transfer has failed.
error ETHTransferFailed();
/// @dev The ERC20 `transferFrom` has failed.
error TransferFromFailed();
/// @dev The ERC20 `transfer` has failed.
error TransferFailed();
/// @dev The ERC20 `approve` has failed.
error ApproveFailed();
/// @dev The ERC20 `totalSupply` query has failed.
error TotalSupplyQueryFailed();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Suggested gas stipend for contract receiving ETH to perform a few
/// storage reads and writes, but low enough to prevent griefing.
uint256 internal constant GAS_STIPEND_NO_GRIEF = 1000000;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ETH OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
// If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
//
// The regular variants:
// - Forwards all remaining gas to the target.
// - Reverts if the target reverts.
// - Reverts if the current contract has insufficient balance.
//
// The force variants:
// - Forwards with an optional gas stipend
// (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
// - If the target reverts, or if the gas stipend is exhausted,
// creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
// Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
// - Reverts if the current contract has insufficient balance.
//
// The try variants:
// - Forwards with a mandatory gas stipend.
// - Instead of reverting, returns whether the transfer succeeded.
/// @dev Sends `amount` (in wei) ETH to `to`.
function safeTransferETH(address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
if iszero(call(gas(), to, amount, 0x00, 0x00, 0x00, 0x00)) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Sends all the ETH in the current contract to `to`.
function safeTransferAllETH(address to) internal {
/// @solidity memory-safe-assembly
assembly {
// Transfer all the ETH and check if it succeeded or not.
if iszero(call(gas(), to, selfbalance(), 0x00, 0x00, 0x00, 0x00)) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
/// If force transfer is used, returns the vault. Else returns `address(0)`.
function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (address vault)
{
if (amount == uint256(0)) return address(0); // Early return if `amount` is zero.
uint256 selfBalanceBefore = address(this).balance;
/// @solidity memory-safe-assembly
assembly {
if lt(selfBalanceBefore, amount) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
pop(call(gasStipend, to, amount, 0x00, 0x00, 0x00, 0x00))
}
if (address(this).balance == selfBalanceBefore) {
vault = address(new SingleUseETHVault());
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, shr(96, shl(96, to)))
if iszero(call(gas(), vault, amount, 0x00, 0x20, 0x00, 0x00)) { revert(0x00, 0x00) }
}
emit SingleUseETHVaultCreated(to, amount, vault);
}
}
/// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
/// If force transfer is used, returns the vault. Else returns `address(0)`.
function forceSafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (address vault)
{
vault = forceSafeTransferETH(to, address(this).balance, gasStipend);
}
/// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
/// If force transfer is used, returns the vault. Else returns `address(0)`.
function forceSafeTransferETH(address to, uint256 amount) internal returns (address vault) {
vault = forceSafeTransferETH(to, amount, GAS_STIPEND_NO_GRIEF);
}
/// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
/// If force transfer is used, returns the vault. Else returns `address(0)`.
function forceSafeTransferAllETH(address to) internal returns (address vault) {
vault = forceSafeTransferETH(to, address(this).balance, GAS_STIPEND_NO_GRIEF);
}
/// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
success := call(gasStipend, to, amount, 0x00, 0x00, 0x00, 0x00)
}
}
/// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
function trySafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
success := call(gasStipend, to, selfbalance(), 0x00, 0x00, 0x00, 0x00)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ERC20 OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
/// Reverts upon failure.
///
/// The `from` account must have at least `amount` approved for
/// the current contract to manage.
function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x60, amount) // Store the `amount` argument.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
///
/// The `from` account must have at least `amount` approved for the current contract to manage.
function trySafeTransferFrom(address token, address from, address to, uint256 amount)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x60, amount) // Store the `amount` argument.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
success := lt(or(iszero(extcodesize(token)), returndatasize()), success)
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends all of ERC20 `token` from `from` to `to`.
/// Reverts upon failure.
///
/// The `from` account must have their entire balance approved for the current contract to manage.
function safeTransferAllFrom(address token, address from, address to)
internal
returns (uint256 amount)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
// Read the balance, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
)
) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
/// Reverts upon failure.
function safeTransfer(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sends all of ERC20 `token` from the current contract to `to`.
/// Reverts upon failure.
function safeTransferAll(address token, address to) internal returns (uint256 amount) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
mstore(0x20, address()) // Store the address of the current contract.
// Read the balance, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
)
) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
mstore(0x14, to) // Store the `to` argument.
amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
/// Reverts upon failure.
function safeApprove(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
/// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
/// then retries the approval again (some tokens, e.g. USDT, requires this).
/// Reverts upon failure.
function safeApproveWithRetry(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
// Perform the approval, retrying upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x34, 0) // Store 0 for the `amount`.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
pop(call(gas(), token, 0, 0x10, 0x44, 0x00, 0x00)) // Reset the approval.
mstore(0x34, amount) // Store back the original `amount`.
// Retry the approval, reverting upon failure.
success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
// Check the `extcodesize` again just in case the token selfdestructs lol.
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
revert(0x1c, 0x04)
}
}
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Returns the amount of ERC20 `token` owned by `account`.
/// Returns zero if the `token` does not exist.
function balanceOf(address token, address account) internal view returns (uint256 amount) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, account) // Store the `account` argument.
mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
amount :=
mul( // The arguments of `mul` are evaluated from right to left.
mload(0x20),
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
)
)
}
}
/// @dev Returns the total supply of the `token`.
/// Reverts if the token does not exist or does not implement `totalSupply()`.
function totalSupply(address token) internal view returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, 0x18160ddd) // `totalSupply()`.
if iszero(
and(gt(returndatasize(), 0x1f), staticcall(gas(), token, 0x1c, 0x04, 0x00, 0x20))
) {
mstore(0x00, 0x54cd9435) // `TotalSupplyQueryFailed()`.
revert(0x1c, 0x04)
}
result := mload(0x00)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
enum TokenStandard {
ERC721,
ERC1155,
ERC20
}
struct MintStageInfo {
uint80 price;
uint32 walletLimit; // 0 for unlimited
bytes32 merkleRoot; // 0x0 for no presale enforced
uint24 maxStageSupply; // 0 for unlimited
uint256 startTimeUnixSeconds;
uint256 endTimeUnixSeconds;
}
struct MintStageInfo1155 {
uint80[] price;
uint32[] walletLimit; // 0 for unlimited
bytes32[] merkleRoot; // 0x0 for no presale enforced
uint24[] maxStageSupply; // 0 for unlimited
uint256 startTimeUnixSeconds;
uint256 endTimeUnixSeconds;
}
struct SetupConfig {
/// @dev The maximum number of tokens that can be minted.
/// - Can be decreased if current supply < new max supply
/// - Cannot be increased once set
uint256 maxSupply;
/// @dev The maximum number of tokens that can be minted per wallet
/// @notice A value of 0 indicates unlimited mints per wallet
uint256 walletLimit;
/// @dev The base URI of the token.
string baseURI;
/// @dev The contract URI of the token.
string contractURI;
/// @dev The mint stages of the token.
MintStageInfo[] stages;
/// @dev The payout recipient of the token.
address payoutRecipient;
/// @dev The royalty recipient of the token.
address royaltyRecipient;
/// @dev The royalty basis points of the token.
uint96 royaltyBps;
/// @dev The mint fee per token.
uint256 mintFee;
}// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E; address constant ME_SUBSCRIPTION = 0x0403c10721Ff2936EfF684Bbb57CD792Fd4b1B6c; address constant MINT_FEE_RECEIVER = 0x0B98151bEdeE73f9Ba5F2C7b72dEa02D38Ce49Fc;
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
import {MintStageInfo1155} from "../../../common/Structs.sol";
import {ERC1155MErrorsAndEvents} from "../ERC1155MErrorsAndEvents.sol";
interface IERC1155M is ERC1155MErrorsAndEvents {
function getNumberStages() external view returns (uint256);
function getGlobalWalletLimit(uint256 tokenId) external view returns (uint256);
function getMaxMintableSupply(uint256 tokenId) external view returns (uint256);
function totalMintedByAddress(address account) external view returns (uint256[] memory);
function getStageInfo(uint256 stage)
external
view
returns (MintStageInfo1155 memory, uint256[] memory, uint256[] memory);
function mint(uint256 tokenId, uint32 qty, uint32 limit, bytes32[] calldata proof) external payable;
function authorizedMint(address to, uint256 tokenId, uint32 qty, uint32 limit, bytes32[] calldata proof)
external
payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
import {MintStageInfo1155} from "contracts/common/Structs.sol";
contract ERC1155MStorage {
// Mint stage information. See MintStageInfo1155 for details.
MintStageInfo1155[] internal _mintStages;
// The name of the token
string public name;
// The symbol of the token
string public symbol;
// Whether the token can be transferred.
bool internal _transferable;
// The total mintable supply per token.
uint256[] internal _maxMintableSupply;
// Global wallet limit, across all stages, per token.
uint256[] internal _globalWalletLimit;
// Total mint fee
uint256 internal _totalMintFee;
// Address of ERC-20 token used to pay for minting. If 0 address, use native currency.
address internal _mintCurrency;
// Number of tokens
uint256 internal _numTokens;
// Fund receiver
address internal _fundReceiver;
// Whether the contract has been setup.
bool internal _setupLocked;
// Royalty recipient
address internal _royaltyRecipient;
// Royalty basis points
uint96 internal _royaltyBps;
// Contract uri
string internal _contractURI;
// Minted count per stage per token per wallet.
mapping(uint256 => mapping(uint256 => mapping(address => uint32))) internal _stageMintedCountsPerTokenPerWallet;
// Minted count per stage per token.
mapping(uint256 => mapping(uint256 => uint256)) internal _stageMintedCountsPerToken;
// Mint fee for each item minted
uint256 internal _mintFee;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
///@title AuthorizedMinterControl
///@dev Abstract contract to manage authorized minters for MagicDrop tokens
abstract contract AuthorizedMinterControl {
/*==============================================================
= STORAGE =
==============================================================*/
mapping(address => bool) private _authorizedMinters;
/*==============================================================
= EVENTS =
==============================================================*/
event AuthorizedMinterAdded(address indexed minter);
event AuthorizedMinterRemoved(address indexed minter);
/*==============================================================
= ERRORS =
==============================================================*/
error NotAuthorized();
/*==============================================================
= MODIFIERS =
==============================================================*/
///@dev Modifier to check if the sender is an authorized minter
modifier onlyAuthorizedMinter() {
if (!_authorizedMinters[msg.sender]) revert NotAuthorized();
_;
}
/*==============================================================
= PUBLIC WRITE METHODS =
==============================================================*/
///@dev Add an authorized minter.
///@dev Please override this function to check if `msg.sender` is authorized
///@param minter Address to be added as an authorized minter
function addAuthorizedMinter(address minter) external virtual;
///@dev Remove an authorized minter.
///@dev Please override this function to check if `msg.sender` is authorized
///@param minter Address to be removed from authorized minters
function removeAuthorizedMinter(address minter) external virtual;
/*==============================================================
= PUBLIC VIEW METHODS =
==============================================================*/
///@dev Check if an address is an authorized minter
///@param minter Address to check
///@return bool True if the address is an authorized minter, false otherwise
function isAuthorizedMinter(address minter) public view returns (bool) {
return _authorizedMinters[minter];
}
/*==============================================================
= INTERNAL HELPERS =
==============================================================*/
///@dev Internal function to add an authorized minter
///@param minter Address to be added as an authorized minter
function _addAuthorizedMinter(address minter) internal {
_authorizedMinters[minter] = true;
emit AuthorizedMinterAdded(minter);
}
///@dev Internal function to remove an authorized minter
///@param minter Address to be removed from authorized minters
function _removeAuthorizedMinter(address minter) internal {
_authorizedMinters[minter] = false;
emit AuthorizedMinterRemoved(minter);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol)
pragma solidity ^0.8.0;
import "./IERC1155Upgradeable.sol";
import "./IERC1155ReceiverUpgradeable.sol";
import "./extensions/IERC1155MetadataURIUpgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/ContextUpgradeable.sol";
import "../../utils/introspection/ERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {
using AddressUpgradeable for address;
// Mapping from token ID to account balances
mapping(uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/**
* @dev See {_setURI}.
*/
function __ERC1155_init(string memory uri_) internal onlyInitializing {
__ERC1155_init_unchained(uri_);
}
function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {
_setURI(uri_);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {
return
interfaceId == type(IERC1155Upgradeable).interfaceId ||
interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: address zero is not a valid owner");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner or approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner or approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `from`
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `amount` tokens of token type `id`.
*/
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `ids` and `amounts` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
/**
* @dev Hook that is called after any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155ReceiverUpgradeable.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non-ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non-ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[47] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice A single-use vault that allows a designated caller to withdraw all ETH in it.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/SingleUseETHVault.sol)
contract SingleUseETHVault {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Unable to withdraw all.
error WithdrawAllFailed();
/// @dev Not authorized.
error Unauthorized();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* WITHDRAW ALL */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
fallback() external payable virtual {
/// @solidity memory-safe-assembly
assembly {
mstore(0x40, 0) // Optimization trick to remove free memory pointer initialization.
let owner := sload(0)
// Initialization.
if iszero(owner) {
sstore(0, calldataload(0x00)) // Store the owner.
return(0x00, 0x00) // Early return.
}
// Authorization check.
if iszero(eq(caller(), owner)) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.
revert(0x1c, 0x04)
}
let to := calldataload(0x00)
// If the calldata is less than 32 bytes, zero-left-pad it to 32 bytes.
// Then use the rightmost 20 bytes of the word as the `to` address.
// This allows for the calldata to be `abi.encode(to)` or `abi.encodePacked(to)`.
to := shr(mul(lt(calldatasize(), 0x20), shl(3, sub(0x20, calldatasize()))), to)
// If `to` is `address(0)`, set it to `msg.sender`.
to := xor(mul(xor(to, caller()), iszero(to)), to)
// Transfers the whole balance to `to`.
if iszero(call(gas(), to, selfbalance(), 0x00, 0x00, 0x00, 0x00)) {
mstore(0x00, 0x651aee10) // `WithdrawAllFailed()`.
revert(0x1c, 0x04)
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
import {ErrorsAndEvents} from "../../common/ErrorsAndEvents.sol";
interface ERC1155MErrorsAndEvents is ErrorsAndEvents {
error InvalidLimitArgsLength();
error InvalidTokenId();
event UpdateStage(
uint256 indexed stage,
uint80[] price,
uint32[] walletLimit,
bytes32[] merkleRoot,
uint24[] maxStageSupply,
uint256 startTimeUnixSeconds,
uint256 endTimeUnixSeconds
);
event SetMintFee(uint256 mintFee);
event SetMaxMintableSupply(uint256 indexed tokenId, uint256 maxMintableSupply);
event SetGlobalWalletLimit(uint256 indexed tokenId, uint256 globalWalletLimit);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155Upgradeable is IERC165Upgradeable {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155ReceiverUpgradeable is IERC165Upgradeable {
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)
pragma solidity ^0.8.0;
import "../IERC1155Upgradeable.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
function __ERC165_init() internal onlyInitializing {
}
function __ERC165_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165Upgradeable).interfaceId;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
interface ErrorsAndEvents {
error CannotIncreaseMaxMintableSupply();
error GlobalWalletLimitOverflow();
error InsufficientStageTimeGap();
error InsufficientBalance();
error InvalidProof();
error InvalidStage();
error InvalidStageArgsLength();
error InvalidStartAndEndTimestamp();
error NoSupplyLeft();
error NotEnoughValue();
error NotMintable();
error Mintable();
error StageSupplyExceeded();
error TransferFailed();
error WalletGlobalLimitExceeded();
error WalletStageLimitExceeded();
error WithdrawFailed();
error WrongMintCurrency();
error NotSupported();
error NewSupplyLessThanTotalSupply();
error NotTransferable();
error InitialOwnerCannotBeZero();
error ContractAlreadySetup();
error TransferableAlreadySet();
event SetMintable(bool mintable);
event SetTransferable(bool transferable);
event SetActiveStage(uint256 activeStage);
event SetBaseURI(string baseURI);
event SetTokenURISuffix(string suffix);
event SetMintCurrency(address mintCurrency);
event Withdraw(uint256 value);
event WithdrawERC20(address mintCurrency, uint256 value);
event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator);
event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator);
event ContractURIUpdated();
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @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 IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"viaIR": true,
"codegen": "yul",
"remappings": [
"solady/=lib/solady/",
"solemate/=/lib/solemate/src/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"forge-std/=lib/forge-std/src/",
"erc721a/contracts/=lib/ERC721A/contracts/",
"erc721a-upgradeable/contracts/=lib/ERC721A-Upgradeable/contracts/",
"@limitbreak/creator-token-standards/src/=lib/creator-token-standards/src/",
"@ensdomains/=node_modules/@ensdomains/",
"@layerzerolabs/=node_modules/@layerzerolabs/",
"@limitbreak/permit-c/=lib/creator-token-standards/lib/PermitC/src/",
"@opensea/tstorish/=lib/creator-token-standards/lib/tstorish/src/",
"@openzeppelin-3/=node_modules/@openzeppelin-3/",
"@rari-capital/solmate/=lib/creator-token-standards/lib/PermitC/lib/solmate/",
"@uniswap/=node_modules/@uniswap/",
"ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
"ERC721A/=lib/ERC721A/contracts/",
"PermitC/=lib/creator-token-standards/lib/PermitC/",
"creator-token-standards/=lib/creator-token-standards/",
"ds-test/=lib/solmate/lib/ds-test/src/",
"erc4626-tests/=lib/operator-filter-registry/lib/openzeppelin-contracts/lib/erc4626-tests/",
"eth-gas-reporter/=node_modules/eth-gas-reporter/",
"forge-gas-metering/=lib/creator-token-standards/lib/PermitC/lib/forge-gas-metering/",
"hardhat-deploy/=node_modules/hardhat-deploy/",
"hardhat/=node_modules/hardhat/",
"murky/=lib/creator-token-standards/lib/murky/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"openzeppelin/=lib/creator-token-standards/lib/PermitC/lib/openzeppelin-contracts/contracts/",
"operator-filter-registry/=lib/operator-filter-registry/",
"solmate/=lib/solmate/src/",
"tstorish/=lib/creator-token-standards/lib/tstorish/src/"
],
"evmVersion": "cancun",
"outputSelection": {
"*": {
"*": [
"abi"
]
}
},
"optimizer": {
"enabled": true,
"mode": "3",
"fallback_to_optimizing_for_size": false,
"disable_system_request_memoization": true
},
"metadata": {},
"libraries": {},
"enableEraVMExtensions": false,
"forceEVMLA": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"CannotIncreaseMaxMintableSupply","type":"error"},{"inputs":[],"name":"ContractAlreadySetup","type":"error"},{"inputs":[],"name":"GlobalWalletLimitOverflow","type":"error"},{"inputs":[],"name":"InitialOwnerCannotBeZero","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InsufficientStageTimeGap","type":"error"},{"inputs":[],"name":"InvalidLimitArgsLength","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidStage","type":"error"},{"inputs":[],"name":"InvalidStageArgsLength","type":"error"},{"inputs":[],"name":"InvalidStartAndEndTimestamp","type":"error"},{"inputs":[],"name":"InvalidTokenId","type":"error"},{"inputs":[],"name":"Mintable","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NewSupplyLessThanTotalSupply","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"NoSupplyLeft","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"NotEnoughValue","type":"error"},{"inputs":[],"name":"NotMintable","type":"error"},{"inputs":[],"name":"NotSupported","type":"error"},{"inputs":[],"name":"NotTransferable","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[],"name":"RoyaltyOverflow","type":"error"},{"inputs":[],"name":"RoyaltyReceiverIsZeroAddress","type":"error"},{"inputs":[],"name":"StageSupplyExceeded","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TransferableAlreadySet","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"WalletGlobalLimitExceeded","type":"error"},{"inputs":[],"name":"WalletStageLimitExceeded","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"inputs":[],"name":"WrongMintCurrency","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"AuthorizedMinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"AuthorizedMinterRemoved","type":"event"},{"anonymous":false,"inputs":[],"name":"ContractURIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"DefaultRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"activeStage","type":"uint256"}],"name":"SetActiveStage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"SetBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"globalWalletLimit","type":"uint256"}],"name":"SetGlobalWalletLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxMintableSupply","type":"uint256"}],"name":"SetMaxMintableSupply","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"mintCurrency","type":"address"}],"name":"SetMintCurrency","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mintFee","type":"uint256"}],"name":"SetMintFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"mintable","type":"bool"}],"name":"SetMintable","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"suffix","type":"string"}],"name":"SetTokenURISuffix","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"transferable","type":"bool"}],"name":"SetTransferable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"TokenRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stage","type":"uint256"},{"indexed":false,"internalType":"uint80[]","name":"price","type":"uint80[]"},{"indexed":false,"internalType":"uint32[]","name":"walletLimit","type":"uint32[]"},{"indexed":false,"internalType":"bytes32[]","name":"merkleRoot","type":"bytes32[]"},{"indexed":false,"internalType":"uint24[]","name":"maxStageSupply","type":"uint24[]"},{"indexed":false,"internalType":"uint256","name":"startTimeUnixSeconds","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTimeUnixSeconds","type":"uint256"}],"name":"UpdateStage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"mintCurrency","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"WithdrawERC20","type":"event"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"addAuthorizedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"qty","type":"uint32"},{"internalType":"uint32","name":"limit","type":"uint32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"authorizedMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"contractNameAndVersion","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getActiveStageFromTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getGlobalWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getMaxMintableSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMintCurrency","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberStages","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stage","type":"uint256"}],"name":"getStageInfo","outputs":[{"components":[{"internalType":"uint80[]","name":"price","type":"uint80[]"},{"internalType":"uint32[]","name":"walletLimit","type":"uint32[]"},{"internalType":"bytes32[]","name":"merkleRoot","type":"bytes32[]"},{"internalType":"uint24[]","name":"maxStageSupply","type":"uint24[]"},{"internalType":"uint256","name":"startTimeUnixSeconds","type":"uint256"},{"internalType":"uint256","name":"endTimeUnixSeconds","type":"uint256"}],"internalType":"struct MintStageInfo1155","name":"","type":"tuple"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"uint256","name":"mintFee","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"isAuthorizedMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSetupLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTransferable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"qty","type":"uint32"},{"internalType":"uint32","name":"limit","type":"uint32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"qty","type":"uint32"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"removeAuthorizedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"contractUri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"globalWalletLimit","type":"uint256"}],"name":"setGlobalWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"maxMintableSupply","type":"uint256"}],"name":"setMaxMintableSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintFee","type":"uint256"}],"name":"setMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint80[]","name":"price","type":"uint80[]"},{"internalType":"uint32[]","name":"walletLimit","type":"uint32[]"},{"internalType":"bytes32[]","name":"merkleRoot","type":"bytes32[]"},{"internalType":"uint24[]","name":"maxStageSupply","type":"uint24[]"},{"internalType":"uint256","name":"startTimeUnixSeconds","type":"uint256"},{"internalType":"uint256","name":"endTimeUnixSeconds","type":"uint256"}],"internalType":"struct MintStageInfo1155[]","name":"newStages","type":"tuple[]"}],"name":"setStages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"transferable","type":"bool"}],"name":"setTransferable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newURI","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"},{"internalType":"uint256[]","name":"maxMintableSupply","type":"uint256[]"},{"internalType":"uint256[]","name":"globalWalletLimit","type":"uint256[]"},{"internalType":"address","name":"mintCurrency","type":"address"},{"internalType":"address","name":"fundReceiver","type":"address"},{"components":[{"internalType":"uint80[]","name":"price","type":"uint80[]"},{"internalType":"uint32[]","name":"walletLimit","type":"uint32[]"},{"internalType":"bytes32[]","name":"merkleRoot","type":"bytes32[]"},{"internalType":"uint24[]","name":"maxStageSupply","type":"uint24[]"},{"internalType":"uint256","name":"startTimeUnixSeconds","type":"uint256"},{"internalType":"uint256","name":"endTimeUnixSeconds","type":"uint256"}],"internalType":"struct MintStageInfo1155[]","name":"initialStages","type":"tuple[]"},{"internalType":"address","name":"royaltyReceiver","type":"address"},{"internalType":"uint96","name":"royaltyFeeNumerator","type":"uint96"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"totalMintedByAddress","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
3cda3351ab66c31281be63f79c25e30ef51a6293b25eea4a86beb47b323525497c4612af0100098532c62f00d004f78aa12b754df0c31d39fc023cba20392d4c8cef50fa00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x00040000000000020012000000000002000000000302001900000060021002700000088b0020019d0000088b02200197000300000021035500020000000103550000008004000039000000400040043f00000001003001900000003f0000c13d000000040020008c000015f90000413d000000000301043b000000e003300270000008930030009c000000680000a13d000008940030009c000000b60000213d000008a60030009c000001490000a13d000008a70030009c000001860000a13d000008a80030009c000002b40000213d000008ab0030009c000004740000613d000008ac0030009c000015f90000c13d000000440020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000402100370000000000202043b000f00000002001d000008d80020009c000015f90000213d0000002401100370000000000201043b000000000002004b0000000001000039000000010100c039000e00000002001d000000000012004b000015f90000c13d00000000020004110000000f0020006c000009eb0000c13d0000088c01000041000000800010043f0000002001000039000000840010043f0000002901000039000000a40010043f0000092401000041000000c40010043f0000092501000041000000e40010043f0000088f010000410000222a000104300000000001000416000000000001004b000015f90000c13d000000000100041a0000ff00001001900000005c0000c13d000000ff0210018f000000ff0020008c000000570000613d000000ff011001bf000000000010041b000000ff01000039000000800010043f00000000010004140000088b0010009c0000088b01008041000000c00110021000000890011001c70000800d02000039000000010300003900000891040000412228221e0000040f0000000100200190000015f90000613d0000002001000039000001000010044300000120000004430000089201000041000022290001042e0000088c01000041000000800010043f0000002001000039000000840010043f0000002701000039000000a40010043f0000088d01000041000000c40010043f0000088e01000041000000e40010043f0000088f010000410000222a00010430000008b70030009c000000d10000a13d000008b80030009c000000f00000a13d000008b90030009c000001650000a13d000008ba0030009c000002ab0000213d000008bd0030009c000003730000613d000008be0030009c000015f90000c13d000000640020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000402100370000000000202043b000e00000002001d0000002402100370000000000202043b000f00000002001d000008d80020009c000015f90000213d0000004401100370000000000101043b000009170010009c000015f90000213d000008e902000041000000000202041a0000000003000411000000000023004b000017700000c13d0000091701100197000027100010008c000006b30000213d000d00000001001d0000000f0000006b00000ab10000613d0000000e01000029000000000010043f0000091f01000041000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d0000000f0600002900000060026002100000000d03000029000000000223019f000000000101043b000000000021041b000000400100043d00000000003104350000088b0010009c0000088b01008041000000400110021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ee011001c70000800d0200003900000003030000390000092c040000410000000e050000292228221e0000040f00000001002001900000076c0000c13d000015f90000013d000008950030009c000001560000a13d000008960030009c000001950000a13d000008970030009c000003600000213d0000089a0030009c000004930000613d0000089b0030009c000015f90000c13d000000240020008c000015f90000413d0000000401100370000000000101043b000008d80010009c000015f90000213d000008e902000041000000000202041a0000000003000411000000000023004b000017700000c13d000000000001004b00000b1c0000c13d000008f301000041000000000010043f000008eb010000410000222a00010430000008c90030009c000001080000213d000008d10030009c000001ca0000213d000008d50030009c0000067d0000613d000008d60030009c0000076e0000613d000008d70030009c000015f90000c13d000000240020008c000015f90000413d0000000003000416000000000003004b000015f90000c13d0000000401100370000000000101043b000008db0010009c000015f90000213d0000000401100039222817840000040f000f00000001001d000e00000002001d22281af70000040f00000000030000310000000f010000290000000e02000029222817e80000040f22281b010000040f0000000001000019000022290001042e000008c20030009c0000017b0000213d000008c60030009c000003df0000613d000008c70030009c000004eb0000613d000008c80030009c000015f90000c13d0000000001000416000000000001004b000015f90000c13d000008e901000041000000000101041a0000000002000411000000000012004b000017700000c13d000000d001000039000000000101041a000008d8021001980000082d0000c13d0000094401000041000000800010043f00000902010000410000222a00010430000008ca0030009c000001f10000213d000008ce0030009c0000068b0000613d000008cf0030009c000007840000613d000008d00030009c000015f90000c13d000000a40020008c000015f90000413d0000000403100370000000000303043b000f00000003001d000008d80030009c000015f90000213d0000004403100370000000000303043b000e00000003001d0000088b0030009c000015f90000213d0000006403100370000000000303043b0000088b0030009c000015f90000213d0000008403100370000000000303043b000008db0030009c000015f90000213d0000002304300039000000000024004b000015f90000813d0000000404300039000000000141034f000000000101043b000900000001001d000008db0010009c000015f90000213d000000240130003900000009030000290000000503300210000800000001001d000600000003001d000700000013001d000000070020006b000015f90000213d0000000001000411000000000010043f000000d801000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a000000ff0010019000000d170000c13d000000400100043d0000095e020000410000094b0000013d000008b00030009c000002410000213d000008b40030009c000006df0000613d000008b50030009c000007ce0000613d000008b60030009c000015f90000c13d0000000001000416000000000001004b000015f90000c13d000000d701000039000007020000013d0000089f0030009c000002830000213d000008a30030009c000006f50000613d000008a40030009c000007dd0000613d000008a50030009c000015f90000c13d0000000001000416000000000001004b000015f90000c13d000000d201000039000000000101041a00000912001001980000078a0000013d000008bf0030009c000003b50000613d000008c00030009c0000041b0000613d000008c10030009c000015f90000c13d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b000000000010043f0000009701000039000000200010043f00000040020000390000000001000019222821f20000040f000000000101041a000000000001004b0000078a0000013d000008c30030009c000003ed0000613d000008c40030009c000005cb0000613d000008c50030009c000015f90000c13d0000000001000416000000000001004b000015f90000c13d000000d001000039000007fe0000013d000008ad0030009c000006430000613d000008ae0030009c000007420000613d000008af0030009c000015f90000c13d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b222818700000040f000003e70000013d0000089c0030009c000006620000613d0000089d0030009c000007520000613d0000089e0030009c000015f90000c13d000000240020008c000015f90000413d0000000401100370000000000101043b000f00000001001d000008d80010009c000015f90000213d000008e901000041000000000101041a0000000002000411000000000012004b000017700000c13d000008d9010000410000000c0010043f0000000f01000029000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008fb011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000d00000001001d000000000101041a000e00000001001d000008fc01000041000000000010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008fd011001c70000800b02000039222822230000040f0000000100200190000016a90000613d000000000101043b0000000e0010006c00000b190000a13d000008fe01000041000000000010043f000008eb010000410000222a00010430000008d20030009c0000069e0000613d000008d30030009c0000078f0000613d000008d40030009c000015f90000c13d000000240020008c000015f90000413d0000000001000416000000000001004b000015f90000c13d0000006703000039000000000203041a000000010420019000000001012002700000007f0110618f0000001f0010008c00000000050000390000000105002039000000000552013f0000000100500190000008120000c13d000000800010043f000000000004004b000008180000613d000000000030043f000000000001004b000009470000613d000008e70200004100000000040000190000000003040019000000000402041a000000a005300039000000000045043500000001022000390000002004300039000000000014004b000001e80000413d00000a280000013d000008cb0030009c000006b70000613d000008cc0030009c000007ad0000613d000008cd0030009c000015f90000c13d000000440020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000002402100370000000000202043b000f00000002001d0000000401100370000000000101043b000000000010043f0000091f01000041000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a000009170020009c000002130000213d0000091f01000041000000000201041a00000917012001980000000003000019000000010300c08a000000000313c0d90000000f0030006b0000000003000019000000000301201900000001040000310000000005430019000000000045004b000015f90000213d00000965053001980000001f0630018f00000003074003670000000003540019000002280000613d000000000807034f000000008908043c0000000004940436000000000034004b000002240000c13d0000006002200270000000000006004b000002360000613d000000000457034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f00000000004304350000000f011000b9000027100110011a000000400300043d0000002004300039000000000014043500000000002304350000088b0030009c0000088b03008041000000400130021000000950011001c7000022290001042e000008b10030009c000007060000613d000008b20030009c000007fa0000613d000008b30030009c000015f90000c13d000000240020008c000015f90000413d0000000003000416000000000003004b000015f90000c13d0000000403100370000000000403043b000008db0040009c000015f90000213d0000002303400039000000000023004b000015f90000813d0000000405400039000000000351034f000000000303043b000008db0030009c000015f90000213d00000024044000390000000006430019000000000026004b000015f90000213d000008e902000041000000000202041a0000000006000411000000000026004b000017700000c13d000000d402000039000000000702041a000000010070019000000001067002700000007f0660618f0000001f0060008c00000000080000390000000108002039000000000787013f0000000100700190000008120000c13d000000200060008c0000027c0000413d0000001f073000390000000507700270000009290770009a000000200030008c00000905070040410000001f066000390000000506600270000009290660009a000000000067004b0000027c0000813d000000000007041b0000000107700039000000000067004b000002780000413d0000001f0030008c00000b6a0000a13d000009650630019800000c6e0000c13d0000090505000041000000000700001900000c780000013d000008a00030009c000007160000613d000008a10030009c000008030000613d000008a20030009c000015f90000c13d000000440020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000002402100370000000000402043b0000000401100370000000000301043b000008e901000041000000000101041a0000000002000411000000000012004b000017700000c13d000000d101000039000000000101041a000000000013004b000008200000813d000000cd02000039000000000102041a000000000031004b0000164e0000a13d000009000130009a000e00000001001d000000000101041a000000000001004b00000a3c0000613d000000000020043f000000000014004b00000a3c0000a13d0000090101000041000000800010043f00000902010000410000222a00010430000008bb0030009c0000038b0000613d000008bc0030009c000015f90000c13d0000000001000416000000000001004b000015f90000c13d000000c901000039000007020000013d000008a90030009c000005dd0000613d000008aa0030009c000015f90000c13d000001040020008c000015f90000413d0000000003000416000000000003004b000015f90000c13d0000000403100370000000000303043b000008db0030009c000015f90000213d0000002305300039000000000025004b000015f90000813d0000000405300039000000000551034f000000000505043b000008db0050009c000015f90000213d00000024063000390000000003650019000000000023004b000015f90000213d0000002403100370000000000303043b000008db0030009c000015f90000213d0000002307300039000000000027004b000015f90000813d0000000407300039000000000771034f000000000807043b000008db0080009c000005f80000213d00000005078002100000003f097000390000090d09900197000008f40090009c000005f80000213d0000008009900039000000400090043f000000800080043f00000024033000390000000007370019000000000027004b000015f90000213d000000000008004b000002ee0000613d000000000831034f000000000808043b000000200440003900000000008404350000002003300039000000000073004b000002e70000413d0000004403100370000000000303043b000008db0030009c000015f90000213d0000002304300039000000000024004b000000000700001900000916070080410000091604400197000000000004004b00000000080000190000091608004041000009160040009c000000000807c019000000000008004b000015f90000c13d0000000404300039000000000441034f000000000404043b000008db0040009c000005f80000213d00000005084002100000003f078000390000090d09700197000000400700043d0000000009970019000000000079004b000000000a000039000000010a004039000008db0090009c000005f80000213d0000000100a00190000005f80000c13d000000400090043f000000000b47043600000024033000390000000008380019000000000028004b000015f90000213d000000000004004b0000031f0000613d0000000004070019000000000931034f000000000909043b000000200440003900000000009404350000002003300039000000000083004b000003180000413d0000006403100370000000000903043b000008d80090009c000015f90000213d0000008403100370000000000803043b000008d80080009c000015f90000213d000000a403100370000000000403043b000008db0040009c000015f90000213d0000002303400039000000000023004b000000000a000019000009160a0080410000091603300197000000000003004b000000000c000019000009160c004041000009160030009c000000000c0ac01900000000000c004b000015f90000c13d0000000403400039000000000331034f000000000303043b000008db0030009c000015f90000213d0000002404400039000000050a300210000000000a4a001900000000002a004b000015f90000213d000000c402100370000000000202043b000008d80020009c000015f90000213d000000e40a100370000000000a0a043b0000091700a0009c000015f90000213d000008e90a000041000000000c0a041a000000000a000411000f0000000c001d0000000000ca004b000017700000c13d000000d20a000039000000000d0a041a0000091200d001980000134f0000c13d000000000a070433000000800c00043d0000000000ac004b0000146a0000c13d00000000000c004b000014d30000c13d0000091b0ad001970000091c0aa001c7000000d20b0000390000000000ab041b000000d10a00003900000000000a041b000015310000013d000008980030009c000005fe0000613d000008990030009c000015f90000c13d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b000008d80010009c000015f90000213d000008d9020000410000000c0020043f000000000010043f0000000c010000390000002002000039000007010000013d000008d9010000410000000c0010043f0000000001000411000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008fb011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000001041b00000000010004140000088b0010009c0000088b01008041000000c001100210000008ec011001c70000800d0200003900000002030000390000092d04000041000006dd0000013d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b000f00000001001d000008d80010009c000015f90000213d000008e901000041000000000101041a0000000002000411000000000012004b000017700000c13d0000000f01000029000000000010043f000000d801000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a000009660220019700000001022001bf000000000021041b00000000010004140000088b0010009c0000088b01008041000000c001100210000008ec011001c70000800d0200003900000002030000390000092b04000041000003dd0000013d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b000f00000001001d000008d80010009c000015f90000213d000008e901000041000000000101041a0000000002000411000000000012004b000017700000c13d0000000f01000029000000000010043f000000d801000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a0000096602200197000000000021041b00000000010004140000088b0010009c0000088b01008041000000c001100210000008ec011001c70000800d02000039000000020300003900000933040000410000000f05000029000007690000013d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b222818620000040f0000000302200210000000000101041a000000000121022f000000ff0020008c0000000001002019000007d60000013d000000640020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000402100370000000000202043b000f00000002001d000008d80020009c000015f90000213d0000002402100370000000000202043b000e00000002001d0000004401100370000000000101043b000d00000001001d0000088b0010009c000015f90000213d000008e901000041000000000101041a0000000002000411000000000012004b000017700000c13d000000cd03000039000000000103041a0000000e02000029000000000021004b0000164e0000a13d000000000030043f000009000120009a000c00000001001d000000000101041a000000000001004b00000b1f0000c13d00000080030000390000000001030019000c00000003001d2228179e0000040f0000000c0400002900000000000404350000000f010000290000000e020000290000000d03000029222820310000040f0000000001000019000022290001042e000000440020008c000015f90000413d0000000003000416000000000003004b000015f90000c13d0000000403100370000000000303043b000008db0030009c000015f90000213d0000002304300039000000000024004b000015f90000813d0000000404300039000000000441034f000000000504043b000008db0050009c000005f80000213d00000005045002100000003f064000390000090d06600197000008f40060009c000005f80000213d0000008006600039000000400060043f000000800050043f00000024033000390000000004340019000000000024004b000015f90000213d000000000005004b000004430000613d000000a005000039000000000631034f000000000606043b000008d80060009c000015f90000213d00000000056504360000002003300039000000000043004b0000043b0000413d0000002403100370000000000303043b000008db0030009c000015f90000213d0000002304300039000000000024004b000000000500001900000916050040410000091604400197000000000004004b00000000060000190000091606002041000009160040009c000000000605c019000000000006004b000015f90000613d0000000404300039000000000441034f000000000404043b000008db0040009c000005f80000213d00000005054002100000003f065000390000090d06600197000000400700043d0000000006670019000c00000007001d000000000076004b00000000070000390000000107004039000008db0060009c000005f80000213d0000000100700190000005f80000c13d000000400060043f0000000c060000290000000006460436000b00000006001d00000024033000390000000005350019000000000025004b000015f90000213d000000000004004b00000d970000c13d000000800300043d000000000003004b000000000300001900000da60000613d00000dcb0000013d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b000000000001004b0000000002000039000000010200c039000000000021004b000015f90000c13d000008e902000041000000000202041a0000000003000411000000000023004b000017700000c13d000000000001004b0000000004000039000000010400c039000000cc02000039000000000302041a000000ff0030019000000000050000390000000105006039000000000054004b000009de0000613d0000092701000041000000800010043f00000902010000410000222a00010430000000a40020008c000015f90000413d0000000003000416000000000003004b000015f90000c13d0000000403100370000000000303043b000900000003001d000008d80030009c000015f90000213d0000002403100370000000000303043b000800000003001d000008d80030009c000015f90000213d0000006403100370000000000303043b000600000003001d0000004403100370000000000303043b000700000003001d0000008403100370000000000403043b000008db0040009c000015f90000213d0000002303400039000000000023004b000015f90000813d0000000405400039000000000351034f000000000303043b000008db0030009c000005f80000213d0000001f0630003900000965066001970000003f066000390000096506600197000008f40060009c000005f80000213d00000024044000390000008006600039000000400060043f000000800030043f0000000004430019000000000024004b000015f90000213d0000002002500039000000000221034f00000965043001980000001f0530018f000000a001400039000004cd0000613d000000a006000039000000000702034f000000007807043c0000000006860436000000000016004b000004c90000c13d000000000005004b000004da0000613d000000000242034f0000000304500210000000000501043300000000054501cf000000000545022f000000000202043b0000010004400089000000000242022f00000000024201cf000000000252019f0000000000210435000000a00130003900000000000104350000000002000411000000090020006b00000c8f0000c13d000000080000006b00000cd20000c13d000000400100043d00000064021000390000094e03000041000000000032043500000044021000390000094f0300004100000000003204350000002402100039000000250300003900000dd40000013d000000a40020008c000015f90000413d0000000003000416000000000003004b000015f90000c13d0000000403100370000000000303043b000008d80030009c000015f90000213d0000002404100370000000000404043b000b00000004001d000008d80040009c000015f90000213d0000004404100370000000000404043b000008db0040009c000015f90000213d0000002305400039000000000025004b000015f90000813d0000000405400039000000000551034f000000000605043b000008db0060009c000005f80000213d00000005056002100000003f075000390000090d07700197000008f40070009c000005f80000213d0000008007700039000000400070043f000000800060043f00000024044000390000000005450019000000000025004b000015f90000213d000000000006004b0000051b0000613d0000008006000039000000000741034f000000000707043b000000200660003900000000007604350000002004400039000000000054004b000005140000413d0000006404100370000000000404043b000008db0040009c000015f90000213d0000002305400039000000000025004b000000000600001900000916060080410000091605500197000000000005004b00000000070000190000091607004041000009160050009c000000000706c019000000000007004b000015f90000c13d0000000405400039000000000551034f000000000505043b000008db0050009c000005f80000213d00000005065002100000003f076000390000090d07700197000000400800043d0000000007780019000d00000008001d000000000087004b00000000080000390000000108004039000008db0070009c000005f80000213d0000000100800190000005f80000c13d000000400070043f0000000d070000290000000007570436000c00000007001d00000024044000390000000006460019000000000026004b000015f90000213d000000000005004b0000054f0000613d0000000d05000029000000000741034f000000000707043b000000200550003900000000007504350000002004400039000000000064004b000005480000413d0000008404100370000000000504043b000008db0050009c000015f90000213d0000002304500039000000000024004b000000000600001900000916060080410000091604400197000000000004004b00000000070000190000091607004041000009160040009c000000000706c019000000000007004b000015f90000c13d0000000406500039000000000461034f000000000404043b000008db0040009c000005f80000213d0000001f0740003900000965077001970000003f077000390000096507700197000000400800043d0000000007780019000600000008001d000000000087004b00000000080000390000000108004039000008db0070009c000005f80000213d0000000100800190000005f80000c13d0000002405500039000000400070043f00000006070000290000000007470436000500000007001d0000000005540019000000000025004b000015f90000213d0000002002600039000000000221034f00000965054001980000001f0640018f0000000501500029000005860000613d000000000702034f0000000508000029000000007907043c0000000008980436000000000018004b000005820000c13d000000000006004b000005930000613d000000000252034f0000000305600210000000000601043300000000065601cf000000000656022f000000000202043b0000010005500089000000000252022f00000000025201cf000000000262019f000000000021043500000005014000290000000000010435000a08d80030019b00000000010004110000000a0010006b000010370000c13d0000000d010000290000000002010433000000800100043d000000000021004b0000112a0000c13d0000000b02000029000708d80020019c000004e10000613d0000000a0000006b0000117a0000c13d000000000001004b0000000d02000029000011810000613d00000000030000190000000001020433000000000031004b0000164e0000a13d000f00000003001d00000005013002100000000c021000290000000002020433000e00000002001d000000a0011000390000000001010433000000000010043f0000009701000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a0000000e03000029000000000032001a000017190000413d0000000002320019000000000021041b0000000f030000290000000103300039000000800100043d000000000013004b0000000d02000029000005a70000413d0000117f0000013d0000000001000416000000000001004b000015f90000c13d000008e901000041000000000101041a0000000002000411000000000012004b000017700000c13d000000cf01000039000000000301041a00000000010004140000088b0010009c0000088b01008041000000c001100210000000000003004b000008650000c13d0000093402000041000008690000013d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000201043b0000014001000039000000400010043f0000006001000039000000800010043f000000a00010043f000000c00010043f000000e00010043f000001000000043f000001200000043f000000c901000039000000000101041a000e00000002001d000000000012004b0000081c0000813d00000000010004112228189c0000040f000000d102000039000000000602041a000008db0060009c000008b30000a13d0000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a00010430000000840020008c000015f90000413d0000000003000416000000000003004b000015f90000c13d0000000403100370000000000303043b000008db0030009c000015f90000213d0000002304300039000000000024004b000015f90000813d0000000404300039000000000441034f000000000404043b000f00000004001d000008db0040009c000015f90000213d0000002404300039000e00000004001d0000000f03400029000000000023004b000015f90000213d0000002403100370000000000303043b000008db0030009c000015f90000213d0000002304300039000000000024004b000015f90000813d0000000404300039000000000441034f000000000404043b000d00000004001d000008db0040009c000015f90000213d0000002404300039000c00000004001d0000000d03400029000000000023004b000015f90000213d0000004401100370000000000101043b000b00000001001d000008d80010009c000015f90000213d0000000001000415000000110110008a0009000500100218000000000100041a000a00000001001d0008ff000010019400000cb40000c13d0000000001000415000000100110008a00090005001002180000000a01000029000000ff0010019000000cb40000c13d0000000a01000029000008e10110019700000101011001bf0000000b02000029000008d806200198000000000010041b00000ddf0000c13d000000400100043d000008f1020000410000094b0000013d0000000001000416000000000001004b000015f90000c13d000000cb03000039000000000203041a000000010420019000000001012002700000007f0110618f0000001f0010008c00000000050000390000000105002039000000000552013f0000000100500190000008120000c13d000000800010043f000000000004004b000008180000613d000000000030043f000000000001004b000009470000613d000008e50200004100000000040000190000000003040019000000000402041a000000a005300039000000000045043500000001022000390000002004300039000000000014004b000006590000413d00000a280000013d000000440020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000402100370000000000202043b000008d80020009c000015f90000213d0000002401100370000000000101043b000f00000001001d000008d80010009c000015f90000213d000000000020043f0000006601000039000000200010043f00000040020000390000000001000019222821f20000040f0000000f02000029000000000020043f000000200010043f00000000010000190000004002000039222821f20000040f000007880000013d000000440020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000402100370000000000302043b000008d80030009c000015f90000213d0000002401100370000000000201043b00000000010300192228182d0000040f000007d60000013d000000240020008c000015f90000413d0000000003000416000000000003004b000015f90000c13d0000000401100370000000000101043b000008db0010009c000015f90000213d0000000401100039222817cd0000040f000f00000001001d000e00000002001d22281af70000040f0000000f010000290000000e0200002922281b5c0000040f0000000001000019000022290001042e000000440020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000402100370000000000502043b000008d80050009c000015f90000213d0000002401100370000000000101043b000009170010009c000015f90000213d000008e902000041000000000202041a0000000003000411000000000023004b000017700000c13d0000091702100197000027110020008c00000aaf0000413d0000096101000041000000000010043f000008eb010000410000222a00010430000008d9010000410000000c0010043f0000000001000411000000000010043f000008fc01000041000000000010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008fd011001c70000800b02000039222822230000040f0000000100200190000016a90000613d000000000101043b000f00000001001d00000000010004140000088b0010009c0000088b01008041000000c001100210000008fb011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000009530220009a000000000021041b00000000010004140000088b0010009c0000088b01008041000000c001100210000008ec011001c70000800d02000039000000020300003900000954040000410000000005000411000007690000013d000008e901000041000000000501041a0000000001000411000000000051004b000017700000c13d00000000010004140000088b0010009c0000088b01008041000000c001100210000008ec011001c70000800d020000390000000303000039000008ed0400004100000000060000192228221e0000040f0000000100200190000015f90000613d0000091601000041000008e902000041000000000012041b0000000001000019000022290001042e000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b000000000010043f0000009701000039000000200010043f00000040020000390000000001000019222821f20000040f000000000101041a000000800010043f000008da01000041000022290001042e000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b000008d80010009c000015f90000213d000000000010043f000000d801000039000000200010043f00000040020000390000000001000019222821f20000040f000007880000013d000000840020008c000015f90000413d0000000403100370000000000303043b000f00000003001d0000002403100370000000000303043b0000088b0030009c000015f90000213d0000004404100370000000000404043b000b00000004001d0000088b0040009c000015f90000213d0000006404100370000000000404043b000008db0040009c000015f90000213d0000002305400039000000000025004b000015f90000813d0000000405400039000000000151034f000000000101043b000a00000001001d000008db0010009c000015f90000213d00000024014000390000000a040000290000000504400210000900000001001d000700000004001d000800000014001d000000080020006b000015f90000213d0000090601000041000000000201041a0000000004000410000000000042004b00000b770000c13d0000091101000041000000000010043f000008eb010000410000222a00010430000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b000008d80010009c000015f90000213d2228189c0000040f0000002002000039000000400300043d000f00000003001d0000000002230436222818200000040f00000a320000013d000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d000008e902000041000000000202041a0000000003000411000000000023004b000017700000c13d0000000401100370000000000101043b000000d702000039000000000012041b000000800010043f00000000010004140000088b0010009c0000088b01008041000000c00110021000000890011001c70000800d020000390000000103000039000008ff040000412228221e0000040f0000000100200190000015f90000613d0000000001000019000022290001042e000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000201043b000008f900200198000015f90000c13d000000e003200270000008cd0030009c00000000010000390000000101006039000008d60030009c00000001011061bf000007800000613d000008cd0030009c000009510000c13d000000010110018f000000800010043f000008da01000041000022290001042e0000000001000416000000000001004b000015f90000c13d000000cc01000039000000000101041a000000ff001001900000000001000039000000010100c039000000800010043f000008da01000041000022290001042e0000000001000416000000000001004b000015f90000c13d000000ca03000039000000000203041a000000010420019000000001012002700000007f0110618f0000001f0010008c00000000050000390000000105002039000000000054004b000008120000c13d000000800010043f000000000004004b000008180000613d000000000030043f000000000001004b000009470000613d000008e30200004100000000040000190000000003040019000000000402041a000000a005300039000000000045043500000001022000390000002004300039000000000014004b000007a40000413d00000a280000013d000000440020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000002402100370000000000202043b0000000401100370000000000501043b000008e901000041000000000101041a0000000003000411000000000013004b000017700000c13d000000d101000039000000000101041a000000000015004b000008200000813d000000cd01000039000000000301041a000000000053004b0000164e0000a13d000009000350009a000000000303041a000000000003004b00000a520000613d000000000010043f000000000032004b00000a520000a13d0000091a01000041000000800010043f00000902010000410000222a00010430000000240020008c000015f90000413d0000000002000416000000000002004b000015f90000c13d0000000401100370000000000101043b2228187e0000040f000000400200043d00000000001204350000088b0020009c0000088b02008041000000400120021000000928011001c7000022290001042e0000000001000416000000000001004b000015f90000c13d0000001501000039000000800010043f0000091301000041000000a00010043f0000010001000039000000400010043f0000000501000039000000c00010043f0000091401000041000000e00010043f0000004001000039000001000010043f00000080010000390000014002000039222817bb0000040f0000000002010019000001000110008a000001200010043f000000c001000039222817bb0000040f000001000110008a0000088b0010009c0000088b01008041000000600110021000000915011001c7000022290001042e0000000001000416000000000001004b000015f90000c13d000008e901000041000000000101041a000008d801100197000000800010043f000008da01000041000022290001042e0000000001000416000000000001004b000015f90000c13d000000d403000039000000000203041a000000010520019000000001012002700000007f0410018f00000000010460190000001f0010008c00000000060000390000000106002039000000000662013f0000000100600190000008240000613d0000095a01000041000000000010043f0000002201000039000000040010043f0000095b010000410000222a000104300000096602200197000000a00020043f000000000001004b0000082a0000013d0000092101000041000001400010043f00000922010000410000222a000104300000095101000041000000800010043f00000902010000410000222a00010430000000800010043f000000000005004b000009440000c13d0000096601200197000000a00010043f000000000004004b000000c001000039000000a00100603900000a290000013d000000cf01000039000000000101041a000f00000001001d0000000001000410000000140010043f0000093d01000041000000000010043f00000000010004140000088b0010009c0000088b01008041000000c0011002100000093e011001c7000e00000002001d222822230000040f00000060031002700000088b03300197000000200030008c000000200400003900000000040340190000001f0540018f000000200640019000000020046000390000084a0000613d0000002007000039000000000801034f000000008908043c0000000007970436000000000047004b000008460000c13d000000000005004b000008570000613d000000000661034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f00000000005404350003000000010355000100000003001f0000001f0030008c000000000100003900000001010020390000000000120170000000200100043d00000000010060190000000f02000029000000000021004b0000095a0000813d000000400100043d00000943020000410000094b0000013d000008ec011001c70000800902000039000009340400004100000000050000192228221e0000040f000300000001035500000060031002700001088b0030019d0000088b033001980000088d0000c13d0000000100200190000009490000613d000000cf01000039000000000001041b000009390100004100000000001004430000000001000410000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800a02000039222822230000040f0000000100200190000016a90000613d000000d202000039000000000202041a000008d804200197000000000301043b00000000010004140000088b0010009c0000088b01008041000000c001100210000000000003004b000f00000003001d00000ab50000c13d000000000204001900000ab80000013d0000001f0430003900000935044001970000003f044000390000093604400197000000400500043d0000000004450019000000000054004b00000000060000390000000106004039000008db0040009c000005f80000213d0000000100600190000005f80000c13d000000400040043f0000001f0430018f000000000635043600000937053001980000000003560019000008a50000613d000000000701034f000000007807043c0000000006860436000000000036004b000008a10000c13d000000000004004b0000086f0000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001304350000086f0000013d00000005046002100000003f024000390000090d02200197000000400300043d0000000002230019000d00000003001d000000000032004b00000000030000390000000103004039000008db0020009c000005f80000213d0000000100300190000005f80000c13d000a00000001001d000000400020043f0000000d010000290000000001610436000c00000001001d0000001f0240018f000000000004004b000008d00000613d0000000c01400029000000000300003100000002033003670000000c04000029000000003503043c0000000004540436000000000014004b000008cc0000c13d000000000002004b000000000006004b00000a7d0000c13d000000c901000039000000000101041a0000000e0010006c0000164e0000a13d000000c901000039000000000010043f0000000e0100002900000006011000c9000009090110009a222819220000040f000000400700043d0000006002000039000000000327043600000000250104340000006004700039000000c006000039000000000064043500000000060504330000012004700039000000000064043500000000090700190000014004700039000000000006004b000008f30000613d0000000007000019000000200550003900000000080504330000090a0880019700000000048404360000000107700039000000000067004b000008ec0000413d0000000005940049000000600650008a00000000050204330000008002900039000000000062043500000000060504330000000002640436000000000006004b000009040000613d0000000004000019000000200550003900000000070504330000088b0770019700000000027204360000000104400039000000000064004b000008fd0000413d000009670490009900000040051000390000000005050433000000a0069000390000000007420019000000000076043500000000060504330000000002620436000000000006004b000009150000613d00000000070000190000002005500039000000000805043300000000028204360000000107700039000000000067004b0000090f0000413d000000000542001900000060041000390000000004040433000000c006900039000000000056043500000000050404330000000002520436000000000005004b000009260000613d0000000006000019000000200440003900000000070404330000090b0770019700000000027204360000000106600039000000000056004b0000091f0000413d00000080041000390000000004040433000f00000009001d000000e0059000390000000000450435000000a001100039000000000101043300000000049200490000000000430435000001000390003900000000001304350000000a01000029222818200000040f00000000020100190000000f030000290000004001300039000000000332004900000000003104350000000d01000029222818200000040f0000000f0200002900000000012100490000088b0020009c0000088b0200804100000040022002100000088b0010009c0000088b010080410000006001100210000000000121019f000022290001042e000000000030043f000000020020008c00000a1e0000813d000000a00100003900000a290000013d000000400100043d000009380200004100000000002104350000088b0010009c0000088b010080410000004001100210000008f2011001c70000222a000104300000000101000039000009620020009c000007800000613d000009630020009c000007800000613d000009640020009c000007800000613d0000000001000019000007800000013d000000cf03000039000000000003041b000d00000001001d000000000021001a000017190000413d0000093401000041000000140010043f000000340020043f0000093f01000041000000000010043f00000000010004140000088b0010009c0000088b01008041000000c00110021000000940011001c70000000e020000292228221e0000040f00000060031002700000088b07300197000000200070008c000000200400003900000000040740190000001f0340018f0000002008400190000009790000613d000000000401034f0000000005000019000000004604043c0000000005650436000000000085004b000009750000c13d000000000003004b000009860000613d000000000481034f0000000303300210000000000508043300000000053501cf000000000535022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000353019f0000000000380435000100000007001f0003000000010355000000000100043d000000010010008c00000000010000390000000101006039000000000112016f000000010010019000000a630000613d000000d001000039000000000101041a000000d202000039000000000202041a000008d802200197000000140020043f0000000d02000029000000340020043f0000093f02000041000000000020043f0000000003000414000008d8021001970000088b0030009c0000088b03008041000000c00130021000000940011001c7000e00000002001d2228221e0000040f00000060031002700000088b07300197000000200070008c000000200400003900000000040740190000001f0340018f0000002008400190000009af0000613d000000000401034f0000000005000019000000004604043c0000000005650436000000000085004b000009ab0000c13d000000000003004b000009bc0000613d000000000481034f0000000303300210000000000508043300000000053501cf000000000535022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000353019f0000000000380435000c00000007001d000100000007001f0003000000010355000000000100043d000000010010008c00000000010000390000000101006039000b00000002001d000000000112016f000000010010019000000afb0000613d0000000d020000290000000f01200029000000340000043f000000d002000039000000000202041a000000400300043d00000020043000390000000000140435000008d80120019700000000001304350000088b0030009c0000088b03008041000000400130021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008f5011001c70000800d0200003900000001030000390000094204000041000007690000013d0000096603300197000000000313019f000000000032041b000000800010043f00000000010004140000088b0010009c0000088b01008041000000c00110021000000890011001c70000800d0200003900000001030000390000092604000041000007690000013d000000000020043f0000006601000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a00000966022001970000000e03000029000000000232019f000000000021041b000000400100043d00000000003104350000088b0010009c0000088b01008041000000400110021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ee011001c70000800d020000390000000303000039000009230400004100000000050004110000000f060000292228221e0000040f00000001002001900000076c0000c13d000015f90000013d000009050200004100000000040000190000000003040019000000000402041a000000a005300039000000000045043500000001022000390000002004300039000000000014004b00000a200000413d000000c001300039000000800210008a0000008001000039222817a90000040f0000002001000039000000400200043d000f00000002001d00000000021204360000008001000039222817bb0000040f0000000f0200002900000000012100490000088b0010009c0000088b0100804100000060011002100000088b0020009c0000088b020080410000004002200210000000000121019f000022290001042e000f00000004001d000d00000003001d000000000030043f0000009701000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a0000000f02000029000000000012004b00000b530000813d000000400100043d00000904020000410000094b0000013d000000ce01000039000000000301041a000000000053004b0000164e0000a13d000000000010043f0000090c0150009a000000000021041b000000800020043f00000000010004140000088b0010009c0000088b01008041000000c00110021000000890011001c70000800d0200003900000002030000390000095204000041000007690000013d000b00000002001d000c00000007001d000008dc0100004100000000001004430000000e01000029000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800202000039222822230000040f0000000100200190000016a90000613d000000010200008a0000000b0220014f000000000101043b000000000001004b000000000100003900000001010060390000000c001001b0000000010220c1bf00000001002001900000098f0000613d00000b120000013d0000801004000039000f00000000001d000b00000006001d0000000e01000029000000000010043f000000d601000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000000002040019222822230000040f00000001002001900000000f03000029000015f90000613d000000000101043b000000000030043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039000f00000003001d222822230000040f0000000f050000290000000100200190000015f90000613d00008010040000390000000d020000290000000002020433000000000052004b0000164e0000a13d00000005025002100000000c022000290000000003020433000000000101043b000000000101041a000000000013001a0000000b06000029000017190000413d00000000011300190000000000120435000f00010050003d0000000f0060006b00000a800000413d000008d30000013d000000000005004b00000b410000c13d0000096001000041000000000010043f000008eb010000410000222a00010430000008ec011001c7000080090200003900000000050000192228221e0000040f000300000001035500000060031002700001088b0030019d0000088b0330019800000ad50000c13d000000010020019000000b160000613d000000cf01000039000000000101041a0000000f02000029000000000021001a000017190000413d0000000001210019000000400200043d00000000001204350000088b0020009c0000088b02008041000000400120021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ee011001c70000800d0200003900000001030000390000093b04000041000007690000013d0000001f0430003900000935044001970000003f044000390000093604400197000000400500043d0000000004450019000000000054004b00000000060000390000000106004039000008db0040009c000005f80000213d0000000100600190000005f80000c13d000000400040043f0000001f0430018f00000000063504360000093705300198000000000356001900000aed0000613d000000000701034f000000007807043c0000000006860436000000000036004b00000ae90000c13d000000000004004b00000abe0000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000abe0000013d000008dc0100004100000000001004430000000e01000029000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800202000039222822230000040f0000000100200190000016a90000613d000000010200008a0000000b0220014f000000000101043b000000000001004b000000000100003900000001010060390000000c001001b0000000010220c1bf0000000100200190000009c70000613d0000094101000041000000000010043f000008eb010000410000222a00010430000000400100043d0000093a020000410000094b0000013d0000000d01000029000000000001041b0000000f01000029222821be0000040f0000000001000019000022290001042e000000000020043f0000009701000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a0000000d0010002a000017190000413d000000cd04000039000000000204041a0000000e0020006c0000164e0000a13d0000000d01100029000000000040043f000000400300043d0000000c02000029000000000202041a000000000021004b000004100000a13d0000093c0100004100000000001304350000088b0030009c0000088b030080410000004001300210000008f2011001c70000222a000104300000006003500210000000000332019f0000091f04000041000000000034041b000000a001100210000000000151019f000000d303000039000000000013041b000000800020043f00000000010004140000088b0010009c0000088b01008041000000c00110021000000890011001c70000800d0200003900000002030000390000092004000041000007690000013d000000cd03000039000000000103041a0000000d05000029000000000051004b0000164e0000a13d000000000030043f0000000e01000029000000000021041b000000400100043d00000000002104350000088b0010009c0000088b01008041000000400110021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ee011001c70000800d0200003900000002030000390000090304000041000007690000013d000000000003004b000000000400001900000b700000613d0000002004500039000000000141034f000000000401043b0000000301300210000009680110027f0000096801100167000000000114016f0000000103300210000000000131019f00000c850000013d0000000002000410000000000021041b000000cd01000039000000000101041a0000000f0010006c0000164e0000a13d0006088b0030019b000000cd01000039000000000010043f0000000f01000029000009000110009a000e00000001001d000000000101041a000000000001004b00000d6d0000c13d000008fc01000041000000000010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008fd011001c70000800b02000039222822230000040f0000000100200190000016a90000613d000000000101043b000000c902000039000000000202041a000000000002004b00000e290000613d000000000500001900000b9b0000013d0000000105500039000000000025004b00000e270000813d00000006035000c9000009070430009a000000000404041a000000000014004b00000b980000213d000009080430009a000000000404041a000000000014004b00000b980000a13d000500000005001d000000000052004b0000164e0000a13d000000c901000039000000000010043f000009090130009a222819220000040f000400000001001d000000d001000039000000000101041a000308d80010019c00000bc80000c13d0000000401000029000000000101043300000000020104330000000f0020006c0000164e0000a13d0000000f0200002900000005022002100000000001120019000000200110003900000000010104330000090a01100197000000d702000039000000000202041a000000000012001a000017190000413d000000000212001a00000006012000b900000bc50000613d00000000022100d9000000060020006c000017190000c13d0000000002000416000000000012004b00000d6a0000413d00000004010000290000006001100039000e00000001001d000000000101043300000000020104330000000f0020006c0000164e0000a13d0000000f020000290000000502200210000200200020003d000000020110002900000000010104330000090b00100198000010560000c13d000000ce01000039000000000101041a0000000f0010006c0000164e0000a13d000000ce02000039000000000020043f0000000f020000290000090c0220009a000100000002001d000000000202041a000000000002004b000011340000c13d00000004010000290000002001100039000e00000001001d000000000101043300000000020104330000000f0020006c0000164e0000a13d000000020110002900000000010104330000088b00100198000012970000c13d00000004010000290000004001100039000000000101043300000000020104330000000f0020006c0000164e0000a13d00000002011000290000000001010433000c00000001001d000000000001004b000013940000c13d000000030000006b000014870000c13d000000d701000039000000000201041a00000006012000b9000000000002004b00000c020000613d00000000022100d9000000060020006c000017190000c13d000000cf02000039000000000302041a000000000013001a000017190000413d0000000001130019000000000012041b0000000501000029000000000010043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000002000411000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a0000088b0320019700000006033000290000088b0030009c000017190000213d0000091002200197000000000223019f000000000021041b0000000501000029000000000010043f000000d601000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a000000060020002a000017190000413d0000000602200029000000000021041b000000400100043d000e00000001001d2228179e0000040f0000000e04000029000000000004043500000000010004110000000f020000290000000603000029222820310000040f0000000001000412001200000001001d000080020100003900000024030000390000000004000415000000120440008a0000000504400210000008dc02000041222822070000040f0000090602000041000000000012041b0000000001000019000022290001042e000009050500004100000000070000190000000008470019000000000881034f000000000808043b000000000085041b00000001055000390000002007700039000000000067004b00000c700000413d000000000036004b00000c830000813d0000000306300210000000f80660018f000009680660027f00000968066001670000000004470019000000000141034f000000000101043b000000000161016f000000000015041b000000010130021000000001011001bf000000000012041b00000000010004140000088b0010009c0000088b01008041000000c001100210000008ec011001c70000800d0200003900000001030000390000092a04000041000007690000013d0000000901000029000000000010043f0000006601000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000002000411000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a000000ff00100190000004df0000c13d000000400100043d0000006402100039000009450300004100000000003204350000004402100039000009460300004100000d930000013d000008dc0100004100000000001004430000000001000410000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800202000039222822230000040f0000000100200190000016a90000613d000000000101043b000000000001004b00000d8a0000c13d0000000a01000029000000ff0110018f000000010010008c00000009010000290000000501100270000000000100003f000000010100603f00000d8d0000c13d000000080000006b000006390000613d000001000100008a0000000a0110017f00000001011001bf0000063c0000013d000000400100043d000d00000001001d000008f60010009c000005f80000213d0000000d020000290000004001200039000000400010043f000000010100003900000000031204360000000702000029000b00000003001d0000000000230435000000400200043d000c00000002001d000008f60020009c000005f80000213d0000000c030000290000004002300039000000400020043f00000000021304360000000601000029000a00000002001d0000000000120435000000090000006b00000e2c0000c13d0000000d010000290000000001010433000000000001004b00000e330000613d00000000030000190000000c020000290000000002020433000000000032004b0000164e0000a13d000000000031004b0000164e0000a13d000f00000003001d00000005013002100000000a021000290000000002020433000e00000002001d0000000b011000290000000001010433000000000010043f0000009701000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a0000000e03000029000000000032001a000017190000413d0000000002320019000000000021041b0000000f0300002900000001033000390000000d010000290000000001010433000000000013004b00000cf00000413d00000e330000013d00000024010000390000000201100367000000000101043b000000cd02000039000000000202041a000000000012004b0000164e0000a13d000000cd02000039000000000020043f000009000210009a000000000202041a000000000002004b00000e060000c13d000008fc01000041000000000010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008fd011001c70000800b02000039222822230000040f0000000100200190000016a90000613d000000000101043b000000c902000039000000000202041a000000000002004b00000e290000613d000000000500001900000d390000013d0000000105500039000000000025004b00000e270000813d00000006035000c9000009070430009a000000000404041a000000000014004b00000d360000213d000009080430009a000000000404041a000000000014004b00000d360000a13d000500000005001d000000000052004b0000164e0000a13d000000c901000039000000000010043f000009090130009a222819220000040f000400000001001d00000002010003670000002402100370000000000202043b000000d003000039000000000303041a000308d80030019c000010800000c13d000000040300002900000000030304330000000004030433000000000024004b0000164e0000a13d00000005042002100000000003340019000000200330003900000000030304330000090a03300197000000d704000039000000000504041a000000000035001a000017190000413d0000000e040000290000088b04400197000000000535001a00000000034500a900000d670000613d00000000055300d9000000000045004b000017190000c13d0000000004000416000000000034004b000010800000813d000000400100043d0000095d020000410000094b0000013d0000000f01000029000000000010043f0000009701000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a000000060010002a000017190000413d000000cd02000039000000000202041a0000000f0020006c0000164e0000a13d0000000601100029000000cd02000039000000000020043f0000000e02000029000000000202041a000000000021004b00000b860000a13d00000e240000013d00000009010000290000000501100270000000000100003f000000400100043d0000006402100039000008de0300004100000000003204350000004402100039000008df03000041000000000032043500000024021000390000002e0300003900000dd40000013d0000000c04000029000000000631034f000000000606043b000000200440003900000000006404350000002003300039000000000053004b00000d980000413d0000000c030000290000000003030433000000800400043d000000000034004b00000dcb0000c13d000008db0030009c000005f80000213d00000005043002100000003f054000390000093006500197000000400500043d000a00000005001d0000000005560019000000000065004b00000000060000390000000106004039000008db0050009c000005f80000213d0000000100600190000005f80000c13d000000400050043f0000000a050000290000000003350436000900000003001d0000001f0340018f000000000004004b00000dc10000613d000000000121034f00000009024000290000000904000029000000001501043c0000000004540436000000000024004b00000dbd0000c13d000000000003004b000000800100043d000000000001004b00000e660000c13d000000400200043d000f00000002001d000000200100003900000000021204360000000a01000029000007500000013d000000400100043d00000064021000390000092e03000041000000000032043500000044021000390000092f0300004100000000003204350000002402100039000000290300003900000000003204350000088c0200004100000000002104350000000402100039000000200300003900000000003204350000088b0010009c0000088b010080410000004001100210000008e0011001c70000222a00010430000000ca01000039000000000301041a000000010030019000000001023002700000007f0220618f0000001f0020008c00000000040000390000000104002039000000000343013f0000000100300190000008120000c13d000000200020008c00000dfc0000413d000000000010043f0000000f040000290000001f034000390000000503300270000008e20330009a000000200040008c000008e3030040410000001f022000390000000502200270000008e20220009a000000000023004b00000dfc0000813d000000000003041b0000000103300039000000000023004b00000df80000413d0000000f020000290000001f0020008c00000e580000a13d000000000010043f000000200200008a0000000f0320018000000e9c0000c13d000008e302000041000000000400001900000ea80000013d000000000010043f0000009701000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a0000000e0010002a000017190000413d00000024020000390000000202200367000000000202043b000000cd03000039000000000303041a000000000023004b0000164e0000a13d0000000e01100029000000cd03000039000000000030043f000009000220009a000000000202041a000000000021004b00000d240000a13d000000400100043d0000093c020000410000094b0000013d000000c901000039000000000010043f000000400100043d00000921020000410000094b0000013d000000cc01000039000000000101041a000000ff0010019000000e330000c13d000000400100043d00000949020000410000094b0000013d0000000701000029000000000010043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000902000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a000f00060010007400000f5d0000813d000000400100043d00000064021000390000094a03000041000000000032043500000044021000390000094b03000041000010330000013d0000000f0000006b000000000200001900000e5e0000613d0000000e020000290000000202200367000000000202043b0000000f050000290000000303500210000009680330027f0000096803300167000000000232016f0000000103500210000000000232019f00000eb70000013d00000000030000190000000c010000290000000001010433000000000031004b0000164e0000a13d000e00000003001d0000000503300210000000a0013000390000000001010433000f08d80010019c00008010020000390000102d0000613d000d00000003001d0000000b013000290000000001010433000000000010043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c7222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d0000000a0200002900000000020204330000000e03000029000000000032004b0000164e0000a13d0000000d040000290000000902400029000000000101043b000000000101041a00000000001204350000000103300039000000800100043d000000000013004b00000e670000413d00000dc50000013d000008e302000041000000020500036700000000040000190000000e080000290000000007840019000000000775034f000000000707043b000000000072041b00000001022000390000002004400039000000000034004b00000ea00000413d0000000f0030006c00000eb40000813d0000000f030000290000000303300210000000f80330018f000009680330027f00000968033001670000000e044000290000000204400367000000000404043b000000000334016f000000000032041b0000000f02000029000000010220021000000001022001bf000000000021041b000000cb01000039000000000301041a000000010030019000000001023002700000007f0220618f0000001f0020008c00000000040000390000000104002039000000000343013f0000000100300190000008120000c13d000000200020008c00000ed50000413d000000000010043f0000000d040000290000001f034000390000000503300270000008e40330009a000000200040008c000008e5030040410000001f022000390000000502200270000008e40220009a000000000023004b00000ed50000813d000000000003041b0000000103300039000000000023004b00000ed10000413d0000000d020000290000001f0020008c00000edf0000a13d000000000010043f000000200200008a0000000d0320018000000eed0000c13d000008e502000041000000000400001900000ef90000013d0000000d0000006b000000000200001900000ee50000613d0000000c020000290000000202200367000000000202043b0000000d050000290000000303500210000009680330027f0000096803300167000000000232016f0000000103500210000000000232019f00000f080000013d000008e502000041000000020500036700000000040000190000000c080000290000000007840019000000000775034f000000000707043b000000000072041b00000001022000390000002004400039000000000034004b00000ef10000413d0000000d0030006c00000f050000813d0000000d030000290000000303300210000000f80330018f000009680330027f00000968033001670000000c044000290000000204400367000000000404043b000000000334016f000000000032041b0000000d02000029000000010220021000000001022001bf000000000021041b000000400100043d000008e60010009c000005f80000213d0000002002100039000000400020043f0000000000010435000000000100041a0000ff000010019000000f1c0000c13d000000400100043d0000006402100039000008ef0300004100000000003204350000004402100039000008f003000041000000000032043500000024021000390000002b0300003900000dd40000013d0000006701000039000000000301041a000000010030019000000001023002700000007f0220618f0000001f0020008c00000000040000390000000104002039000000000343013f0000000100300190000008120000c13d000000200020008c00000f320000413d000000000010043f000008e7030000410000001f022000390000000502200270000008e80220009a000000000003041b0000000103300039000000000023004b00000f2e0000413d000000000001041b000008e901000041000000000201041a000000000002004b000011260000c13d000000000061041b00000000010004140000088b0010009c0000088b01008041000000c001100210000008ec011001c70000800d020000390000000303000039000008ed0400004100000000050000192228221e0000040f0000000100200190000015f90000613d00000064010000390000000201100367000000000101043b000000d702000039000000000012041b000000080000006b0000076c0000c13d000000000200041a0000096901200197000000000010041b0000000103000039000000400100043d00000000003104350000088b0010009c0000088b01008041000000400110021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ee011001c70000800d020000390000089104000041000007690000013d0000000701000029000000000010043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000902000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000021041b0000000701000029000000000010043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000802000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a000000060020002a000017190000413d00000006030000290000000002320019000000000021041b000000400100043d00000020021000390000000000320435000000070200002900000000002104350000088b0010009c0000088b01008041000000400110021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008f5011001c70000800d020000390000000403000039000008f7040000410000000005000411000000090600002900000008070000292228221e0000040f0000000100200190000015f90000613d000008dc0100004100000000001004430000000801000029000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800202000039222822230000040f0000000100200190000016a90000613d000000000101043b000000000001004b0000076c0000613d000000400300043d0000008401300039000000a0020000390000000000210435000000640130003900000006020000290000000000210435000000440130003900000007020000290000000000210435000000240130003900000009020000290000000000210435000008f8010000410000000000130435000000040130003900000000020004110000000000210435000000a402300039000000800100043d0000000000120435000f00000003001d000000c402300039000000000001004b00000fe30000613d00000000030000190000000004230019000000a005300039000000000505043300000000005404350000002003300039000000000013004b00000fdc0000413d0000001f03100039000009650330019700000000012100190000000000010435000000c4013000390000088b0010009c0000088b0100804100000060011002100000000f020000290000088b0020009c0000088b020080410000004002200210000000000121019f00000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f00000008020000292228221e0000040f00000060031002700000088b03300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000f05700029000010060000613d000000000801034f0000000f09000029000000008a08043c0000000009a90436000000000059004b000010020000c13d000000000006004b000010130000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000146d0000613d0000001f01400039000000600110018f0000000f04100029000000000014004b00000000010000390000000101004039000008db0040009c000005f80000213d0000000100100190000005f80000c13d0000000002040019000000400040043f000000200030008c000015f90000413d0000000f010000290000000001010433000008f900100198000015f90000c13d000008fa01100197000008f80010009c0000076c0000613d000012530000013d000000400100043d00000064021000390000093103000041000000000032043500000044021000390000093203000041000000000032043500000024021000390000002a0300003900000dd40000013d0000000a01000029000000000010043f0000006601000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000002000411000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a000000ff00100190000005990000c13d00000cad0000013d0000000501000029000000000010043f000000d601000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a000000060010002a000017190000413d0000000e02000029000000000202043300000000030204330000000f0030006c0000164e0000a13d0000000601100029000000020220002900000000020204330000090b02200197000000000021004b00000bd60000a13d000011770000013d00000004030000290000006003300039000d00000003001d00000000030304330000000004030433000000000024004b0000164e0000a13d00000005042002100000000003340019000000200330003900000000030304330000090b00300198000011450000c13d000000ce03000039000000000303041a000000000023004b0000164e0000a13d000000ce04000039000000000040043f0000090c0420009a000000000404041a000000000004004b000012cf0000c13d00000004030000290000002003300039000d00000003001d00000000030304330000000004030433000000000024004b0000164e0000a13d00000005042002100000000003340019000000200330003900000000030304330000088b00300198000014260000c13d0000000403000029000000400330003900000000030304330000000004030433000000000024004b0000164e0000a13d0000000502200210000000000232001900000020022000390000000002020433000b00000002001d000000000002004b000015c40000c13d000000030000006b000015fb0000c13d0000000e01000029000e088b0010019b000000d701000039000000000201041a0000000e012000b9000000000002004b000010bd0000613d00000000022100d90000000e0020006c000017190000c13d000000cf02000039000000000302041a000000000013001a000017190000413d0000000001130019000000000012041b0000000501000029000000000010043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b00000024020000390000000202200367000000000202043b000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000008d802200197000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a0000088b032001970000000e033000290000088b0030009c000017190000213d0000091002200197000000000223019f000000000021041b0000000501000029000000000010043f000000d601000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b00000024020000390000000202200367000000000202043b000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a0000000e0020002a000017190000413d000e000e0000002d0000000e02200029000000000021041b000000400100043d000d00000001001d2228179e0000040f0000000d04000029000000000004043500000024010000390000000201100367000000000201043b0000000f010000290000000e03000029222820310000040f0000000001000019000022290001042e000008ea01000041000000000010043f000008eb010000410000222a00010430000000400100043d0000006402100039000009470300004100000000003204350000004402100039000009480300004100000000003204350000002402100039000000280300003900000dd40000013d000000c902000039000000000202041a000c00000002001d000000000002004b00000006020000290000125a0000c13d0000000f0010006c0000164e0000a13d000000ce01000039000000000010043f0000000101000029000000000101041a000000000012004b00000be20000a13d000000400100043d00000956020000410000094b0000013d0000000501000029000000000010043f000000d601000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b00000024020000390000000202200367000000000202043b000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d0000000e020000290000088b03200197000000000101043b000000000401041a000000000034001a000017190000413d00000002010003670000002402100370000000000202043b0000000d0500002900000000050504330000000006050433000000000026004b0000164e0000a13d000000000334001900000005042002100000000004450019000000200440003900000000040404330000090b04400197000000000043004b0000108d0000a13d000000400100043d00000955020000410000094b0000013d000000cc02000039000000000202041a000000ff002001900000000d0200002900000e300000613d000000000001004b000012e10000c13d000000400100043d000000400200003900000000022104360000004003100039000000800400043d00000000004304350000006003100039000000000004004b000011920000613d000000800500003900000000060000190000002005500039000000000705043300000000037304360000000106600039000000000046004b0000118c0000413d000000000413004900000000004204350000000d0200002900000000040204330000000002430436000000000004004b000011a10000613d00000000030000190000000d050000290000002005500039000000000605043300000000026204360000000103300039000000000043004b0000119b0000413d00000000021200490000088b0020009c0000088b0200804100000060022002100000088b0010009c0000088b010080410000004001100210000000000112019f00000000020004140000088b0020009c0000088b02008041000000c002200210000000000121019f000008ec011001c70000800d0200003900000004030000390000094c0400004100000000050004110000000a0600002900000007070000292228221e0000040f0000000100200190000015f90000613d000008dc0100004100000000001004430000000b01000029000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800202000039222822230000040f0000000100200190000016a90000613d000000000101043b000000000001004b0000076c0000613d000000400300043d0000004401300039000000a002000039000000000021043500000024013000390000000a0200002900000000002104350000094d010000410000000000130435000000040130003900000000020004110000000000210435000000a401300039000000800200043d0000000000210435000f00000003001d000000c401300039000000000002004b000011e30000613d000000800300003900000000040000190000002003300039000000000503043300000000015104360000000104400039000000000024004b000011dd0000413d0000000f030000290000000002310049000000040220008a000000640330003900000000002304350000000d0200002900000000020204330000000001210436000000000002004b000011f50000613d00000000030000190000000d050000290000002005500039000000000405043300000000014104360000000103300039000000000023004b000011ef0000413d0000000f030000290000000002310049000000040220008a00000084033000390000000000230435000000060200002900000000020204330000000001210436000000000002004b0000000506000029000012080000613d000000000300001900000000041300190000000005630019000000000505043300000000005404350000002003300039000000000023004b000012010000413d000000000312001900000000000304350000001f0220003900000965022001970000000f03000029000000000131004900000000012100190000088b0010009c0000088b0100804100000060011002100000088b0030009c0000088b0200004100000000020340190000004002200210000000000121019f00000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f00000007020000292228221e0000040f00000060031002700000088b03300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000f057000290000122d0000613d000000000801034f0000000f09000029000000008a08043c0000000009a90436000000000059004b000012290000c13d000000000006004b0000123a0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000014e40000613d0000001f01400039000000600110018f0000000f04100029000000000014004b00000000010000390000000101004039000008db0040009c000005f80000213d0000000100100190000005f80000c13d0000000002040019000000400040043f000000200030008c000015f90000413d0000000f010000290000000001010433000008f900100198000015f90000c13d000008fa011001970000094d0010009c0000076c0000613d0000088c01000041000e00000002001d00000000001204350000000401200039222821d70000040f0000000e02000029000015200000013d0000000002000019000e00000000001d000d00000002001d000000000020043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000002000411000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a0000088b011001970000000e02000029000000000021001a000017190000413d000e00000021001d0000000d0200002900000001022000390000000c0020006c0000125c0000413d0000000e02000029000000060020002a000017190000413d0000000602200029000000ce01000039000000000101041a0000000f0010006c0000113c0000213d0000164e0000013d0000000501000029000000000010043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000002000411000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a0000088b0110019700000006011000290000088b0010009c000017190000213d0000000e02000029000000000202043300000000030204330000000f0030006c0000164e0000a13d000000020220002900000000020204330000088b02200197000000000021004b00000bed0000a13d000014670000013d000000c902000039000000000202041a000b00000002001d000000000002004b000013520000c13d0000000e020000290000088b042001970000002402100370000000000202043b000000000023004b0000164e0000a13d000000ce03000039000000000030043f0000090c0320009a000000000303041a000000000034004b000010970000a13d000011420000013d00000000030000190000000001020433000000000031004b0000164e0000a13d000900000003001d0000000501300210000000a00210003900000000030204330000000c011000290000000001010433000e00000001001d000f00000003001d000000000030043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000a02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a0008000e0010007400000e510000413d0000000f01000029000000000010043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000a02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000802000029000000000021041b0000000f01000029000000000010043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000702000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000201041a0000000e03000029000000000032001a000017190000413d0000000002320019000000000021041b00000009030000290000000103300039000000800100043d000000000013004b0000000d02000029000012e20000413d000011810000013d000000400100043d00000918020000410000094b0000013d0000000f01000029000a08d80010019b0000000002000019000d00000000001d000c00000002001d000000000020043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b00000024020000390000000202200367000000000202043b000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000a02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a0000088b011001970000000d02000029000000000021001a000017190000413d000d00000021001d0000000c0200002900000001022000390000000b0020006c000013560000413d0000000e010000290000088b011001970000000d02000029000000000012001a000017190000413d00000000041200190000000201000367000000ce02000039000000000302041a000012d60000013d00000000010004110000006003100210000000400100043d000000200210003900000000003204350000000b03000029000000e0033002100000003404100039000000000034043500000018030000390000000000310435000008f60010009c000005f80000213d0000004003100039000000400030043f0000088b0020009c0000088b02008041000000400220021000000000010104330000088b0010009c0000088b010080410000006001100210000000000121019f00000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ec011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b00000007020000290000003f022000390000090d02200197000000400300043d0000000002230019000000000032004b00000000040000390000000104004039000008db0020009c000005f80000213d0000000100400190000005f80000c13d000000400020043f0000000a0200002900000000022304360000000805000029000000000050007c000015f90000213d0000000a0000006b000013f10000613d0000000904000029000000020440036700000000050300190000002005500039000000004604043c000000000065043500000009060000290000002006600039000900000006001d000000080060006c000013cd0000413d0000000003030433000000000003004b000013f10000613d0000000503300210000d00000032001d0000000043020434000e00000004001d000000000031004b000000000300003900000020030020390000000000130435000000200130015f0000000002020433000000000021043500000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000e030000290000000d0030006c0000000002030019000013da0000413d0000000c0010006c0000171f0000c13d0000000b01000029000e088b0010019c00000bf80000613d0000000501000029000000000010043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000002000411000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b000000000101041a0000088b0110019700000006011000290000088b0010009c000017190000213d0000000e0010006c00000bf80000a13d000014670000013d0000000501000029000000000010043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b00000024020000390000000202200367000000000202043b000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000008d802200197000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d0000000e020000290000088b02200197000000000101043b000000000101041a0000088b0110019700000000032100190000088b0030009c000017190000213d00000002010003670000002402100370000000000202043b0000000d0400002900000000040404330000000005040433000000000025004b0000164e0000a13d00000005052002100000000004540019000000200440003900000000040404330000088b04400197000000000043004b000010a40000a13d000000400100043d00000959020000410000094b0000013d000000400100043d00000919020000410000094b0000013d000000040230008c000015190000413d000000000400043d000008f904400197000000000501043b000008fa05500197000000000445019f000000000040043f000008fa044001970000088c0040009c000015190000c13d000000440030008c000015190000413d000000040510037000000965062001980000001f0720018f000000400400043d0000000001640019000014fd0000613d000000000805034f0000000009040019000000008a08043c0000000009a90436000000000019004b000014820000c13d000014fd0000013d0000000401000029000000000101043300000000020104330000000f0020006c0000164e0000a13d000000020110002900000000010104330000090a01100197000000d702000039000000000202041a000000000012001a000017190000413d000000000212001a00000006012000b9000014990000613d00000000022100d9000000060020006c000017190000c13d000000400200043d000c00000002001d000000600010043f0000000001000410000000400010043f000000000100041100000060011002100000002c0010043f0000090e010000410000000c0010043f00000000010004140000088b0010009c0000088b01008041000000c0011002100000090f011001c700000003020000292228221e0000040f000d00000002001d00000060021002700000088b02200197000000200020008c000e00000002001d00000020020080390000001f0320018f0000002002200190000014b90000613d000000000401034f0000000005000019000000004604043c0000000005650436000000000025004b000014b50000c13d000000000003004b000014c60000613d000000000421034f0000000303300210000000000502043300000000053501cf000000000535022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000353019f00000000003204350001000e0000002f0003000000010355000000000100043d000000010010008c000000000100003900000001010060390000000d0110017f0000000100100190000016540000613d000000600000043f0000000c01000029000000400010043f00000bfa0000013d000000000e000019000014d80000013d000000010ee000390000000000ce004b000015290000813d000000050fe00210000000a00af00039000000000a0a043300000000000a004b000014d50000613d000000000ffb0019000000000f0f04330000000000af004b000014d50000a13d000000400100043d0000091a020000410000094b0000013d000000040230008c000015190000413d000000000400043d000008f904400197000000000501043b000008fa05500197000000000445019f000000000040043f000008fa044001970000088c0040009c000015190000c13d000000440030008c000015190000413d000000040510037000000965062001980000001f0720018f000000400400043d0000000001640019000014fd0000613d000000000805034f0000000009040019000000008a08043c0000000009a90436000000000019004b000014f90000c13d000000000007004b0000150a0000613d000000000565034f0000000306700210000000000701043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f00000000005104350000000005040433000008db0050009c000015190000213d0000002401500039000000000031004b000015190000213d00000000014500190000000003010433000008db0030009c000015190000213d000000000224001900000000063100190000002006600039000000000026004b0000166f0000a13d000000400200043d000f00000002001d0000088c0100004100000000001204350000000401200039222821e40000040f0000000f0200002900000000012100490000088b0010009c0000088b0100804100000060011002100000088b0020009c0000088b020080410000004002200210000000000121019f0000222a000104300000091b0ad001970000091c0aa001c7000000d20b0000390000000000ab041b000000d10a0000390000000000ca041b000008db00c0009c000005f80000213d000000cd0b000039000000000a0b041a0000000000cb041b0000000000ac004b0000153e0000813d000009000dc0009a000009000ea0009a0000000000ed004b0000153e0000813d00000000000d041b000000010dd000390000000000ed004b0000153a0000413d0000000000b0043f00000000000c004b000015490000613d000000a00b000039000000000d00001900000000ba0b0434000009000ed0009a0000000000ae041b000000010dd000390000000000cd004b000015430000413d000000000b070433000008db00b0009c000005f80000213d000000ce0c000039000000000a0c041a0000000000bc041b0000000000ab004b000015590000813d0000090c0db0009a0000090c0ea0009a0000000000ed004b000015590000813d00000000000d041b000000010dd000390000000000ed004b000015550000413d0000000000c0043f00000000000b004b000015640000613d000000000c00001900000020077000390000090c0ac0009a000000000d0704330000000000da041b000000010cc000390000000000bc004b0000155d0000413d000000cc07000039000000000a07041a000009660aa00197000000010aa001bf0000000000a7041b000008d807900197000000d009000039000000000a09041a0000091d0aa0019700000000077a019f000000000079041b000000d209000039000000000709041a0000091d07700197000000000787019f000000000079041b0000001f0750003900000965077001970000003f077000390000096509700197000000400700043d0000000009970019000000000079004b000000000a000039000000010a004039000008db0090009c000005f80000213d0000000100a00190000005f80000c13d000000400090043f000000000a61034f0000000009570436000009650b5001980000001f0c50018f0000000006b900190000158e0000613d000000000d0a034f000000000e09001900000000df0d043c000000000efe043600000000006e004b0000158a0000c13d00000000000c004b0000159b0000613d000000000aba034f000000030bc00210000000000c060433000000000cbc01cf000000000cbc022f000000000a0a043b000001000bb00089000000000aba022f000000000aba01cf000000000aca019f0000000000a60435000000000559001900000000000504350000000006070433000008db0060009c000005f80000213d0000006705000039000000000b05041a0000000100b00190000000010ab002700000007f0aa0618f0000001f00a0008c000000000c000039000000010c002039000000000bcb013f0000000100b00190000008120000c13d0000002000a0008c000015bc0000413d000000000050043f0000001f0b600039000000050bb00270000008e80bb0009a000000200060008c000008e70b0040410000001f0aa00039000000050aa00270000008e80aa0009a0000000000ab004b000015bc0000813d00000000000b041b000000010bb000390000000000ab004b000015b80000413d0000001f0060008c000016aa0000a13d000000000050043f000009650a600198000017220000c13d0000002009000039000008e7080000410000172e0000013d0000000f020000290000006004200210000000400200043d000000200320003900000000004304350000006401100370000000000101043b000000e0011002100000003404200039000000000014043500000018010000390000000000120435000009570020009c000005f80000813d0000004001200039000000400010043f0000088b0030009c0000088b03008041000000400130021000000000020204330000088b0020009c0000088b020080410000006002200210000000000112019f00000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ec011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b00000006020000290000003f022000390000090d02200197000000400300043d0000000002230019000000000032004b00000000040000390000000104004039000008db0020009c000005f80000213d0000000100400190000005f80000c13d000000400020043f000000090200002900000000022304360000000705000029000000000050007c000016b30000a13d00000000010000190000222a0001043000000024010000390000000201100367000000000101043b000000040200002900000000020204330000000003020433000000000013004b0000164e0000a13d00000005011002100000000001210019000000200110003900000000010104330000090a01100197000000d702000039000000000202041a000000000012001a000017190000413d0000000e03000029000e088b0030019b000000000212001a0000000e012000b9000016140000613d00000000022100d90000000e0020006c000017190000c13d000000400200043d000b00000002001d000000600010043f0000000001000410000000400010043f000000000100041100000060011002100000002c0010043f0000090e010000410000000c0010043f00000000010004140000088b0010009c0000088b01008041000000c0011002100000090f011001c700000003020000292228221e0000040f000c00000002001d00000060021002700000088b02200197000000200020008c000d00000002001d00000020020080390000001f0320018f0000002002200190000016340000613d000000000401034f0000000005000019000000004604043c0000000005650436000000000025004b000016300000c13d000000000003004b000016410000613d000000000421034f0000000303300210000000000502043300000000053501cf000000000535022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000353019f00000000003204350001000d0000002f0003000000010355000000000100043d000000010010008c000000000100003900000001010060390000000c0110017f0000000100100190000016910000613d000000600000043f0000000b01000029000000400010043f000010b50000013d0000095a01000041000000000010043f0000003201000039000000040010043f0000095b010000410000222a00010430000008dc0100004100000000001004430000000301000029000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800202000039222822230000040f0000000100200190000016a90000613d000000010200008a0000000d0220014f000000000101043b000000000001004b000000000100003900000001010060390000000e001001b0000000010220c1bf0000000100200190000014cf0000613d0000095c01000041000000000010043f000008eb010000410000222a0001043000000000023500190000003f0220003900000965022001970000000004420019000000000024004b00000000020000390000000102004039000008db0040009c000005f80000213d0000000100200190000005f80000c13d0000000003040019000000400040043f000000000001004b000015190000613d0000088c020000410000000004030019000f00000003001d00000000002304350000000402300039000000200300003900000000003204350000002402400039222817bb0000040f0000000f0200002900000000012100490000088b0010009c0000088b010080410000088b0020009c0000088b0200804100000060011002100000004002200210000000000121019f0000222a00010430000008dc0100004100000000001004430000000301000029000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800202000039222822230000040f0000000100200190000016a90000613d000000010200008a0000000c0220014f000000000101043b000000000001004b000000000100003900000001010060390000000d001001b0000000010220c1bf00000001002001900000164a0000613d0000166b0000013d000000000001042f000000000006004b0000000007000019000017740000c13d000000000075041b000000000003004b0000173d0000c13d000008d8052001980000076c0000613d000017450000013d000000090000006b000016dc0000613d0000000804000029000000020440036700000000050300190000002005500039000000004604043c000000000065043500000008060000290000002006600039000800000006001d000000070060006c000016b80000413d0000000003030433000000000003004b000016dc0000613d0000000503300210000c00000023001d0000000043020434000d00000004001d000000000031004b000000000300003900000020030020390000000000130435000000200130015f0000000002020433000000000021043500000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000d030000290000000c0030006c0000000002030019000016c50000413d0000000b0010006c0000171f0000c13d00000064010000390000000201100367000000000101043b0000088b00100198000010b10000613d0000000501000029000000000010043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b00000024020000390000000202200367000000000202043b000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d000000000101043b0000000f02000029000008d802200197000000000020043f000000200010043f00000064010000390000000201100367000000000101043b000d00000001001d00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000015f90000613d0000000e020000290000088b02200197000000000101043b000000000101041a0000088b0110019700000000012100190000088b0010009c0000177f0000a13d0000095a01000041000000000010043f0000001101000039000000040010043f0000095b010000410000222a00010430000000400100043d00000958020000410000094b0000013d000008e7080000410000002009000039000000010ba0008a000000050bb002700000091e0bb0009a000000000c790019000000000c0c04330000000000c8041b000000200990003900000001088000390000000000b8004b000017270000c13d00000000006a004b000017380000813d000000030a600210000000f80aa0018f000009680aa0027f000009680aa00167000000000779001900000000070704330000000007a7016f000000000078041b000000010660021000000001076001bf000000000075041b000000000003004b000016b00000613d0000000001040019000000000203001922281b5c0000040f0000000201000367000000c402100370000000000202043b000008d8052001980000076c0000613d000008e903000041000000000303041a0000000f0030006b000017700000c13d000000e401100370000000000101043b0000091701100197000027100010008c000006b30000213d000000600220021200000ab10000613d000000000221019f0000091f03000041000000000023041b000000400200043d00000000001204350000088b0020009c0000088b02008041000000400120021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ee011001c70000800d02000039000000020300003900000920040000412228221e0000040f0000000100200190000015f90000613d0000000201000367000000c402100370000000000202043b000008d802200197000000e401100370000000000101043b000000a001100210000000000121019f000000d302000039000000000012041b0000000001000019000022290001042e0000095f01000041000000000010043f000008eb010000410000222a000104300000000307600210000009680770027f00000968077001670000000008090433000000000778016f0000000106600210000000000767019f000000000075041b000000000003004b000016b00000613d0000173d0000013d0000000d020000290000088b02200197000000000021004b000010b10000a13d000014670000013d0000001f03100039000000000023004b0000000004000019000009160400404100000916052001970000091603300197000000000653013f000000000053004b00000000030000190000091603002041000009160060009c000000000304c019000000000003004b0000179c0000613d0000000203100367000000000303043b000008db0030009c0000179c0000213d00000020011000390000000004310019000000000024004b0000179c0000213d0000000002030019000000000001042d00000000010000190000222a000104300000096a0010009c000017a30000813d0000002001100039000000400010043f000000000001042d0000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a000104300000001f0220003900000965022001970000000001120019000000000021004b00000000020000390000000102004039000008db0010009c000017b50000213d0000000100200190000017b50000c13d000000400010043f000000000001042d0000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a0001043000000000430104340000000001320436000000000003004b000017c70000613d000000000200001900000000052100190000000006240019000000000606043300000000006504350000002002200039000000000032004b000017c00000413d000000000231001900000000000204350000001f0230003900000965022001970000000001210019000000000001042d0000001f03100039000000000023004b0000000004000019000009160400404100000916052001970000091603300197000000000653013f000000000053004b00000000030000190000091603002041000009160060009c000000000304c019000000000003004b000017e60000613d0000000203100367000000000303043b000008db0030009c000017e60000213d000000050430021000000020011000390000000004410019000000000024004b000017e60000213d0000000002030019000000000001042d00000000010000190000222a000104300000096b0020009c000018180000813d00000000040100190000001f0120003900000965011001970000003f011000390000096505100197000000400100043d0000000005510019000000000015004b00000000070000390000000107004039000008db0050009c000018180000213d0000000100700190000018180000c13d000000400050043f00000000052104360000000007420019000000000037004b0000181e0000213d00000965062001980000001f0720018f00000002044003670000000003650019000018080000613d000000000804034f0000000009050019000000008a08043c0000000009a90436000000000039004b000018040000c13d000000000007004b000018150000613d000000000464034f0000000306700210000000000703043300000000076701cf000000000767022f000000000404043b0000010006600089000000000464022f00000000046401cf000000000474019f000000000043043500000000022500190000000000020435000000000001042d0000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a0001043000000000010000190000222a00010430000000000301001900000000040104330000000001420436000000000004004b0000182c0000613d00000000020000190000002003300039000000000503043300000000015104360000000102200039000000000042004b000018260000413d000000000001042d0001000000000002000108d80010019c0000184e0000613d000000000020043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f00000001002001900000184c0000613d000000000101043b0000000102000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f00000001002001900000184c0000613d000000000101043b000000000101041a000000000001042d00000000010000190000222a00010430000000400100043d00000064021000390000093103000041000000000032043500000044021000390000093203000041000000000032043500000024021000390000002a0300003900000000003204350000088c0200004100000000002104350000000402100039000000200300003900000000003204350000088b0010009c0000088b010080410000004001100210000008e0011001c70000222a00010430000000cd02000039000000000302041a000000000013004b0000186a0000a13d000000000020043f000009000110009a0000000002000019000000000001042d0000095a01000041000000000010043f0000003201000039000000040010043f0000095b010000410000222a00010430000000ce02000039000000000302041a000000000013004b000018780000a13d000000000020043f0000090c0110009a0000000002000019000000000001042d0000095a01000041000000000010043f0000003201000039000000040010043f0000095b010000410000222a00010430000000c903000039000000000403041a000000000004004b000018940000613d0000000002000019000018870000013d0000000102200039000000000042004b000018930000813d00000006052000c9000009070650009a000000000606041a000000000016004b000018840000213d000009080550009a000000000505041a000000000015004b000018840000a13d000000000030043f0000000001020019000000000001042d000000000030043f000000400100043d000009210200004100000000002104350000088b0010009c0000088b010080410000004001100210000008f2011001c70000222a000104300008000000000002000000d102000039000000000202041a000200000002001d0000096b0020009c000019160000813d000000020200002900000005022002100000003f032000390000090d03300197000000400400043d0000000003340019000500000004001d000000000043004b00000000040000390000000104004039000008db0030009c000019160000213d0000000100400190000019160000c13d000000400030043f000000020300002900000005040000290000000003340436000100000003001d0000001f0320018f000000000002004b000018c00000613d0000000105000029000000000225001900000000040000310000000204400367000000004604043c0000000005650436000000000025004b000018bc0000c13d000000000003004b000000020000006b0000190c0000613d000000c902000039000000000202041a000400000002001d000000000002004b0000190c0000613d000308d80010019b000080100300003900000000040000190000000501400210000600010010002d0000000002000019000800000004001d000700000002001d000000000020043f000000d501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000000002030019222822230000040f00000001002001900000190e0000613d000000000101043b0000000802000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f00000001002001900000190e0000613d000000000101043b0000000302000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f00000001002001900000190e0000613d0000801003000039000000050200002900000000020204330000000804000029000000000042004b000019100000a13d00000006050000290000000002050433000000000101043b000000000101041a0000088b01100197000000000021001a0000191c0000413d0000000001210019000000000015043500000007020000290000000102200039000000040020006c000018cf0000413d0000000104400039000000020040006c000018cb0000413d0000000501000029000000000001042d00000000010000190000222a000104300000095a01000041000000000010043f0000003201000039000000040010043f0000095b010000410000222a000104300000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a000104300000095a01000041000000000010043f0000001101000039000000040010043f0000095b010000410000222a000104300006000000000002000500000001001d000000400100043d000600000001001d0000096c0010009c00001aef0000813d0000000601000029000000c002100039000000400020043f0000000501000029000000000301041a000400000002001d000300000003001d0000000000320435000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f000000010020019000001af50000613d000000000301043b0000000601000029000000e0011000390000000307000029000000030070008c000019ea0000413d0000000004000019000000000203041a000000a0052002700000090a055001970000004006100039000000000056043500000050052002700000090a05500197000000200610003900000000005604350000090a0220019700000000002104350000000302400039000000010330003900000060011000390000000504400039000000000074004b0000000004020019000019410000413d000000000303041a000000000072004b000019ee0000413d000000000072004b000019f30000413d000000000072004b0000195d0000813d000000a0023002700000090a022001970000000001210436000000060110006a000000a10110008a000009650210019700000004030000290000000001320019000000000021004b00000000020000390000000102004039000008db0010009c00001aef0000213d000000010020019000001aef0000c13d000000400010043f00000006010000290000000001310436000100000001001d00000005010000290000000101100039000000000301041a000000400200043d000300000002001d000400000003001d0000000002320436000200000002001d000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f000000010020019000001af50000613d000000000201043b0000000407000029000000080070008c000019fa0000413d00000000010000190000000206000029000000e003600039000000000402041a000000e0054002700000000000530435000000c0034002700000088b03300197000000c0056000390000000000350435000000a0034002700000088b03300197000000a005600039000000000035043500000080034002700000088b033001970000008005600039000000000035043500000060034002700000088b033001970000006005600039000000000035043500000040034002700000088b033001970000004005600039000000000035043500000020034002700000088b03300197000000200560003900000000003504350000088b03400197000000000036043500000001022000390000010006600039000000080110003900000007031001bf000000000073004b000019850000413d000000000202041a000000000071004b000019ff0000413d000000000071004b00001a040000413d000000000071004b00001a0a0000413d000000000071004b00001a100000413d000000000071004b00001a160000413d000000000071004b00001a1c0000413d000000000071004b00001a220000413d0000000303000029000000000071004b000019bd0000813d000000e001200270000000000616043600000000013600490000001f0110003900000965021001970000000001320019000000000021004b00000000020000390000000102004039000008db0010009c00001aef0000213d000000010020019000001aef0000c13d000000400010043f0000000101000029000000000031043500000005010000290000000201100039000000000301041a000000400200043d000400000002001d000200000003001d0000000002320436000300000002001d000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f000000010020019000001af50000613d0000000205000029000000000005004b00001a2a0000613d000000000101043b00000000020000190000000304000029000000000301041a000000000434043600000001011000390000000102200039000000000052004b000019e30000413d00001a2b0000013d0000000002000019000000000303041a000000000070004b000019560000813d0000090a0430019700000000014104360000000102200039000000000072004b000019580000813d00000050043002700000090a0440019700000000014104360000000102200039000000000072004b0000195a0000413d0000195d0000013d00000000010000190000000206000029000000000202041a000000000070004b000019ac0000813d0000088b03200197000000000636043600000001011001bf000000000071004b000019ae0000813d00000020032002700000088b0330019700000000063604360000000101100039000000000071004b000019b00000813d00000040032002700000088b0330019700000000063604360000000101100039000000000071004b000019b20000813d00000060032002700000088b0330019700000000063604360000000101100039000000000071004b000019b40000813d00000080032002700000088b0330019700000000063604360000000101100039000000000071004b000019b60000813d000000a0032002700000088b0330019700000000063604360000000101100039000000000071004b000019b80000813d000000c0032002700000088b03300197000000000636043600000001011000390000000303000029000000000071004b000019bb0000413d000019bd0000013d0000000304000029000000040300002900000000013400490000001f0110003900000965021001970000000001320019000000000021004b00000000020000390000000102004039000008db0010009c00001aef0000213d000000010020019000001aef0000c13d000000400010043f00000006010000290000004001100039000000000031043500000005010000290000000301100039000000000301041a000000400200043d000400000002001d000200000003001d0000000002320436000300000002001d000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f000000010020019000001af50000613d000000000201043b00000002070000290000000a0070008c00001ab30000413d00000000030000190000000306000029000000000102041a000000d8041002700000090b0440019700000120056000390000000000450435000000c0041002700000090b0440019700000100056000390000000000450435000000a8041002700000090b04400197000000e005600039000000000045043500000090041002700000090b04400197000000c005600039000000000045043500000078041002700000090b04400197000000a005600039000000000045043500000060041002700000090b044001970000008005600039000000000045043500000048041002700000090b044001970000006005600039000000000045043500000030041002700000090b044001970000004005600039000000000045043500000018041002700000090b04400197000000200560003900000000004504350000090b0110019700000000001604350000000a01300039000000010220003900000140066000390000001303300039000000000073004b000000000301001900001a530000413d000000000202041a000000000071004b00001ab80000413d000000000071004b00001abd0000413d000000000071004b00001ac30000413d000000000071004b00001ac90000413d000000000071004b00001acf0000413d000000000071004b00001ad50000413d000000000071004b00001adb0000413d000000000071004b00001ae10000413d000000000071004b00001ae70000413d0000000403000029000000000071004b00001a9a0000813d000000d8012002700000090b01100197000000000616043600000000013600490000001f0110003900000965021001970000000001320019000000000021004b00000000020000390000000102004039000008db0010009c00001aef0000213d000000010020019000001aef0000c13d000000400010043f00000006010000290000006002100039000000000032043500000005040000290000000402400039000000000302041a000000800210003900000000003204350000000502400039000000000302041a000000a0021000390000000000320435000000000001042d00000000010000190000000306000029000000000202041a000000000070004b00001a840000813d0000090b0320019700000000063604360000000101100039000000000071004b00001a860000813d00000018032002700000090b0330019700000000063604360000000101100039000000000071004b00001a880000813d00000030032002700000090b0330019700000000063604360000000101100039000000000071004b00001a8a0000813d00000048032002700000090b0330019700000000063604360000000101100039000000000071004b00001a8c0000813d00000060032002700000090b0330019700000000063604360000000101100039000000000071004b00001a8e0000813d00000078032002700000090b0330019700000000063604360000000101100039000000000071004b00001a900000813d00000090032002700000090b0330019700000000063604360000000101100039000000000071004b00001a920000813d000000a8032002700000090b0330019700000000063604360000000101100039000000000071004b00001a940000813d000000c0032002700000090b03300197000000000636043600000001011000390000000403000029000000000071004b00001a970000413d00001a9a0000013d0000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a0001043000000000010000190000222a00010430000008e901000041000000000101041a0000000002000411000000000012004b00001afd0000c13d000000000001042d0000095f01000041000000000010043f000008eb010000410000222a0001043000000000430104340000096b0030009c00001b500000813d0000006702000039000000000502041a000000010650019000000001055002700000007f0550618f0000001f0050008c00000000070000390000000107002039000000000076004b00001b560000c13d000000200050008c00001b1f0000413d000000000020043f0000001f063000390000000506600270000008e80660009a000000200030008c000008e7060040410000001f055000390000000505500270000008e80550009a000000000056004b00001b1f0000813d000000000006041b0000000106600039000000000056004b00001b1b0000413d0000001f0030008c00001b3e0000a13d000000000020043f000009650630019800001b490000613d000008e7040000410000002005000039000000010760008a00000005077002700000091e0770009a00000000081500190000000008080433000000000084041b00000020055000390000000104400039000000000074004b00001b290000c13d000000000036004b00001b3a0000813d0000000306300210000000f80660018f000009680660027f000009680660016700000000011500190000000001010433000000000161016f000000000014041b000000010130021000000001011001bf000000000012041b000000000001042d000000000003004b00001b4e0000613d0000000301300210000009680110027f00000968011001670000000004040433000000000114016f0000000103300210000000000131019f000000000012041b000000000001042d0000002005000039000008e704000041000000000036004b00001b320000413d00001b3a0000013d000000000002041b000000000001042d0000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a000104300000095a01000041000000000010043f0000002201000039000000040010043f0000095b010000410000222a000104300010000000000002000c00000002001d000f00000001001d000000c902000039000000000102041a000000000002041b000000000001004b00001be50000613d00000006021000c9000000060320011a000000000031004b000020280000c13d000000c901000039000000000010043f000009090120009a000d00000001001d0000096d0010009c00001be50000413d0000096e0300004100001b770000013d0000000401300039000000000001041b0000000501300039000000000001041b00000006033000390000000d0030006c00001be50000813d000000000103041a000000000003041b000000000001004b001000000003001d00001b930000613d000e00000001001d000000000030043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000101043b0000000e020000290000000202200039000000030220011a0000000002210019000000000021004b000000100300002900001b930000813d000000000001041b0000000101100039000000000021004b00001b8f0000413d00000001013001bf000000000201041a000000000001041b000000000002004b00001baf0000613d000e00000002001d000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000101043b0000000e02000029000000070220003900000003022002700000000002210019000000000021004b000000100300002900001baf0000813d000000000001041b0000000101100039000000000021004b00001bab0000413d0000000201300039000000000201041a000000000001041b000000000002004b00001bc80000613d000e00000002001d000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000101043b0000000e02100029000000000021004b000000100300002900001bc80000813d000000000001041b0000000101100039000000000021004b00001bc40000413d0000000301300039000000000201041a000000000001041b000000000002004b00001b700000613d000e00000002001d000000000010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000101043b0000000e0200002900000009022000390000000a0220011a0000000002210019000000000021004b000000100300002900001b700000813d000000000001041b0000000101100039000000000021004b00001be00000413d00001b700000013d0000000c0000006b0000200e0000613d0000000f01000029000100a00010003d000200800010003d000000000300001900000005013002100000000f011000290000000004000031001000000004001d0000000f0240006a000000bf0220008a000e00000003001d000000000003004b00001c230000613d0000000203100367000000000303043b00000916042001970000091605300197000000000645013f000000000045004b00000000050000190000091605002041000000000023004b00000000070000190000091607004041000009160060009c000000000507c019000000000005004b0000200f0000613d000000000801001900000002033000290000000203300367000000000303043b0000000e01000029000000010510008a0000000c0050006c0000201f0000813d00000005055002100000000f055000290000000205500367000000000505043b0000091606500197000000000746013f000000000046004b00000000040000190000091604004041000000000025004b00000000060000190000091606008041000009160070009c000000000406c019000000000004004b0000200f0000c13d00000001045000290000000204400367000000000404043b000009680040009c000020280000613d000000000043004b00000000010800190000202e0000a13d000900000001001d0000000203100367000000000303043b00000916042001970000091605300197000000000645013f000000000045004b00000000040000190000091604004041000000000023004b00000000020000190000091602008041000009160060009c000000000402c019000000000004004b0000200f0000c13d0000000f0530002900000080025000390000000202200367000000a0045000390000000203400367000000000303043b000000000102043b000b00000001001d000a00000003001d000000000031004b000020250000813d00000010025000690000001f0920008a0000000202500367000000000402043b000009160b90019700000916024001970000000006b2013f0000000000b2004b00000000020000190000091602004041000000000094004b00000000070000190000091607008041000009160060009c000000000207c019000000000002004b0000200f0000c13d00000000065400190000000202600367000000000402043b000008db0040009c0000200f0000213d000000050d4002100000001002d00069000000200760003900000916062001970000091608700197000000000a68013f000000000068004b00000000060000190000091606004041000000000027004b000000000200001900000916020020410000091600a0009c000000000602c019000000000006004b0000200f0000c13d000000d101000039000000000201041a000000000024004b000020170000c13d00000020085000390000000202800367000000000602043b0000091602600197000000000ab2013f0000000000b2004b00000000020000190000091602004041000000000096004b000000000c000019000009160c0080410000091600a0009c00000000020cc019000000000002004b0000200f0000c13d00000000065600190000000202600367000000000a02043b000008db00a0009c0000200f0000213d000000050ca002100000001002c000690000002006600039000009160e200197000009160f6001970000000003ef013f0000000000ef004b000000000e000019000009160e004041000000000026004b00000000020000190000091602002041000009160030009c000000000e02c01900000000000e004b0000200f0000c13d00000000004a004b000020170000c13d000000200e8000390000000202e00367000000000802043b00000916028001970000000003b2013f0000000000b2004b00000000020000190000091602004041000000000098004b000000000a000019000009160a008041000009160030009c00000000020ac019000000000002004b0000200f0000c13d00000000085800190000000202800367000000000f02043b000008db00f0009c0000200f0000213d0000000502f00210000d00000002001d0000001002200069000000200880003900000916032001970000091601800197000000000a31013f000000000031004b00000000010000190000091601004041000000000028004b000000000200001900000916020020410000091600a0009c000000000102c019000000000001004b0000200f0000c13d00000000004f004b000020170000c13d0000002001e000390000000201100367000000000e01043b0000091601e001970000000002b1013f0000000000b1004b0000000001000019000009160100404100000000009e004b00000000030000190000091603008041000009160020009c000000000103c019000000000001004b0000200f0000c13d00000000055e00190000000201500367000000000901043b000008db0090009c0000200f0000213d000000050b9002100000001001b00069000000200550003900000916021001970000091603500197000000000a23013f000000000023004b00000000020000190000091602004041000000000015004b000000000100001900000916010020410000091600a0009c000000000201c019000000000002004b0000200f0000c13d000000000049004b000020170000c13d000000400900043d0000096c0090009c000020110000813d000000c00e9000390000004000e0043f0000003f01d000390000090d01100197000000000f1e0019000008db00f0009c000020110000213d0000004000f0043f00000000004e0435000000000d7d00190000001000d0006c0000200f0000213d0000000000d7004b00001cf50000813d000000e00f9000390000000201700367000000000201043b0000090a0020009c0000200f0000213d000000000f2f043600000020077000390000000000d7004b00001ced0000413d000000000fe904360000003f01c000390000096501100197000000400700043d000000000d17001900000000007d004b00000000020000390000000102004039000008db00d0009c000020110000213d0000000100200190000020110000c13d0000004000d0043f0000000000470435000000000c6c00190000001000c0006c0000200f0000213d0000000000c6004b00001d120000813d000000000d0700190000000201600367000000000e01043b0000088b00e0009c0000200f0000213d000000200dd000390000000000ed043500000020066000390000000000c6004b00001d090000413d00000000007f04350000000d010000290000003f011000390000090d01100197000000400600043d0000000007160019000000000067004b00000000020000390000000102004039000008db0070009c000020110000213d0000000100200190000020110000c13d000000400070043f00000000004604350000000d07800029000000100070006c0000200f0000213d000000000087004b00001d2e0000a13d000000000a0600190000000201800367000000000101043b000000200aa0003900000000001a04350000002008800039000000000078004b00001d270000413d0000004001900039000800000001001d00000000006104350000003f01b000390000096501100197000000400600043d0000000007160019000000000067004b00000000020000390000000102004039000008db0070009c000020110000213d0000000100200190000020110000c13d000000400070043f000000000046043500000000045b0019000000100040006c0000200f0000213d000000000045004b00001d4d0000813d00000000010600190000000202500367000000000702043b0000090b0070009c0000200f0000213d000000200110003900000000007104350000002005500039000000000045004b00001d440000413d000000a001900039000600000001001d0000000a0200002900000000002104350000008001900039000500000001001d0000000b0200002900000000002104350000006001900039000700000001001d0000000000610435000000c901000039000000000101041a000008db0010009c000020110000213d0000000102100039000000c903000039000000000023041b000000000030043f00000000020904330000000023020434000008db0030009c000020110000213d000a00000002001d000b0000000f001d00000006011000c9001000000001001d000009090410009a000000000104041a000000000034041b000d00000003001d000000000013004b00001d970000813d000300000001001d000400000004001d000000000040043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000201043b0000000d0300002900000002013000390000097201100197000000030110011a0000000001120019000008db03300197000000033030011a000000000003004b00001d8c0000613d0000097c033000d100000100033000390000097303300197000000010410008a000000000504041a00000000053501cf000000000335022f000000000034041b00000003030000290000000203300039000000030330011a0000000002320019000000000021004b000000040400002900001d970000813d000000000001041b0000000101100039000000000021004b00001d930000413d000000000040043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000000b0a0000290000200f0000613d0000000d07000029000000033270011a000000000101043b000000030070008c0000000a0b00002900001dba0000413d000000000400001900000000650b04340000090a05500197000000000606043300000050066002100000097406600197000000000565019f0000004006b000390000000006060433000000a0066002100000097506600197000000000565019f0000000006140019000000000056041b000000600bb000390000000104400039000000000024004b00001da90000413d00000003042000c9000000000047004b00001dcf0000613d0000000004000019000000000500001900000050064000c90000090a0760021f000000ff0060008c0000096808000041000000000887a13f00000000b70b04340000090a0770019700000000066701cf0000000006002019000000000585016f000000000556019f0000000104400039000000000034004b00001dbf0000413d0000000001210019000000000051041b00000000010a04330000000012010434000008db0020009c000020110000213d000b00000001001d0000001001000029000009760310009a000000000103041a000000000023041b000d00000002001d000000000012004b00001e010000813d000400000001001d000a00000003001d000000000030043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000201043b0000000d0300002900000007013000390000000301100270000000000112001900000002033002100000001c0330019000001df60000613d00000003033002100000010003300089000000010410008a000000000504041a00000000053501cf000000000335022f000000000034041b0000000403000029000000070330003900000003033002700000000002320019000000000021004b0000000a0300002900001e010000813d000000000001041b0000000101100039000000000021004b00001dfd0000413d000000000030043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000101043b0000000d0b0000290000000302b002720000000b0a00002900001e290000613d0000000003000019000000010900008a000000000400001900000000060a0019000000000500001900000000670604340000088b07700197000000050840021000000000078701cf0000088b0880021f000000000898013f000000000585016f000000000575019f000000070040008c000000010440003900001e150000413d0000000004130019000000000054041b000001000aa000390000000103300039000000000023004b00001e120000413d0000000703b0019000001e2c0000c13d00001e3b0000013d000000010900008a0000000703b0019000001e3b0000613d0000000004000019000000000500001900000000a60a04340000088b06600197000000050740021000000000067601cf0000088b0770021f000000000797013f000000000575016f000000000556019f0000000104400039000000000034004b00001e2e0000413d0000000001210019000000000051041b00000008010000290000000001010433000b00000001001d0000000002010433000008db0020009c000020110000213d0000001001000029000009770310009a000000000103041a000000000023041b000d00000002001d000000000012004b00001e5e0000813d000800000001001d000a00000003001d000000000030043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000201043b00000008012000290000000d02200029000000000012004b0000000a0300002900001e5e0000813d000000000002041b0000000102200039000000000012004b00001e5a0000413d000000000030043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000101043b0000000d06000029000000000006004b0000000b0500002900001e750000613d0000000002000019000000000312001900000020055000390000000004050433000000000043041b0000000102200039000000000062004b00001e6e0000413d000000070100002900000000010104330000000012010434000008db0020009c000020110000213d000b00000001001d0000001001000029000009780310009a000000000103041a000000000023041b000d00000002001d000000000012004b00001eab0000813d000800000001001d000a00000003001d000000000030043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d000000000201043b0000000d03000029000000090130003900000972011001970000000a0110011a0000000001120019000008db033001970000000a3030011a000000000003004b00001ea00000613d00000018033000c900000979033001970000010003300089000000010410008a000000000504041a00000000053501cf000000000335022f000000000034041b000000080300002900000009033000390000000a0330011a0000000002320019000000000021004b0000000a0300002900001eab0000813d000000000001041b0000000101100039000000000021004b00001ea70000413d000000000030043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008ee011001c70000801002000039222822230000040f00000001002001900000200f0000613d0000000d0d0000290000000a32d0011a000000000101043b0000000a00d0008c0000000b0c00002900001ebe0000813d000000010a00008a0000000e0b00002900001ed50000013d0000000004000019000000010a00008a0000000e0b000029000000000500001900000000070c0019000000000600001900000000780704340000090b0880019700000018095000c900000000089801cf0000090b0990021f0000000009a9013f000000000696016f000000000686019f000000090050008c000000010550003900001ec40000413d0000000005140019000000000065041b000001400cc000390000000104400039000000000024004b00001ec10000413d0000000a042000c900000000004d004b00001eea0000613d0000000004000019000000000500001900000018064000c90000090b0760021f000000ff0060008c00000000080a0019000000000887a13f00000000c70c04340000090b0770019700000000066701cf0000000006002019000000000585016f000000000556019f0000000104400039000000000034004b00001eda0000413d0000000001210019000000000051041b000000050100002900000000010104330000001003000029000009070230009a000000000012041b000009080130009a00000006020000290000000002020433000000000021041b0000000c00b0006c0000201f0000813d00000002010003670000000902100360000000000202043b000000000f0000310000000f03f0006a000000bf0330008a00000916043001970000091605200197000000000645013f000000000045004b00000000040000190000091604004041000000000032004b00000000030000190000091603008041000009160060009c000000000403c019000000000004004b0000200f0000c13d0000000f06200029000000000261034f000000000202043b00000000036f00490000001f0930008a000009160a90019700000916032001970000000004a3013f0000000000a3004b00000000030000190000091603004041000000000092004b00000000050000190000091605008041000009160040009c000000000305c019000000000003004b0000200f0000c13d0000000003620019000000000231034f000000000202043b000008db0020009c0000200f0000213d000000050420021000000000054f0049000000200430003900000916035001970000091607400197000000000b37013f000000000037004b00000000030000190000091603004041000000000054004b000000000500001900000916050020410000091600b0009c000000000305c019000000000003004b0000200f0000c13d0000002005600039000000000351034f000000000303043b0000091607300197000000000ba7013f0000000000a7004b00000000070000190000091607004041000000000093004b000000000c000019000009160c0080410000091600b0009c00000000070cc019000000000007004b0000200f0000c13d0000000007630019000000000371034f000000000303043b000008db0030009c0000200f0000213d000000050b300210000000000bbf00490000002007700039000009160cb00197000009160d700197000000000ecd013f0000000000cd004b000000000c000019000009160c0040410000000000b7004b000000000b000019000009160b0020410000091600e0009c000000000c0bc01900000000000c004b0000200f0000c13d000000200b5000390000000005b1034f000000000505043b000009160c500197000000000dac013f0000000000ac004b000000000c000019000009160c004041000000000095004b000000000e000019000009160e0080410000091600d0009c000000000c0ec01900000000000c004b0000200f0000c13d000000000c6500190000000005c1034f000000000805043b000008db0080009c0000200f0000213d000d0005008002180000000d0ef0006a001000000008001d000000200dc000390000000005060019000000000609001900000000090f0019000009160fe00197000009160cd001970000000008fc013f0000000000fc004b000000000c000019000009160c004041000a0000000d001d0000000000ed004b000000100d000029000000000e000019000009160e002041000009160080009c000000000c0ec01900000000000c004b0000200f0000c13d000000000f09001900000000090600190000000006050019000000200bb000390000000005b1034f000000000e05043b0000091605e00197000000000ca5013f0000000000a5004b0000000005000019000009160500404100000000009e004b000000000900001900000916090080410000091600c0009c000000000509c019000000000005004b0000200f0000c13d00000000096e0019000000000591034f000000000605043b000008db0060009c0000200f0000213d000000050560021000000000055f004900000020089000390000091609500197000009160a800197000000000c9a013f00000000009a004b00000000090000190000091609004041000000000058004b000000000500001900000916050020410000091600c0009c000000000905c019000000000009004b0000200f0000c13d0000002005b00039000000000551034f0000004009b00039000000000991034f000000000909043b000b00000009001d000000000c05043b000000400900043d000000c0059000390000000000250435000000c005000039000000000e590436000000e00f900039000000000002004b00001fbd0000613d000000000a000019000000000541034f000000000b05043b0000090a00b0009c0000200f0000213d000000000fbf04360000002004400039000000010aa0003900000000002a004b00001fb40000413d00000000029f004900000000002e043500000000023f0436000000000003004b00001fcc0000613d0000000004000019000000000571034f000000000a05043b0000088b00a0009c0000200f0000213d0000000002a2043600000020077000390000000104400039000000000034004b00001fc30000413d0000000003920049000000400490003900000000003404350000000003d204360000097a00d0009c0000200f0000213d0000000d0a00002900000000000a004b00001fdb0000613d0000000a041003600000000007a30019000000004504043c0000000003530436000000000073004b00001fd70000c13d0000001f00a001900000000002a200190000000003920049000000200330003900000060049000390000000000340435000000200320003900000000006304350000004002200039000000000006004b00001ff00000613d0000000003000019000000000481034f000000000404043b0000090b0040009c0000200f0000213d000000000242043600000020088000390000000103300039000000000063004b00001fe70000413d000000a0019000390000000b03000029000000000031043500000080019000390000000000c1043500000000019200490000088b0010009c0000088b0100804100000060011002100000088b0090009c0000088b090080410000004002900210000000000121019f00000000020004140000088b0020009c0000088b02008041000000c002200210000000000121019f000008ec011001c70000800d0200003900000002030000390000097b040000410000000e050000292228221e0000040f00000001002001900000200f0000613d0000000e0300002900000001033000390000000c0030006c00001beb0000413d000000000001042d00000000010000190000222a000104300000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a00010430000000400100043d000009710200004100000000002104350000088b0010009c0000088b010080410000004001100210000008f2011001c70000222a000104300000095a01000041000000000010043f0000003201000039000000040010043f0000095b010000410000222a00010430000000400100043d0000097002000041000020190000013d0000095a01000041000000000010043f0000001101000039000000040010043f0000095b010000410000222a00010430000000400100043d0000096f02000041000020190000013d000b000000000002000100000004001d000400000003001d000500000002001d0000000002010019000000400300043d000308d80010019c000021310000613d000200000002001d000009570030009c000021b20000813d0000004001300039000000400010043f000000010100003900000000041304360000000502000029000900000004001d0000000000240435000000400400043d000008f60040009c000021b20000213d0000004002400039000000400020043f00000000021404360000000401000029000800000002001d00000000001204350000000001030433000000000001004b000020760000613d0000000002000019000700000003001d000600000004001d0000000001040433000000000021004b0000212b0000a13d000b00000002001d0000000501200210000000090210002900000008011000290000000001010433000a00000001001d0000000001020433000000000010043f0000009701000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000021290000613d000000000101043b000000000201041a0000000a04000029000000000042001a0000000703000029000021b80000413d0000000002420019000000000021041b0000000b0200002900000001022000390000000001030433000000000012004b0000000604000029000020520000413d0000000501000029000000000010043f0000006501000039000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000021290000613d000000000101043b0000000302000029000000000020043f000000200010043f00000000010004140000088b0010009c0000088b01008041000000c001100210000008f5011001c70000801002000039222822230000040f0000000100200190000021290000613d000000000101043b000000000201041a000000040020002a000021b80000413d00000004030000290000000002320019000000000021041b000000400100043d00000020021000390000000000320435000000050200002900000000002104350000088b0010009c0000088b01008041000000400110021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008f5011001c70000800d0200003900000004030000390000000005000411000008f704000041000000000600001900000003070000292228221e0000040f0000000100200190000021290000613d000008dc0100004100000000001004430000000201000029000000040010044300000000010004140000088b0010009c0000088b01008041000000c001100210000008dd011001c70000800202000039222822230000040f0000000100200190000021440000613d000000000101043b000000000001004b000021280000613d000000400700043d0000008401700039000000a0020000390000000000210435000000640170003900000004020000290000000000210435000000440170003900000005020000290000000000210435000008f80100004100000000001704350000000401700039000000000200041100000000002104350000002401700039000000000001043500000001010000290000000031010434000000a4027000390000000000120435000000c402700039000000000001004b000020de0000613d000000000400001900000000052400190000000006430019000000000606043300000000006504350000002004400039000000000014004b000020d70000413d0000001f03100039000009650330019700000000011200190000000000010435000000000173004900000000012100190000088b0010009c0000088b0100804100000060011002100000088b0070009c0000088b0200004100000000020740190000004002200210000000000121019f00000000020004140000088b0020009c0000088b02008041000000c002200210000000000121019f0000000302000029000b00000007001d2228221e0000040f0000000b0b00002900000060031002700000088b03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000021040000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000021000000c13d000000000006004b000021110000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000021450000613d0000001f01400039000000600110018f0000000002b10019000000000012004b00000000010000390000000101004039000008db0020009c000021b20000213d0000000100100190000021b20000c13d000000400020043f000000200030008c000021290000413d00000000010b0433000008f900100198000021290000c13d000008fa01100197000008f80010009c000021810000c13d000000000001042d00000000010000190000222a000104300000095a01000041000000000010043f0000003201000039000000040010043f0000095b010000410000222a0001043000000064013000390000097d02000041000000000021043500000044013000390000097e0200004100000000002104350000002401300039000000210200003900000000002104350000088c0100004100000000001304350000000401300039000000200200003900000000002104350000088b0030009c0000088b030080410000004001300210000008e0011001c70000222a00010430000000000001042f000000040230008c0000217a0000413d000000000400043d000008f904400197000000000501043b000008fa05500197000000000445019f000000000040043f000008fa044001970000088c0040009c0000217a0000c13d000000440030008c0000217a0000413d000000040510037000000965062001980000001f0720018f000000400400043d00000000016400190000215e0000613d000000000805034f0000000009040019000000008a08043c0000000009a90436000000000019004b0000215a0000c13d000000000007004b0000216b0000613d000000000565034f0000000306700210000000000701043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f00000000005104350000000005040433000008db0050009c0000217a0000213d0000002401500039000000000031004b0000217a0000213d00000000014500190000000003010433000008db0030009c0000217a0000213d000000000224001900000000063100190000002006600039000000000026004b000021900000a13d000000400200043d000b00000002001d0000088c0100004100000000001204350000000401200039222821e40000040f000021860000013d0000088c0100004100000000001204350000000401200039000b00000002001d222821d70000040f0000000b0200002900000000012100490000088b0010009c0000088b0100804100000060011002100000088b0020009c0000088b020080410000004002200210000000000121019f0000222a0001043000000000023500190000003f0220003900000965022001970000000004420019000000000024004b00000000020000390000000102004039000008db0040009c000021b20000213d0000000100200190000021b20000c13d0000000003040019000000400040043f000000000001004b0000217a0000613d0000088c020000410000000004030019000b00000003001d00000000002304350000000402300039000000200300003900000000003204350000002402400039222817bb0000040f0000000b0200002900000000012100490000088b0010009c0000088b010080410000088b0020009c0000088b0200804100000060011002100000004002200210000000000121019f0000222a000104300000095a01000041000000000010043f0000004101000039000000040010043f0000095b010000410000222a000104300000095a01000041000000000010043f0000001101000039000000040010043f0000095b010000410000222a000104300001000000000002000008e902000041000000000502041a0000000002000414000008d8061001970000088b0020009c0000088b02008041000000c001200210000008ec011001c70000800d020000390000000303000039000008ed04000041000100000006001d2228221e0000040f0000000100200190000021d50000613d000000010000006b0000000001000019000009160100604100000001011001af000008e902000041000000000012041b000000000001042d00000000010000190000222a0001043000000060021000390000097f030000410000000000320435000000400210003900000980030000410000000000320435000000200210003900000028030000390000000000320435000000200200003900000000002104350000008001100039000000000001042d000000600210003900000981030000410000000000320435000000400210003900000982030000410000000000320435000000200210003900000034030000390000000000320435000000200200003900000000002104350000008001100039000000000001042d000000000001042f0000088b0010009c0000088b0100804100000040011002100000088b0020009c0000088b020080410000006002200210000000000112019f00000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f000008ec011001c70000801002000039222822230000040f0000000100200190000022050000613d000000000101043b000000000001042d00000000010000190000222a0001043000000000050100190000000000200443000000040030008c0000220e0000a13d0000000501400270000000000101003100000004001004430000088b0030009c0000088b03008041000000600130021000000000020004140000088b0020009c0000088b02008041000000c002200210000000000112019f00000983011001c70000000002050019222822230000040f00000001002001900000221d0000613d000000000101043b000000000001042d000000000001042f00002221002104210000000102000039000000000001042d0000000002000019000000000001042d00002226002104230000000102000039000000000001042d0000000002000019000000000001042d0000222800000432000022290001042e0000222a00010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff08c379a000000000000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320696e697469616c697a696e6700000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000080000000000000000002000000000000000000000000000000000000200000008000000000000000007f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000715018a500000000000000000000000000000000000000000000000000000000bd85b03800000000000000000000000000000000000000000000000000000000e985e9c400000000000000000000000000000000000000000000000000000000f242432900000000000000000000000000000000000000000000000000000000f542033e00000000000000000000000000000000000000000000000000000000f542033f00000000000000000000000000000000000000000000000000000000fee81cf400000000000000000000000000000000000000000000000000000000f242432a00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000e985e9c500000000000000000000000000000000000000000000000000000000eddd0d9c00000000000000000000000000000000000000000000000000000000f04e283e00000000000000000000000000000000000000000000000000000000df51e12100000000000000000000000000000000000000000000000000000000df51e12200000000000000000000000000000000000000000000000000000000e8a3d48500000000000000000000000000000000000000000000000000000000e8e61bb800000000000000000000000000000000000000000000000000000000bd85b03900000000000000000000000000000000000000000000000000000000c3db27c100000000000000000000000000000000000000000000000000000000cfc0ee430000000000000000000000000000000000000000000000000000000095d89b40000000000000000000000000000000000000000000000000000000009cd2370600000000000000000000000000000000000000000000000000000000a3759f5f00000000000000000000000000000000000000000000000000000000a3759f6000000000000000000000000000000000000000000000000000000000bc1712b6000000000000000000000000000000000000000000000000000000009cd2370700000000000000000000000000000000000000000000000000000000a22cb4650000000000000000000000000000000000000000000000000000000095d89b410000000000000000000000000000000000000000000000000000000097cf84fc000000000000000000000000000000000000000000000000000000009823560c00000000000000000000000000000000000000000000000000000000842392c100000000000000000000000000000000000000000000000000000000842392c2000000000000000000000000000000000000000000000000000000008da5cb5b00000000000000000000000000000000000000000000000000000000938e3d7b00000000000000000000000000000000000000000000000000000000715018a60000000000000000000000000000000000000000000000000000000072bbedb8000000000000000000000000000000000000000000000000000000007a5caab3000000000000000000000000000000000000000000000000000000002d759d0e00000000000000000000000000000000000000000000000000000000475ae0380000000000000000000000000000000000000000000000000000000054d1f13c000000000000000000000000000000000000000000000000000000005f710f5b000000000000000000000000000000000000000000000000000000005f710f5c0000000000000000000000000000000000000000000000000000000070da24ee0000000000000000000000000000000000000000000000000000000054d1f13d000000000000000000000000000000000000000000000000000000005944c75300000000000000000000000000000000000000000000000000000000475ae039000000000000000000000000000000000000000000000000000000004e1273f4000000000000000000000000000000000000000000000000000000004f558e79000000000000000000000000000000000000000000000000000000003115bba6000000000000000000000000000000000000000000000000000000003115bba7000000000000000000000000000000000000000000000000000000003ccfd60b00000000000000000000000000000000000000000000000000000000424aa884000000000000000000000000000000000000000000000000000000002d759d0f000000000000000000000000000000000000000000000000000000002eb2c2d6000000000000000000000000000000000000000000000000000000002ed6d5e800000000000000000000000000000000000000000000000000000000143e55d60000000000000000000000000000000000000000000000000000000025692961000000000000000000000000000000000000000000000000000000002569296200000000000000000000000000000000000000000000000000000000274a204b000000000000000000000000000000000000000000000000000000002a55205a00000000000000000000000000000000000000000000000000000000143e55d7000000000000000000000000000000000000000000000000000000002121dc750000000000000000000000000000000000000000000000000000000022fe44c30000000000000000000000000000000000000000000000000000000004634d8c0000000000000000000000000000000000000000000000000000000004634d8d0000000000000000000000000000000000000000000000000000000006fdde03000000000000000000000000000000000000000000000000000000000e89341c0000000000000000000000000000000000000000000000000000000000fdd58e0000000000000000000000000000000000000000000000000000000001ffc9a70000000000000000000000000000000000000000000000000000000002fe5305000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000389a75e10000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff1806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000647920696e697469616c697a6564000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c7265610000000000000000000000000000000000000084000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000bd28d98b68b096b4a0aea6a6cdbceeb2c75a3c63762949d011f9e00adcdbf11f42d72674974f694b5f5159593243114d38a5c39c89d6b62fee061ff523240ee158317c92fcd4d409d481df68571f5927514cabfa52ead8e1692c4fe775e2f905a7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06fb000000000000000000000000000000000000000000000000ffffffffffffffdf9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae68781146e01cefedca1b589f9c38fdc134bf06dc0686e99c63a67a6d05cf2952ffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927000000000000000000000000000000000000000000000000000000000dc149f000000000000000000000000000000000000000040000001c000000000000000002000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e002000000000000000000000000000000000000200000000000000000000000006e697469616c697a696e67000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069cd6225f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000007448fbae000000000000000000000000000000000000000000000000ffffffffffffff7f0200000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffbfc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62f23a6e610000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000c0000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d955391320200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000006f5e8818276a443d2b2c8332fc729f4de8847f12625c9f099e07b8501c91df8a4fcb12107c6874b3963b72268754bc01cf0f889ead6b06c704806c92614cbf1ae15824d286170762000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000800000000000000000c95161027a9b2f0376fa8fa5f504100ccc4748c73f4e479bac3778d02ee5621cfb7af649000000000000000000000000000000000000000000000000000000009780e26d96b1f2a9a18ef8fc72d589dbf03ef788137b64f43897e83a91e7feec0000000000000000000000000000000000000000000000929eee149b4bd212689941b0eaa3a10d142c88d4dd70d0ff97e1b12a7d9324c4e6bc33ee52ea52e2d49941b0eaa3a10d142c88d4dd70d0ff97e1b12a7d9324c4e6bc33ee52ea52e2d39941b0eaa3a10d142c88d4dd70d0ff97e1b12a7d9324c4e6bc33ee52ea52e2d800000000000000000000000000000000000000000000ffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000ffffff2c932e38b10728cd927fde48893e704a5a8db4808436c3d0bd1bc1ef10d82ed67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000000000640000001c0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000ab143c060000000000000000000000ff0000000000000000000000000000000000000000455243313135354d496e697469616c697a61626c650000000000000000000000312e302e32000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff8dd7a915000000000000000000000000000000000000000000000000000000000b0fe384000000000000000000000000000000000000000000000000000000000590c51300000000000000000000000000000000000000000000000000000000ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff0000000000000000000000010000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000068781146e01cefedca1b589f9c38fdc134bf06dc0686e99c63a67a6d05cf29510000000000000000000000000000000000000000000000aa4ec00224afccfdb78a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76efe82a532900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000140000000000000000017307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c660000000000000000000000000000000000000000000000bcde07732ba7563e295b3edc0bf5ec939a471d93d850a58a6f2902c0ed323728aff731f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000687f1d92694e0d565e7107038d2a76240fc10877ec849b0bc76817c56e180114a5d4097edda6d87cb9329af83fb3712ef77eeb13738ffe43cc35a4ce305ad962e6be4d6cc04eb0219337b22db08c688969a9ec8e34d9a0a2ba38a114e050f1ae7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33cfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92206d69736d617463680000000000000000000000000000000000000000000000455243313135353a206163636f756e747320616e6420696473206c656e67746800000000000000000000000000000000000000000000003fffffffffffffffe0616c6964206f776e657200000000000000000000000000000000000000000000455243313135353a2061646472657373207a65726f206973206e6f7420612076c6711413797b8a562634e98c95d50e7619d39702ed5b82ce335dc93546c3a88c0000000000000000000000000b98151bedee73f9ba5f2c7b72dea02d38ce49fc00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000003ffffffe000000000000000000000000000000000000000000000000000000000ffffffe090b8ec18000000000000000000000000000000000000000000000000000000009cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f39750b219c000000000000000000000000000000000000000000000000000000005b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d800113cb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070a08231000000000000000000000000000000000000000000000000000000000000002400000010000000000000000000000000000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000000000440000001000000000000000000000000000000000000000000000000000000000000000000000000090b8ec18be7426aee8a34d0263892b55ce65ce81d8f4c806eb4719e59015ea49feb92d22f4d678b800000000000000000000000000000000000000000000000000000000a47ca0b7000000000000000000000000000000000000000000000000000000006572206f7220617070726f766564000000000000000000000000000000000000455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e6d69736d61746368000000000000000000000000000000000000000000000000455243313135353a2069647320616e6420616d6f756e7473206c656e67746820dc8d8db70000000000000000000000000000000000000000000000000000000072207472616e7366657200000000000000000000000000000000000000000000455243313135353a20696e73756666696369656e742062616c616e636520666f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fbbc197c81000000000000000000000000000000000000000000000000000000006472657373000000000000000000000000000000000000000000000000000000455243313135353a207472616e7366657220746f20746865207a65726f20616400000000000000000000000000000000000000400000000000000000000000003f6cc768000000000000000000000000000000000000000000000000000000000c899f003b7b88b925c6cdfe9b56bc4df2b91107f0f6d1cec1c3538d156bbe48fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d00dbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d0342112400000000000000000000000000000000000000000000000000000000ea2609da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffc009bde33900000000000000000000000000000000000000000000000000000000b4f3729b000000000000000000000000000000000000000000000000000000004e487b71000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000000000007939f424e2f844a000000000000000000000000000000000000000000000000000000000ea8e4eb5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082b4290000000000000000000000000000000000000000000000000000000000b4457eaa00000000000000000000000000000000000000000000000000000000350a88b301ffc9a700000000000000000000000000000000000000000000000000000000d9b67a26000000000000000000000000000000000000000000000000000000000e89341c00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff000000000000000000000000000000000000000000000000ffffffffffffffe00000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ffffffffffffff4066be4f155c5ef2ebd3772b228f2f00681e4ed5826cdb3b1943cc11ad15ad1d2966be4f155c5ef2ebd3772b228f2f00681e4ed5826cdb3b1943cc11ad15ad1d286bc1af93000000000000000000000000000000000000000000000000000000002ea042aa000000000000000000000000000000000000000000000000000000009efdc09e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000fffffffffffffff0000000000000000000000000ffffffffffffffffffff000000000000000000000000ffffffffffffffffffff00000000000000000000000000000000000000009941b0eaa3a10d142c88d4dd70d0ff97e1b12a7d9324c4e6bc33ee52ea52e2d79941b0eaa3a10d142c88d4dd70d0ff97e1b12a7d9324c4e6bc33ee52ea52e2d69941b0eaa3a10d142c88d4dd70d0ff97e1b12a7d9324c4e6bc33ee52ea52e2d5000000000000000000000000000000000000000000000000fffffffffffffff807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4018d72996080abeebe504164b26fd9c42a9ddaba9caf74a9d608f07fa87f322ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb07300000000000000000000000000000000000000000000000000000000000000455243313135353a206d696e7420746f20746865207a65726f206164647265736420746f6b656e73000000000000000000000000000000000000000000000000455243313135353a204552433131353552656365697665722072656a65637465526563656976657220696d706c656d656e746572000000000000000000000000455243313135353a207472616e7366657220746f206e6f6e2d455243313135350200000200000000000000000000000000000000000000000000000000000000904ad492450ff9289a7cfa12dee43bd08e9e325d261285b38e570de0128eb020
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.