Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 13 from a total of 13 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Stages | 18605837 | 847 days ago | IN | 0 ETH | 0.00073242 | ||||
| Mint | 18447403 | 869 days ago | IN | 0.05 ETH | 0.0014383 | ||||
| Mint | 18383077 | 878 days ago | IN | 0.5 ETH | 0.00105387 | ||||
| Withdraw | 18382295 | 878 days ago | IN | 0 ETH | 0.00014757 | ||||
| Mint | 18381843 | 879 days ago | IN | 0.5 ETH | 0.00096286 | ||||
| Mint | 18263519 | 895 days ago | IN | 0.25 ETH | 0.00213779 | ||||
| Mint | 18078328 | 921 days ago | IN | 0.25 ETH | 0.0042179 | ||||
| Set Stages | 18070287 | 922 days ago | IN | 0 ETH | 0.00041028 | ||||
| Set Stages | 18049558 | 925 days ago | IN | 0 ETH | 0.00107952 | ||||
| Mint | 18046257 | 926 days ago | IN | 0.4 ETH | 0.0013699 | ||||
| Mint | 18039228 | 927 days ago | IN | 0.1 ETH | 0.00202457 | ||||
| Set Stages | 18037114 | 927 days ago | IN | 0 ETH | 0.00108224 | ||||
| Set Stages | 18037108 | 927 days ago | IN | 0 ETH | 0.00173265 |
Latest 14 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 18447403 | 869 days ago | 0.04924242 ETH | ||||
| Transfer | 18447403 | 869 days ago | 0.00075757 ETH | ||||
| Transfer | 18383077 | 878 days ago | 0.42424242 ETH | ||||
| Transfer | 18383077 | 878 days ago | 0.07575757 ETH | ||||
| Transfer | 18381843 | 879 days ago | 0.42424242 ETH | ||||
| Transfer | 18381843 | 879 days ago | 0.07575757 ETH | ||||
| Transfer | 18263519 | 895 days ago | 0.2310606 ETH | ||||
| Transfer | 18263519 | 895 days ago | 0.01893939 ETH | ||||
| Transfer | 18078328 | 921 days ago | 0.2310606 ETH | ||||
| Transfer | 18078328 | 921 days ago | 0.01893939 ETH | ||||
| Transfer | 18046257 | 926 days ago | 0.35151515 ETH | ||||
| Transfer | 18046257 | 926 days ago | 0.04848484 ETH | ||||
| Transfer | 18039228 | 927 days ago | 0.09696969 ETH | ||||
| Transfer | 18039228 | 927 days ago | 0.0030303 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BUNNYGIRLS
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2023-08-31
*/
// File: contracts/operator-filter-registry/lib/Constants.sol
pragma solidity ^0.8.13;
address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;
// File: contracts/operator-filter-registry/IOperatorFilterRegistry.sol
pragma solidity ^0.8.13;
interface IOperatorFilterRegistry {
/**
* @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
* true if supplied registrant address is not registered.
*/
function isOperatorAllowed(address registrant, address operator) external view returns (bool);
/**
* @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
*/
function register(address registrant) external;
/**
* @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
*/
function registerAndSubscribe(address registrant, address subscription) external;
/**
* @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
* address without subscribing.
*/
function registerAndCopyEntries(address registrant, address registrantToCopy) external;
/**
* @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
* Note that this does not remove any filtered addresses or codeHashes.
* Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
*/
function unregister(address addr) external;
/**
* @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
*/
function updateOperator(address registrant, address operator, bool filtered) external;
/**
* @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
*/
function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
/**
* @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
*/
function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
/**
* @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
*/
function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
/**
* @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
* subscription if present.
* Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
* subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
* used.
*/
function subscribe(address registrant, address registrantToSubscribe) external;
/**
* @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
*/
function unsubscribe(address registrant, bool copyExistingEntries) external;
/**
* @notice Get the subscription address of a given registrant, if any.
*/
function subscriptionOf(address addr) external returns (address registrant);
/**
* @notice Get the set of addresses subscribed to a given registrant.
* Note that order is not guaranteed as updates are made.
*/
function subscribers(address registrant) external returns (address[] memory);
/**
* @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
* Note that order is not guaranteed as updates are made.
*/
function subscriberAt(address registrant, uint256 index) external returns (address);
/**
* @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
*/
function copyEntriesOf(address registrant, address registrantToCopy) external;
/**
* @notice Returns true if operator is filtered by a given address or its subscription.
*/
function isOperatorFiltered(address registrant, address operator) external returns (bool);
/**
* @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
*/
function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
/**
* @notice Returns true if a codeHash is filtered by a given address or its subscription.
*/
function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
/**
* @notice Returns a list of filtered operators for a given address or its subscription.
*/
function filteredOperators(address addr) external returns (address[] memory);
/**
* @notice Returns the set of filtered codeHashes for a given address or its subscription.
* Note that order is not guaranteed as updates are made.
*/
function filteredCodeHashes(address addr) external returns (bytes32[] memory);
/**
* @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
* its subscription.
* Note that order is not guaranteed as updates are made.
*/
function filteredOperatorAt(address registrant, uint256 index) external returns (address);
/**
* @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
* its subscription.
* Note that order is not guaranteed as updates are made.
*/
function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
/**
* @notice Returns true if an address has registered
*/
function isRegistered(address addr) external returns (bool);
/**
* @dev Convenience method to compute the code hash of an arbitrary contract
*/
function codeHashOf(address addr) external returns (bytes32);
}
// File: contracts/operator-filter-registry/OperatorFilterer.sol
pragma solidity ^0.8.13;
/**
* @title OperatorFilterer
* @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
* registrant's entries in the OperatorFilterRegistry.
* @dev This smart contract is meant to be inherited by token contracts so they can use the following:
* - 'onlyAllowedOperator' modifier for 'transferFrom' and 'safeTransferFrom' methods.
* - 'onlyAllowedOperatorApproval' modifier for 'approve' and 'setApprovalForAll' methods.
* Please note that if your token contract does not provide an owner with EIP-173, it must provide
* administration methods on the contract itself to interact with the registry otherwise the subscription
* will be locked to the options set during construction.
*/
abstract contract OperatorFilterer {
/// @dev Emitted when an operator is not allowed.
error OperatorNotAllowed(address operator);
IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS);
/// @dev The constructor that is called when the contract is being deployed.
constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
// If an inheriting token contract is deployed to a network without the registry deployed, the modifier
// will not revert, but the contract will need to be registered with the registry once it is deployed in
// order for the modifier to filter addresses.
if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
if (subscribe) {
OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
} else {
if (subscriptionOrRegistrantToCopy != address(0)) {
OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
} else {
OPERATOR_FILTER_REGISTRY.register(address(this));
}
}
}
}
/**
* @dev A helper function to check if an operator is allowed.
*/
modifier onlyAllowedOperator(address from) virtual {
// Allow spending tokens from addresses with balance
// Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
// from an EOA.
if (from != msg.sender) {
_checkFilterOperator(msg.sender);
}
_;
}
/**
* @dev A helper function to check if an operator approval is allowed.
*/
modifier onlyAllowedOperatorApproval(address operator) virtual {
_checkFilterOperator(operator);
_;
}
/**
* @dev A helper function to check if an operator is allowed.
*/
function _checkFilterOperator(address operator) internal view virtual {
// Check registry code length to facilitate testing in environments without a deployed registry.
if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
// under normal circumstances, this function will revert rather than return false, but inheriting contracts
// may specify their own OperatorFilterRegistry implementations, which may behave differently
if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
revert OperatorNotAllowed(operator);
}
}
}
}
// File: contracts/operator-filter-registry/DefaultOperatorFilterer.sol
pragma solidity ^0.8.13;
/**
* @title DefaultOperatorFilterer
* @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
* @dev Please note that if your token contract does not provide an owner with EIP-173, it must provide
* administration methods on the contract itself to interact with the registry otherwise the subscription
* will be locked to the options set during construction.
*/
abstract contract DefaultOperatorFilterer is OperatorFilterer {
/// @dev The constructor that is called when the contract is being deployed.
constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {}
}
// File: erc721a/contracts/IERC721A.sol
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
pragma solidity ^0.8.4;
/**
* @dev Interface of ERC721A.
*/
interface IERC721A {
/**
* The caller must own the token or be an approved operator.
*/
error ApprovalCallerNotOwnerNorApproved();
/**
* The token does not exist.
*/
error ApprovalQueryForNonexistentToken();
/**
* Cannot query the balance for the zero address.
*/
error BalanceQueryForZeroAddress();
/**
* Cannot mint to the zero address.
*/
error MintToZeroAddress();
/**
* The quantity of tokens minted must be more than zero.
*/
error MintZeroQuantity();
/**
* The token does not exist.
*/
error OwnerQueryForNonexistentToken();
/**
* The caller must own the token or be an approved operator.
*/
error TransferCallerNotOwnerNorApproved();
/**
* The token must be owned by 'from'.
*/
error TransferFromIncorrectOwner();
/**
* Cannot safely transfer to a contract that does not implement the
* ERC721Receiver interface.
*/
error TransferToNonERC721ReceiverImplementer();
/**
* Cannot transfer to the zero address.
*/
error TransferToZeroAddress();
/**
* The token does not exist.
*/
error URIQueryForNonexistentToken();
/**
* The 'quantity' minted with ERC2309 exceeds the safety limit.
*/
error MintERC2309QuantityExceedsLimit();
/**
* The 'extraData' cannot be set on an unintialized ownership slot.
*/
error OwnershipNotInitializedForExtraData();
// =============================================================
// STRUCTS
// =============================================================
struct TokenOwnership {
// The address of the owner.
address addr;
// Stores the start time of ownership with minimal overhead for tokenomics.
uint64 startTimestamp;
// Whether the token has been burned.
bool burned;
// Arbitrary data similar to 'startTimestamp' that can be set via {_extraData}.
uint24 extraData;
}
// =============================================================
// TOKEN COUNTERS
// =============================================================
/**
* @dev Returns the total number of tokens in existence.
* Burned tokens will reduce the count.
* To get the total number of tokens minted, please see {_totalMinted}.
*/
function totalSupply() external view returns (uint256);
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* 'interfaceId'. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
// =============================================================
// IERC721
// =============================================================
/**
* @dev Emitted when 'tokenId' token is transferred from 'from' to 'to'.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when 'owner' enables 'approved' to manage the 'tokenId' token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when 'owner' enables or disables
* ('approved') 'operator' to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in 'owner''s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the 'tokenId' token.
*
* Requirements:
*
* - 'tokenId' must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers 'tokenId' token from 'from' to 'to',
* checking first that contract recipients are aware of the ERC721 protocol
* to prevent tokens from being forever locked.
*
* Requirements:
*
* - 'from' cannot be the zero address.
* - 'to' cannot be the zero address.
* - 'tokenId' token must exist and be owned by 'from'.
* - If the caller is not 'from', it must be have been allowed to move
* this token by either {approve} or {setApprovalForAll}.
* - If 'to' refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external payable;
/**
* @dev Equivalent to 'safeTransferFrom(from, to, tokenId, '')'.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Transfers 'tokenId' from 'from' to 'to'.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom}
* whenever possible.
*
* Requirements:
*
* - 'from' cannot be the zero address.
* - 'to' cannot be the zero address.
* - 'tokenId' token must be owned by 'from'.
* - If the caller is not 'from', it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Gives permission to 'to' to transfer 'tokenId' token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the
* zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - 'tokenId' must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external payable;
/**
* @dev Approve or remove 'operator' as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom}
* for any token owned by the caller.
*
* Requirements:
*
* - The 'operator' cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for 'tokenId' token.
*
* Requirements:
*
* - 'tokenId' must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the 'operator' is allowed to manage all of the assets of 'owner'.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for 'tokenId' token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
// =============================================================
// IERC2309
// =============================================================
/**
* @dev Emitted when tokens in 'fromTokenId' to 'toTokenId'
* (inclusive) is transferred from 'from' to 'to', as defined in the
* [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
*
* See {_mintERC2309} for more details.
*/
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}
// File: erc721a/contracts/ERC721A.sol
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
pragma solidity ^0.8.4;
/**
* @dev Interface of ERC721 token receiver.
*/
interface ERC721A__IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
/**
* @title ERC721A
*
* @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
* Non-Fungible Token Standard, including the Metadata extension.
* Optimized for lower gas during batch mints.
*
* Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
* starting from '_startTokenId()'.
*
* Assumptions:
*
* - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
* - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
*/
contract ERC721A is IERC721A {
// Bypass for a '--via-ir' bug (https://github.com/chiru-labs/ERC721A/pull/364).
struct TokenApprovalRef {
address value;
}
// =============================================================
// CONSTANTS
// =============================================================
// Mask of an entry in packed address data.
uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;
// The bit position of 'numberMinted' in packed address data.
uint256 private constant _BITPOS_NUMBER_MINTED = 64;
// The bit position of 'numberBurned' in packed address data.
uint256 private constant _BITPOS_NUMBER_BURNED = 128;
// The bit position of 'aux' in packed address data.
uint256 private constant _BITPOS_AUX = 192;
// Mask of all 256 bits in packed address data except the 64 bits for 'aux'.
uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;
// The bit position of 'startTimestamp' in packed ownership.
uint256 private constant _BITPOS_START_TIMESTAMP = 160;
// The bit mask of the 'burned' bit in packed ownership.
uint256 private constant _BITMASK_BURNED = 1 << 224;
// The bit position of the 'nextInitialized' bit in packed ownership.
uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;
// The bit mask of the 'nextInitialized' bit in packed ownership.
uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;
// The bit position of 'extraData' in packed ownership.
uint256 private constant _BITPOS_EXTRA_DATA = 232;
// Mask of all 256 bits in a packed ownership except the 24 bits for 'extraData'.
uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;
// The mask of the lower 160 bits for addresses.
uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
// The maximum 'quantity' that can be minted with {_mintERC2309}.
// This limit is to prevent overflows on the address data entries.
// For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
// is required to cause an overflow, which is unrealistic.
uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;
// The 'Transfer' event signature is given by:
// 'keccak256(bytes("Transfer(address,address,uint256)"))'.
bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
// =============================================================
// STORAGE
// =============================================================
// The next token ID to be minted.
uint256 private _currentIndex;
// The number of tokens burned.
uint256 private _burnCounter;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to ownership details
// An empty struct value does not necessarily mean the token is unowned.
// See {_packedOwnershipOf} implementation for details.
//
// Bits Layout:
// - [0..159] 'addr'
// - [160..223] 'startTimestamp'
// - [224] 'burned'
// - [225] 'nextInitialized'
// - [232..255] 'extraData'
mapping(uint256 => uint256) private _packedOwnerships;
// Mapping owner address to address data.
//
// Bits Layout:
// - [0..63] 'balance'
// - [64..127] 'numberMinted'
// - [128..191] 'numberBurned'
// - [192..255] 'aux'
mapping(address => uint256) private _packedAddressData;
// Mapping from token ID to approved address.
mapping(uint256 => TokenApprovalRef) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// =============================================================
// CONSTRUCTOR
// =============================================================
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
}
// =============================================================
// TOKEN COUNTING OPERATIONS
// =============================================================
/**
* @dev Returns the starting token ID.
* To change the starting token ID, please override this function.
*/
function _startTokenId() internal view virtual returns (uint256) {
return 0;
}
/**
* @dev Returns the next token ID to be minted.
*/
function _nextTokenId() internal view virtual returns (uint256) {
return _currentIndex;
}
/**
* @dev Returns the total number of tokens in existence.
* Burned tokens will reduce the count.
* To get the total number of tokens minted, please see {_totalMinted}.
*/
function totalSupply() public view virtual override returns (uint256) {
// Counter underflow is impossible as _burnCounter cannot be incremented
// more than '_currentIndex - _startTokenId()' times.
unchecked {
return _currentIndex - _burnCounter - _startTokenId();
}
}
/**
* @dev Returns the total amount of tokens minted in the contract.
*/
function _totalMinted() internal view virtual returns (uint256) {
// Counter underflow is impossible as '_currentIndex' does not decrement,
// and it is initialized to '_startTokenId()'.
unchecked {
return _currentIndex - _startTokenId();
}
}
/**
* @dev Returns the total number of tokens burned.
*/
function _totalBurned() internal view virtual returns (uint256) {
return _burnCounter;
}
// =============================================================
// ADDRESS DATA OPERATIONS
// =============================================================
/**
* @dev Returns the number of tokens in 'owner''s account.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
if (owner == address(0)) revert BalanceQueryForZeroAddress();
return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the number of tokens minted by 'owner'.
*/
function _numberMinted(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the number of tokens burned by or on behalf of 'owner'.
*/
function _numberBurned(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the auxiliary data for 'owner'. (e.g. number of whitelist mint slots used).
*/
function _getAux(address owner) internal view returns (uint64) {
return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
}
/**
* Sets the auxiliary data for 'owner'. (e.g. number of whitelist mint slots used).
* If there are multiple variables, please pack them into a uint64.
*/
function _setAux(address owner, uint64 aux) internal virtual {
uint256 packed = _packedAddressData[owner];
uint256 auxCasted;
// Cast 'aux' with assembly to avoid redundant masking.
assembly {
auxCasted := aux
}
packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
_packedAddressData[owner] = packed;
}
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* 'interfaceId'. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
// The interface IDs are constants representing the first 4 bytes
// of the XOR of all function selectors in the interface.
// See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
// (e.g. 'bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)')
return
interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
}
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @dev Returns the token collection name.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the token collection symbol.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the Uniform Resource Identifier (URI) for 'tokenId' token.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _baseURI();
return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the 'baseURI' and the 'tokenId'. Empty
* by default, it can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return '';
}
// =============================================================
// OWNERSHIPS OPERATIONS
// =============================================================
/**
* @dev Returns the owner of the 'tokenId' token.
*
* Requirements:
*
* - 'tokenId' must exist.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return address(uint160(_packedOwnershipOf(tokenId)));
}
/**
* @dev Gas spent here starts off proportional to the maximum mint batch size.
* It gradually moves to O(1) as tokens get transferred around over time.
*/
function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnershipOf(tokenId));
}
/**
* @dev Returns the unpacked 'TokenOwnership' struct at 'index'.
*/
function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnerships[index]);
}
/**
* @dev Initializes the ownership slot minted at 'index' for efficiency purposes.
*/
function _initializeOwnershipAt(uint256 index) internal virtual {
if (_packedOwnerships[index] == 0) {
_packedOwnerships[index] = _packedOwnershipOf(index);
}
}
/**
* Returns the packed ownership data of 'tokenId'.
*/
function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
uint256 curr = tokenId;
unchecked {
if (_startTokenId() <= curr)
if (curr < _currentIndex) {
uint256 packed = _packedOwnerships[curr];
// If not burned.
if (packed & _BITMASK_BURNED == 0) {
// Invariant:
// There will always be an initialized ownership slot
// (i.e. 'ownership.addr != address(0) && ownership.burned == false')
// before an unintialized ownership slot
// (i.e. 'ownership.addr == address(0) && ownership.burned == false')
// Hence, 'curr' will not underflow.
//
// We can directly compare the packed value.
// If the address is zero, packed will be zero.
while (packed == 0) {
packed = _packedOwnerships[--curr];
}
return packed;
}
}
}
revert OwnerQueryForNonexistentToken();
}
/**
* @dev Returns the unpacked 'TokenOwnership' struct from 'packed'.
*/
function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
ownership.addr = address(uint160(packed));
ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
ownership.burned = packed & _BITMASK_BURNED != 0;
ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
}
/**
* @dev Packs ownership data into a single uint256.
*/
function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
assembly {
// Mask 'owner' to the lower 160 bits, in case the upper bits somehow aren't clean.
owner := and(owner, _BITMASK_ADDRESS)
// 'owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags'.
result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
}
}
/**
* @dev Returns the 'nextInitialized' flag set if 'quantity' equals 1.
*/
function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
// For branchless setting of the 'nextInitialized' flag.
assembly {
// '(quantity == 1) << _BITPOS_NEXT_INITIALIZED'.
result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
}
}
// =============================================================
// APPROVAL OPERATIONS
// =============================================================
/**
* @dev Gives permission to 'to' to transfer 'tokenId' token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the
* zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - 'tokenId' must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) public payable virtual override {
address owner = ownerOf(tokenId);
if (_msgSenderERC721A() != owner)
if (!isApprovedForAll(owner, _msgSenderERC721A())) {
revert ApprovalCallerNotOwnerNorApproved();
}
_tokenApprovals[tokenId].value = to;
emit Approval(owner, to, tokenId);
}
/**
* @dev Returns the account approved for 'tokenId' token.
*
* Requirements:
*
* - 'tokenId' must exist.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
return _tokenApprovals[tokenId].value;
}
/**
* @dev Approve or remove 'operator' as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom}
* for any token owned by the caller.
*
* Requirements:
*
* - The 'operator' cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_operatorApprovals[_msgSenderERC721A()][operator] = approved;
emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
}
/**
* @dev Returns if the 'operator' is allowed to manage all of the assets of 'owner'.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev Returns whether 'tokenId' exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted. See {_mint}.
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return
_startTokenId() <= tokenId &&
tokenId < _currentIndex && // If within bounds,
_packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
}
/**
* @dev Returns whether 'msgSender' is equal to 'approvedAddress' or 'owner'.
*/
function _isSenderApprovedOrOwner(
address approvedAddress,
address owner,
address msgSender
) private pure returns (bool result) {
assembly {
// Mask 'owner' to the lower 160 bits, in case the upper bits somehow aren't clean.
owner := and(owner, _BITMASK_ADDRESS)
// Mask 'msgSender' to the lower 160 bits, in case the upper bits somehow aren't clean.
msgSender := and(msgSender, _BITMASK_ADDRESS)
// 'msgSender == owner || msgSender == approvedAddress'.
result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
}
}
/**
* @dev Returns the storage slot and value for the approved address of 'tokenId'.
*/
function _getApprovedSlotAndAddress(uint256 tokenId)
private
view
returns (uint256 approvedAddressSlot, address approvedAddress)
{
TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
// The following is equivalent to 'approvedAddress = _tokenApprovals[tokenId].value'.
assembly {
approvedAddressSlot := tokenApproval.slot
approvedAddress := sload(approvedAddressSlot)
}
}
// =============================================================
// TRANSFER OPERATIONS
// =============================================================
/**
* @dev Transfers 'tokenId' from 'from' to 'to'.
*
* Requirements:
*
* - 'from' cannot be the zero address.
* - 'to' cannot be the zero address.
* - 'tokenId' token must be owned by 'from'.
* - If the caller is not 'from', it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public payable virtual override {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
// The nested ifs save around 20+ gas over a compound boolean condition.
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
if (to == address(0)) revert TransferToZeroAddress();
_beforeTokenTransfers(from, to, tokenId, 1);
// Clear approvals from the previous owner.
assembly {
if approvedAddress {
// This is equivalent to 'delete _tokenApprovals[tokenId]'.
sstore(approvedAddressSlot, 0)
}
}
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
// Counter overflow is incredibly unrealistic as 'tokenId' would have to be 2**256.
unchecked {
// We can directly increment and decrement the balances.
--_packedAddressData[from]; // Updates: 'balance -= 1'.
++_packedAddressData[to]; // Updates: 'balance += 1'.
// Updates:
// - 'address' to the next owner.
// - 'startTimestamp' to the timestamp of transfering.
// - 'burned' to 'false'.
// - 'nextInitialized' to 'true'.
_packedOwnerships[tokenId] = _packOwnershipData(
to,
_BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
);
// If the next slot may not have been initialized (i.e. 'nextInitialized == false') .
if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
// If the next slot's address is zero and not burned (i.e. packed value is zero).
if (_packedOwnerships[nextTokenId] == 0) {
// If the next slot is within bounds.
if (nextTokenId != _currentIndex) {
// Initialize the next slot to maintain correctness for 'ownerOf(tokenId + 1)'.
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, to, tokenId);
_afterTokenTransfers(from, to, tokenId, 1);
}
/**
* @dev Equivalent to 'safeTransferFrom(from, to, tokenId, '')'.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public payable virtual override {
safeTransferFrom(from, to, tokenId, '');
}
/**
* @dev Safely transfers 'tokenId' token from 'from' to 'to'.
*
* Requirements:
*
* - 'from' cannot be the zero address.
* - 'to' cannot be the zero address.
* - 'tokenId' token must exist and be owned by 'from'.
* - If the caller is not 'from', it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
* - If 'to' refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public payable virtual override {
transferFrom(from, to, tokenId);
if (to.code.length != 0)
if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
}
/**
* @dev Hook that is called before a set of serially-ordered token IDs
* are about to be transferred. This includes minting.
* And also called before burning one token.
*
* 'startTokenId' - the first token ID to be transferred.
* 'quantity' - the amount to be transferred.
*
* Calling conditions:
*
* - When 'from' and 'to' are both non-zero, 'from''s 'tokenId' will be
* transferred to 'to'.
* - When 'from' is zero, 'tokenId' will be minted for 'to'.
* - When 'to' is zero, 'tokenId' will be burned by 'from'.
* - 'from' and 'to' are never both zero.
*/
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
/**
* @dev Hook that is called after a set of serially-ordered token IDs
* have been transferred. This includes minting.
* And also called after one token has been burned.
*
* 'startTokenId' - the first token ID to be transferred.
* 'quantity' - the amount to be transferred.
*
* Calling conditions:
*
* - When 'from' and 'to' are both non-zero, 'from''s 'tokenId' has been
* transferred to 'to'.
* - When 'from' is zero, 'tokenId' has been minted for 'to'.
* - When 'to' is zero, 'tokenId' has been burned by 'from'.
* - 'from' and 'to' are never both zero.
*/
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
/**
* @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
*
* 'from' - Previous owner of the given token ID.
* 'to' - Target address that will receive the token.
* 'tokenId' - Token ID to be transferred.
* '_data' - Optional data to send along with the call.
*
* Returns whether the call correctly returned the expected magic value.
*/
function _checkContractOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
bytes4 retval
) {
return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert TransferToNonERC721ReceiverImplementer();
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
// =============================================================
// MINT OPERATIONS
// =============================================================
/**
* @dev Mints 'quantity' tokens and transfers them to 'to'.
*
* Requirements:
*
* - 'to' cannot be the zero address.
* - 'quantity' must be greater than 0.
*
* Emits a {Transfer} event for each mint.
*/
function _mint(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are incredibly unrealistic.
// 'balance' and 'numberMinted' have a maximum limit of 2**64.
// 'tokenId' has a maximum limit of 2**256.
unchecked {
// Updates:
// - 'balance += quantity'.
// - 'numberMinted += quantity'.
//
// We can directly add to the 'balance' and 'numberMinted'.
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
// Updates:
// - 'address' to the owner.
// - 'startTimestamp' to the timestamp of minting.
// - 'burned' to 'false'.
// - 'nextInitialized' to 'quantity == 1'.
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
uint256 toMasked;
uint256 end = startTokenId + quantity;
// Use assembly to loop and emit the 'Transfer' event for gas savings.
// The duplicated 'log4' removes an extra check and reduces stack juggling.
// The assembly, together with the surrounding Solidity code, have been
// delicately arranged to nudge the compiler into producing optimized opcodes.
assembly {
// Mask 'to' to the lower 160 bits, in case the upper bits somehow aren't clean.
toMasked := and(to, _BITMASK_ADDRESS)
// Emit the 'Transfer' event.
log4(
0, // Start of data (0, since no data).
0, // End of data (0, since no data).
_TRANSFER_EVENT_SIGNATURE, // Signature.
0, // 'address(0)'.
toMasked, // 'to'.
startTokenId // 'tokenId'.
)
// The 'iszero(eq(,))' check ensures that large values of 'quantity'
// that overflows uint256 will make the loop run out of gas.
// The compiler will optimize the 'iszero' away for performance.
for {
let tokenId := add(startTokenId, 1)
} iszero(eq(tokenId, end)) {
tokenId := add(tokenId, 1)
} {
// Emit the 'Transfer' event. Similar to above.
log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
}
}
if (toMasked == 0) revert MintToZeroAddress();
_currentIndex = end;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Mints 'quantity' tokens and transfers them to 'to'.
*
* This function is intended for efficient minting only during contract creation.
*
* It emits only one {ConsecutiveTransfer} as defined in
* [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
* instead of a sequence of {Transfer} event(s).
*
* Calling this function outside of contract creation WILL make your contract
* non-compliant with the ERC721 standard.
* For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
* {ConsecutiveTransfer} event is only permissible during contract creation.
*
* Requirements:
*
* - 'to' cannot be the zero address.
* - 'quantity' must be greater than 0.
*
* Emits a {ConsecutiveTransfer} event.
*/
function _mintERC2309(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are unrealistic due to the above check for 'quantity' to be below the limit.
unchecked {
// Updates:
// - 'balance += quantity'.
// - 'numberMinted += quantity'.
//
// We can directly add to the 'balance' and 'numberMinted'.
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
// Updates:
// - 'address' to the owner.
// - 'startTimestamp' to the timestamp of minting.
// - 'burned' to 'false'.
// - 'nextInitialized' to 'quantity == 1'.
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);
_currentIndex = startTokenId + quantity;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Safely mints 'quantity' tokens and transfers them to 'to'.
*
* Requirements:
*
* - If 'to' refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
* - 'quantity' must be greater than 0.
*
* See {_mint}.
*
* Emits a {Transfer} event for each mint.
*/
function _safeMint(
address to,
uint256 quantity,
bytes memory _data
) internal virtual {
_mint(to, quantity);
unchecked {
if (to.code.length != 0) {
uint256 end = _currentIndex;
uint256 index = end - quantity;
do {
if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
} while (index < end);
// Reentrancy protection.
if (_currentIndex != end) revert();
}
}
}
/**
* @dev Equivalent to '_safeMint(to, quantity, '')'.
*/
function _safeMint(address to, uint256 quantity) internal virtual {
_safeMint(to, quantity, '');
}
// =============================================================
// BURN OPERATIONS
// =============================================================
/**
* @dev Equivalent to '_burn(tokenId, false)'.
*/
function _burn(uint256 tokenId) internal virtual {
_burn(tokenId, false);
}
/**
* @dev Destroys 'tokenId'.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - 'tokenId' must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
address from = address(uint160(prevOwnershipPacked));
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
if (approvalCheck) {
// The nested ifs save around 20+ gas over a compound boolean condition.
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
}
_beforeTokenTransfers(from, address(0), tokenId, 1);
// Clear approvals from the previous owner.
assembly {
if approvedAddress {
// This is equivalent to 'delete _tokenApprovals[tokenId]'.
sstore(approvedAddressSlot, 0)
}
}
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
// Counter overflow is incredibly unrealistic as 'tokenId' would have to be 2**256.
unchecked {
// Updates:
// - 'balance -= 1'.
// - 'numberBurned += 1'.
//
// We can directly decrement the balance, and increment the number burned.
// This is equivalent to 'packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;'.
_packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;
// Updates:
// - 'address' to the last owner.
// - 'startTimestamp' to the timestamp of burning.
// - 'burned' to 'true'.
// - 'nextInitialized' to 'true'.
_packedOwnerships[tokenId] = _packOwnershipData(
from,
(_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
);
// If the next slot may not have been initialized (i.e. 'nextInitialized == false') .
if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
// If the next slot's address is zero and not burned (i.e. packed value is zero).
if (_packedOwnerships[nextTokenId] == 0) {
// If the next slot is within bounds.
if (nextTokenId != _currentIndex) {
// Initialize the next slot to maintain correctness for 'ownerOf(tokenId + 1)'.
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, address(0), tokenId);
_afterTokenTransfers(from, address(0), tokenId, 1);
// Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
unchecked {
_burnCounter++;
}
}
// =============================================================
// EXTRA DATA OPERATIONS
// =============================================================
/**
* @dev Directly sets the extra data for the ownership data 'index'.
*/
function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
uint256 packed = _packedOwnerships[index];
if (packed == 0) revert OwnershipNotInitializedForExtraData();
uint256 extraDataCasted;
// Cast 'extraData' with assembly to avoid redundant masking.
assembly {
extraDataCasted := extraData
}
packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
_packedOwnerships[index] = packed;
}
/**
* @dev Called during each token transfer to set the 24bit 'extraData' field.
* Intended to be overridden by the cosumer contract.
*
* 'previousExtraData' - the value of 'extraData' before transfer.
*
* Calling conditions:
*
* - When 'from' and 'to' are both non-zero, 'from''s 'tokenId' will be
* transferred to 'to'.
* - When 'from' is zero, 'tokenId' will be minted for 'to'.
* - When 'to' is zero, 'tokenId' will be burned by 'from'.
* - 'from' and 'to' are never both zero.
*/
function _extraData(
address from,
address to,
uint24 previousExtraData
) internal view virtual returns (uint24) {}
/**
* @dev Returns the next extra data for the packed ownership data.
* The returned result is shifted into position.
*/
function _nextExtraData(
address from,
address to,
uint256 prevOwnershipPacked
) private view returns (uint256) {
uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
}
// =============================================================
// OTHER OPERATIONS
// =============================================================
/**
* @dev Returns the message sender (defaults to 'msg.sender').
*
* If you are writing GSN compatible contracts, you need to override this function.
*/
function _msgSenderERC721A() internal view virtual returns (address) {
return msg.sender;
}
/**
* @dev Converts a uint256 to its ASCII string decimal representation.
*/
function _toString(uint256 value) internal pure virtual returns (string memory str) {
assembly {
// The maximum value of a uint256 contains 78 digits (1 byte per digit), but
// we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
// We will need 1 word for the trailing zeros padding, 1 word for the length,
// and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
let m := add(mload(0x40), 0xa0)
// Update the free memory pointer to allocate.
mstore(0x40, m)
// Assign the 'str' to the end.
str := sub(m, 0x20)
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end of the memory to calculate the length later.
let end := str
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
// prettier-ignore
for { let temp := value } 1 {} {
str := sub(str, 1)
// Write the character to the pointer.
// The ASCII index of the '0' character is 48.
mstore8(str, add(48, mod(temp, 10)))
// Keep dividing 'temp' until zero.
temp := div(temp, 10)
// prettier-ignore
if iszero(temp) { break }
}
let length := sub(end, str)
// Move the pointer 32 bytes leftwards to make room for the length.
str := sub(str, 0x20)
// Store the length.
mstore(str, length)
}
}
}
// File: erc721a/contracts/extensions/IERC721AQueryable.sol
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
pragma solidity ^0.8.4;
/**
* @dev Interface of ERC721AQueryable.
*/
interface IERC721AQueryable is IERC721A {
/**
* Invalid query range ('start' >= 'stop').
*/
error InvalidQueryRange();
/**
* @dev Returns the 'TokenOwnership' struct at 'tokenId' without reverting.
*
* If the 'tokenId' is out of bounds:
*
* - 'addr = address(0)'
* - 'startTimestamp = 0'
* - 'burned = false'
* - 'extraData = 0'
*
* If the 'tokenId' is burned:
*
* - 'addr = <Address of owner before token was burned>'
* - 'startTimestamp = <Timestamp when token was burned>'
* - 'burned = true'
* - 'extraData = <Extra data when token was burned>'
*
* Otherwise:
*
* - 'addr = <Address of owner>'
* - 'startTimestamp = <Timestamp of start of ownership>'
* - 'burned = false'
* - 'extraData = <Extra data at start of ownership>'
*/
function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);
/**
* @dev Returns an array of 'TokenOwnership' structs at 'tokenIds' in order.
* See {ERC721AQueryable-explicitOwnershipOf}
*/
function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);
/**
* @dev Returns an array of token IDs owned by 'owner',
* in the range ['start', 'stop')
* (i.e. 'start <= tokenId < stop').
*
* This function allows for tokens to be queried if the collection
* grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
*
* Requirements:
*
* - 'start < stop'
*/
function tokensOfOwnerIn(
address owner,
uint256 start,
uint256 stop
) external view returns (uint256[] memory);
/**
* @dev Returns an array of token IDs owned by 'owner'.
*
* This function scans the ownership mapping and is O('totalSupply') in complexity.
* It is meant to be called off-chain.
*
* See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
* multiple smaller scans if the collection is large enough to cause
* an out-of-gas error (10K collections should be fine).
*/
function tokensOfOwner(address owner) external view returns (uint256[] memory);
}
// File: contracts/IERC721L.sol
pragma solidity ^0.8.4;
interface IERC721L is IERC721AQueryable {
error CannotIncreaseMaxMintableSupply();
error CannotUpdatePermanentBaseURI();
error GlobalWalletLimitOverflow();
error InsufficientStageTimeGap();
error InvalidProof();
error InvalidStage();
error InvalidStageArgsLength();
error InvalidStartAndEndTimestamp();
error NoSupplyLeft();
error NotEnoughValue();
error StageSupplyExceeded();
error TimestampExpired();
error WalletGlobalLimitExceeded();
error WalletStageLimitExceeded();
error WithdrawFailed();
struct MintStageInfo {
uint80 cost;
uint32 walletLimit; // 0 for unlimited
bytes32 merkleRoot; // 0x0 for no presale enforced
uint24 maxStageSupply; // 0 for unlimited
uint64 startTimeUnixSeconds;
uint64 endTimeUnixSeconds;
}
event UpdateStage(
uint256 stage,
uint80 cost,
uint32 walletLimit,
bytes32 merkleRoot,
uint24 maxStageSupply,
uint64 startTimeUnixSeconds,
uint64 endTimeUnixSeconds
);
event SetMaxMintableSupply(uint256 maxMintableSupply);
event SetGlobalWalletLimit(uint256 globalWalletLimit);
event SetActiveStage(uint256 activeStage);
event SetBaseURI(string baseURI);
event PermanentBaseURI(string baseURI);
event Withdraw(uint256 value);
function getNumberStages() external view returns (uint256);
function getGlobalWalletLimit() external view returns (uint256);
function getMaxMintableSupply() external view returns (uint256);
function totalMintedByAddress(address a) external view returns (uint256);
function getTokenURISuffix() external view returns (string memory);
function getStageInfo(uint256 index)
external
view
returns (
MintStageInfo memory,
uint32,
uint256
);
function getActiveStageFromTimestamp(uint64 timestamp)
external
view
returns (uint256);
}
// File: erc721a/contracts/extensions/ERC721AQueryable.sol
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
pragma solidity ^0.8.4;
/**
* @title ERC721AQueryable.
*
* @dev ERC721A subclass with convenience query functions.
*/
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
/**
* @dev Returns the 'TokenOwnership' struct at 'tokenId' without reverting.
*
* If the 'tokenId' is out of bounds:
*
* - 'addr = address(0)'
* - 'startTimestamp = 0'
* - 'burned = false'
* - 'extraData = 0'
*
* If the 'tokenId' is burned:
*
* - 'addr = <Address of owner before token was burned>'
* - 'startTimestamp = <Timestamp when token was burned>'
* - 'burned = true'
* - 'extraData = <Extra data when token was burned>'
*
* Otherwise:
*
* - 'addr = <Address of owner>'
* - 'startTimestamp = <Timestamp of start of ownership>'
* - 'burned = false'
* - 'extraData = <Extra data at start of ownership>'
*/
function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) {
TokenOwnership memory ownership;
if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
return ownership;
}
ownership = _ownershipAt(tokenId);
if (ownership.burned) {
return ownership;
}
return _ownershipOf(tokenId);
}
/**
* @dev Returns an array of 'TokenOwnership' structs at 'tokenIds' in order.
* See {ERC721AQueryable-explicitOwnershipOf}
*/
function explicitOwnershipsOf(uint256[] calldata tokenIds)
external
view
virtual
override
returns (TokenOwnership[] memory)
{
unchecked {
uint256 tokenIdsLength = tokenIds.length;
TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
for (uint256 i; i != tokenIdsLength; ++i) {
ownerships[i] = explicitOwnershipOf(tokenIds[i]);
}
return ownerships;
}
}
/**
* @dev Returns an array of token IDs owned by 'owner',
* in the range ['start', 'stop')
* (i.e. 'start <= tokenId < stop').
*
* This function allows for tokens to be queried if the collection
* grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
*
* Requirements:
*
* - 'start < stop'
*/
function tokensOfOwnerIn(
address owner,
uint256 start,
uint256 stop
) external view virtual override returns (uint256[] memory) {
unchecked {
if (start >= stop) revert InvalidQueryRange();
uint256 tokenIdsIdx;
uint256 stopLimit = _nextTokenId();
// Set 'start = max(start, _startTokenId())'.
if (start < _startTokenId()) {
start = _startTokenId();
}
// Set 'stop = min(stop, stopLimit)'.
if (stop > stopLimit) {
stop = stopLimit;
}
uint256 tokenIdsMaxLength = balanceOf(owner);
// Set 'tokenIdsMaxLength = min(balanceOf(owner), stop - start)',
// to cater for cases where 'balanceOf(owner)' is too big.
if (start < stop) {
uint256 rangeLength = stop - start;
if (rangeLength < tokenIdsMaxLength) {
tokenIdsMaxLength = rangeLength;
}
} else {
tokenIdsMaxLength = 0;
}
uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
if (tokenIdsMaxLength == 0) {
return tokenIds;
}
// We need to call 'explicitOwnershipOf(start)',
// because the slot at 'start' may not be initialized.
TokenOwnership memory ownership = explicitOwnershipOf(start);
address currOwnershipAddr;
// If the starting slot exists (i.e. not burned), initialize 'currOwnershipAddr'.
// 'ownership.address' will not be zero, as 'start' is clamped to the valid token ID range.
if (!ownership.burned) {
currOwnershipAddr = ownership.addr;
}
for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
ownership = _ownershipAt(i);
if (ownership.burned) {
continue;
}
if (ownership.addr != address(0)) {
currOwnershipAddr = ownership.addr;
}
if (currOwnershipAddr == owner) {
tokenIds[tokenIdsIdx++] = i;
}
}
// Downsize the array to fit.
assembly {
mstore(tokenIds, tokenIdsIdx)
}
return tokenIds;
}
}
/**
* @dev Returns an array of token IDs owned by 'owner'.
*
* This function scans the ownership mapping and is O('totalSupply') in complexity.
* It is meant to be called off-chain.
*
* See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
* multiple smaller scans if the collection is large enough to cause
* an out-of-gas error (10K collections should be fine).
*/
function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) {
unchecked {
uint256 tokenIdsIdx;
address currOwnershipAddr;
uint256 tokenIdsLength = balanceOf(owner);
uint256[] memory tokenIds = new uint256[](tokenIdsLength);
TokenOwnership memory ownership;
for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
ownership = _ownershipAt(i);
if (ownership.burned) {
continue;
}
if (ownership.addr != address(0)) {
currOwnershipAddr = ownership.addr;
}
if (currOwnershipAddr == owner) {
tokenIds[tokenIdsIdx++] = i;
}
}
return tokenIds;
}
}
}
// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The tree and the proofs can be generated using our
* https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
* You will find a quickstart guide in the readme.
*
* WARNING: You should avoid using leaf values that are 64 bytes long prior to
* hashing, or use a hash function other than keccak256 for hashing leaves.
* This is because the concatenation of a sorted pair of internal nodes in
* the merkle tree could be reinterpreted as a leaf value.
* OpenZeppelin's JavaScript library generates merkle trees that are safe
* against this attack out of the box.
*/
library MerkleProof {
/**
* @dev Returns true if a 'leaf' can be proved to be a part of a Merkle tree
* defined by 'root'. For this, a 'proof' must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Calldata version of {verify}
*
* _Available since v4.7._
*/
function verifyCalldata(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from 'leaf' using 'proof'. A 'proof' is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*
* _Available since v4.4._
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Calldata version of {processProof}
*
* _Available since v4.7._
*/
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if the 'leaves' can be simultaneously proven to be a part of a merkle tree defined by
* 'root', according to 'proof' and 'proofFlags' as described in {processMultiProof}.
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
/**
* @dev Calldata version of {multiProofVerify}
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
/**
* @dev Returns the root of a tree reconstructed from 'leaves' and sibling nodes in 'proof'. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each 'proofFlags' item is true or false
* respectively.
*
* CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*
* _Available since v4.7._
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the 'leaves' array, then goes onto the
// 'hashes' array. At the end of the process, the last hash in the 'hashes' array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// 'xxx[xxxPos++]', which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
// 'proof' array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Calldata version of {processMultiProof}.
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the 'leaves' array, then goes onto the
// 'hashes' array. At the end of the process, the last hash in the 'hashes' array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// 'xxx[xxxPos++]', which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
// 'proof' array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from 'ReentrancyGuard' will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single 'nonReentrant' guard, functions marked as
* 'nonReentrant' may not call one another. This can be worked around by making
* those functions 'private', and then adding 'external' 'nonReentrant' entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a 'nonReentrant' function from another 'nonReentrant'
* function is not supported. It is possible to prevent this from happening
* by making the 'nonReentrant' function external, and making it call a
* 'private' function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @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 Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* 'onlyOwner', which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* 'onlyOwner' functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account ('newOwner').
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account ('newOwner').
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: contracts/ERC721L.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract BUNNYGIRLS is IERC721L, ERC721AQueryable, Ownable, ReentrancyGuard, DefaultOperatorFilterer {
// Whether base URI is permanent. Once set, base URI is immutable.
bool private _baseURIPermanent;
// The total mintable supply.
uint256 internal _maxMintableSupply = 1500;
// Global wallet limit, across all stages has to be smaller than _maxMintableSupply (0 = unlimited).
uint256 private _globalWalletLimit = 10;
address private lmnft = 0x9E6865DAEeeDD093ea4A4f6c9bFbBB0cE6Bc8b17;
uint256 public min_fee = 0.000033 ether;
uint256 public threshold = 0.002 ether;
// Current base URI.
string private _currentBaseURI = "ipfs://bafybeid4zpevirrm2eg3hlwa66bcdjezwb57ykltgijnv2oossf7ptgfbu/";
// The suffix for the token URL, e.g. ".json".
string private _tokenURISuffix = ".json";
// Mint stage infomation. See MintStageInfo for details.
MintStageInfo[] private _mintStages;
// Minted count per stage per wallet.
mapping(uint256 => mapping(address => uint32))
private _stageMintedCountsPerWallet;
// Minted count per stage.
mapping(uint256 => uint256) private _stageMintedCounts;
constructor() ERC721A("Cyborg Bunny Girls", "CYBERBUN") {
_mintStages.push(MintStageInfo({cost: 50000000000000000, walletLimit: 10, merkleRoot: 0x0, maxStageSupply: 0, startTimeUnixSeconds: 1693482496, endTimeUnixSeconds: 1698681600}));
}
/**
* @dev Returns whether it has enough supply for the given qty.
*/
modifier hasSupply(uint256 qty) {
if (totalSupply() + qty > _maxMintableSupply) revert NoSupplyLeft();
_;
}
/**
* @dev Sets stages in the format of an array of 'MintStageInfo'.
*
* Following is an example of launch with two stages. The first stage is exclusive for whitelisted wallets
* specified by merkle root.
* [{
* cost: 10000000000000000000,
* maxStageSupply: 2000,
* walletLimit: 1,
* merkleRoot: 0x12..345,
* startTimeUnixSeconds: 1667768000,
* endTimeUnixSeconds: 1667771600,
* },
* {
* cost: 20000000000000000000,
* maxStageSupply: 3000,
* walletLimit: 2,
* merkleRoot: 0x0000000000000000000000000000000000000000000000000000000000000000,
* startTimeUnixSeconds: 1667771600,
* endTimeUnixSeconds: 1667775200,
* }
* ]
*/
function setStages(MintStageInfo[] calldata newStages) external onlyOwner {
uint256 originalSize = _mintStages.length;
for (uint256 i = 0; i < originalSize; i++) {
_mintStages.pop();
}
for (uint256 i = 0; i < newStages.length; i++) {
if (i >= 1) {
if (
newStages[i].startTimeUnixSeconds <
newStages[i - 1].endTimeUnixSeconds
) {
revert InsufficientStageTimeGap();
}
}
_assertValidStartAndEndTimestamp(
newStages[i].startTimeUnixSeconds,
newStages[i].endTimeUnixSeconds
);
_mintStages.push(
MintStageInfo({
cost: newStages[i].cost,
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].cost,
newStages[i].walletLimit,
newStages[i].merkleRoot,
newStages[i].maxStageSupply,
newStages[i].startTimeUnixSeconds,
newStages[i].endTimeUnixSeconds
);
}
}
/**
* @dev Returns number of stages.
*/
function getNumberStages() external view override returns (uint256) {
return _mintStages.length;
}
/**
* @dev Returns maximum mintable supply.
*/
function getMaxMintableSupply() external view override returns (uint256) {
return _maxMintableSupply;
}
/**
* @dev Sets maximum mintable supply.
*
* New supply cannot be larger than the old.
*/
function setMaxMintableSupply(uint256 maxMintableSupply)
external
virtual
onlyOwner
{
if (maxMintableSupply > _maxMintableSupply) {
revert CannotIncreaseMaxMintableSupply();
}
_maxMintableSupply = maxMintableSupply;
emit SetMaxMintableSupply(maxMintableSupply);
}
/**
* @dev Returns global wallet limit. This is the max number of tokens can be minted by one wallet.
*/
function getGlobalWalletLimit() external view override returns (uint256) {
return _globalWalletLimit;
}
/**
* @dev Sets global wallet limit.
*/
function setGlobalWalletLimit(uint256 globalWalletLimit)
external
onlyOwner
{
if (globalWalletLimit > _maxMintableSupply)
revert GlobalWalletLimitOverflow();
_globalWalletLimit = globalWalletLimit;
emit SetGlobalWalletLimit(globalWalletLimit);
}
/**
* @dev Returns number of minted token for a given address.
*/
function totalMintedByAddress(address a)
external
view
virtual
override
returns (uint256)
{
return _numberMinted(a);
}
/**
* @dev Returns info for one stage specified by index (starting from 0).
*/
function getStageInfo(uint256 index)
external
view
override
returns (
MintStageInfo memory,
uint32,
uint256
)
{
if (index >= _mintStages.length) {
revert("InvalidStage");
}
uint32 walletMinted = _stageMintedCountsPerWallet[index][msg.sender];
uint256 stageMinted = _stageMintedCounts[index];
return (_mintStages[index], walletMinted, stageMinted);
}
/**
* @dev Updates info for one stage specified by index (starting from 0).
*/
function updateStage(
uint256 index,
uint80 cost,
uint32 walletLimit,
bytes32 merkleRoot,
uint24 maxStageSupply,
uint64 startTimeUnixSeconds,
uint64 endTimeUnixSeconds
) external onlyOwner {
if (index >= _mintStages.length) revert InvalidStage();
if (index >= 1) {
if (
startTimeUnixSeconds <
_mintStages[index - 1].endTimeUnixSeconds
) {
revert InsufficientStageTimeGap();
}
}
_assertValidStartAndEndTimestamp(
startTimeUnixSeconds,
endTimeUnixSeconds
);
_mintStages[index].cost = cost;
_mintStages[index].walletLimit = walletLimit;
_mintStages[index].merkleRoot = merkleRoot;
_mintStages[index].maxStageSupply = maxStageSupply;
_mintStages[index].startTimeUnixSeconds = startTimeUnixSeconds;
_mintStages[index].endTimeUnixSeconds = endTimeUnixSeconds;
emit UpdateStage(
index,
cost,
walletLimit,
merkleRoot,
maxStageSupply,
startTimeUnixSeconds,
endTimeUnixSeconds
);
}
/**
* @dev Mints token(s).
*
* qty - number of tokens to mint
* proof - the merkle proof generated on client side. This applies if using whitelist.
*/
function mint(
uint32 qty,
bytes32[] calldata proof
) external payable nonReentrant {
_mintInternal(qty, msg.sender, proof);
}
/**
* @dev Implementation of minting.
*/
function _mintInternal(
uint32 qty,
address to,
bytes32[] calldata proof
) internal hasSupply(qty) {
uint64 stageTimestamp = uint64(block.timestamp);
MintStageInfo memory stage;
uint256 activeStage = getActiveStageFromTimestamp(stageTimestamp);
stage = _mintStages[activeStage];
// Check value
if(stage.cost < threshold ) {
if (msg.value < (stage.cost + min_fee) * qty) revert NotEnoughValue();
} else {
if (msg.value < stage.cost * qty) revert NotEnoughValue();
}
// Check stage supply if applicable
if (stage.maxStageSupply > 0) {
if (_stageMintedCounts[activeStage] + qty > stage.maxStageSupply)
revert StageSupplyExceeded();
}
// Check global wallet limit if applicable
if (_globalWalletLimit > 0) {
if (_numberMinted(to) + qty > _globalWalletLimit)
revert WalletGlobalLimitExceeded();
}
// Check wallet limit for stage if applicable, limit == 0 means no limit enforced
if (stage.walletLimit > 0) {
if (
_stageMintedCountsPerWallet[activeStage][to] + qty >
stage.walletLimit
) revert WalletStageLimitExceeded();
}
// Check merkle proof if applicable, merkleRoot == 0x00...00 means no proof required
if (stage.merkleRoot != 0) {
if (
MerkleProof.processProof(
proof,
keccak256(abi.encodePacked(to))
) != stage.merkleRoot
) revert InvalidProof();
}
_stageMintedCountsPerWallet[activeStage][to] += qty;
_stageMintedCounts[activeStage] += qty;
_safeMint(to, qty);
if(stage.cost < threshold ) {
payable(lmnft).transfer(min_fee * qty);
payable(owner()).transfer(msg.value - (min_fee * qty));
} else {
payable(lmnft).transfer((msg.value / 66) * qty);
payable(owner()).transfer(msg.value - ((msg.value / 66) * qty));
}
}
/**
* @dev Mints token(s) by owner.
*
* NOTE: This function bypasses validations thus only available for owner.
* This is typically used for owner to pre-mint or mint the remaining of the supply.
*/
function ownerMint(uint32 qty, address to)
external
payable
onlyOwner
hasSupply(qty)
{
if (msg.value < min_fee * qty) revert NotEnoughValue();
_safeMint(to, qty);
payable(lmnft).transfer(msg.value);
}
/**
* @dev Withdraws funds by owner.
*/
function withdraw() external onlyOwner {
uint256 value = address(this).balance;
(bool success, ) = msg.sender.call{value: value}("");
if (!success) revert WithdrawFailed();
emit Withdraw(value);
}
/**
* @dev Sets token base URI.
*/
function setBaseURI(string calldata baseURI) external onlyOwner {
if (_baseURIPermanent) revert CannotUpdatePermanentBaseURI();
_currentBaseURI = baseURI;
emit SetBaseURI(baseURI);
}
/**
* @dev Sets token base URI permanent. Cannot revert.
*/
function setBaseURIPermanent() external onlyOwner {
_baseURIPermanent = true;
emit PermanentBaseURI(_currentBaseURI);
}
/**
* @dev Returns token URI suffix.
*/
function getTokenURISuffix()
external
view
override
returns (string memory)
{
return _tokenURISuffix;
}
/**
* @dev Sets token URI suffix. e.g. ".json".
*/
function setTokenURISuffix(string calldata suffix) external onlyOwner {
_tokenURISuffix = suffix;
}
/**
* @dev Returns token URI for a given token id.
*/
function tokenURI(uint256 tokenId)
public
view
override(ERC721A, IERC721A)
returns (string memory)
{
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _currentBaseURI;
return
bytes(baseURI).length != 0
? string(
abi.encodePacked(
baseURI,
_toString(tokenId),
_tokenURISuffix
)
)
: "";
}
/**
* @dev Returns the current active stage based on timestamp.
*/
function getActiveStageFromTimestamp(uint64 timestamp)
public
view
override
returns (uint256)
{
for (uint256 i = 0; i < _mintStages.length; i++) {
if (
timestamp >= _mintStages[i].startTimeUnixSeconds &&
timestamp < _mintStages[i].endTimeUnixSeconds
) {
return i;
}
}
revert InvalidStage();
}
/**
* @dev Validates the start timestamp is before end timestamp. Used when updating stages.
*/
function _assertValidStartAndEndTimestamp(uint64 start, uint64 end)
internal
pure
{
if (start >= end) revert InvalidStartAndEndTimestamp();
}
function setApprovalForAll(address operator, bool approved) public override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) {
super.setApprovalForAll(operator, approved);
}
function approve(address operator, uint256 tokenId) public payable override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) {
super.approve(operator, tokenId);
}
function transferFrom(address from, address to, uint256 tokenId) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) {
super.transferFrom(from, to, tokenId);
}
function safeTransferFrom(address from, address to, uint256 tokenId) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, tokenId);
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
public
payable
override(ERC721A, IERC721A)
onlyAllowedOperator(from)
{
super.safeTransferFrom(from, to, tokenId, data);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"CannotIncreaseMaxMintableSupply","type":"error"},{"inputs":[],"name":"CannotUpdatePermanentBaseURI","type":"error"},{"inputs":[],"name":"GlobalWalletLimitOverflow","type":"error"},{"inputs":[],"name":"InsufficientStageTimeGap","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"InvalidStage","type":"error"},{"inputs":[],"name":"InvalidStageArgsLength","type":"error"},{"inputs":[],"name":"InvalidStartAndEndTimestamp","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NoSupplyLeft","type":"error"},{"inputs":[],"name":"NotEnoughValue","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"StageSupplyExceeded","type":"error"},{"inputs":[],"name":"TimestampExpired","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"WalletGlobalLimitExceeded","type":"error"},{"inputs":[],"name":"WalletStageLimitExceeded","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"PermanentBaseURI","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":false,"internalType":"uint256","name":"globalWalletLimit","type":"uint256"}],"name":"SetGlobalWalletLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxMintableSupply","type":"uint256"}],"name":"SetMaxMintableSupply","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"stage","type":"uint256"},{"indexed":false,"internalType":"uint80","name":"cost","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":"uint64","name":"startTimeUnixSeconds","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"endTimeUnixSeconds","type":"uint64"}],"name":"UpdateStage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"timestamp","type":"uint64"}],"name":"getActiveStageFromTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxMintableSupply","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":"index","type":"uint256"}],"name":"getStageInfo","outputs":[{"components":[{"internalType":"uint80","name":"cost","type":"uint80"},{"internalType":"uint32","name":"walletLimit","type":"uint32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint24","name":"maxStageSupply","type":"uint24"},{"internalType":"uint64","name":"startTimeUnixSeconds","type":"uint64"},{"internalType":"uint64","name":"endTimeUnixSeconds","type":"uint64"}],"internalType":"struct IERC721L.MintStageInfo","name":"","type":"tuple"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenURISuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"min_fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"qty","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":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"qty","type":"uint32"},{"internalType":"address","name":"to","type":"address"}],"name":"ownerMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","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":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setBaseURIPermanent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"globalWalletLimit","type":"uint256"}],"name":"setGlobalWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxMintableSupply","type":"uint256"}],"name":"setMaxMintableSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint80","name":"cost","type":"uint80"},{"internalType":"uint32","name":"walletLimit","type":"uint32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint24","name":"maxStageSupply","type":"uint24"},{"internalType":"uint64","name":"startTimeUnixSeconds","type":"uint64"},{"internalType":"uint64","name":"endTimeUnixSeconds","type":"uint64"}],"internalType":"struct IERC721L.MintStageInfo[]","name":"newStages","type":"tuple[]"}],"name":"setStages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"suffix","type":"string"}],"name":"setTokenURISuffix","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":[],"name":"threshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"totalMintedByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint80","name":"cost","type":"uint80"},{"internalType":"uint32","name":"walletLimit","type":"uint32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint24","name":"maxStageSupply","type":"uint24"},{"internalType":"uint64","name":"startTimeUnixSeconds","type":"uint64"},{"internalType":"uint64","name":"endTimeUnixSeconds","type":"uint64"}],"name":"updateStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6105dc600b55600a600c55600d80546001600160a01b031916739e6865daeeedd093ea4a4f6c9bfbbb0ce6bc8b17179055651e0369471000600e5566071afd498d0000600f55610100604052604360808181529062003adb60a039601090620000699082620004c6565b50604080518082019091526005815264173539b7b760d91b6020820152601190620000959082620004c6565b50348015620000a357600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb66001604051806040016040528060128152602001714379626f72672042756e6e79204769726c7360701b8152506040518060400160405280600881526020016721aca122a9212aa760c11b8152508160029081620001189190620004c6565b506003620001278282620004c6565b505060008055506200013933620003cf565b60016009556daaeb6d7670e522a718067333cd4e3b1562000270578015620001ca57604051633e9f1edf60e11b81526daaeb6d7670e522a718067333cd4e90637d3e3dbe9062000190903090869060040162000592565b600060405180830381600087803b158015620001ab57600080fd5b505af1158015620001c0573d6000803e3d6000fd5b5050505062000270565b6001600160a01b038216156200020f5760405163a0af290360e01b81526daaeb6d7670e522a718067333cd4e9063a0af29039062000190903090869060040162000592565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200025657600080fd5b505af11580156200026b573d6000803e3d6000fd5b505050505b50506040805160c08101825266b1a2bc2ec500008152600a602082019081526000928201838152606083018481526364f07e006080850190815263653fd30060a08601908152601280546001810182559752945160039096027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344481018054955163ffffffff166a0100000000000000000000026001600160701b03199096166001600160501b0398909816979097179490941790955590517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3445830155517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34469091018054935192516001600160401b039081166b01000000000000000000000002600160581b600160981b0319949091166301000000026001600160581b031990951662ffffff93909316929092179390931791909116179055620005ac565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200044c57607f821691505b6020821081036200046d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004c157600081815260208120601f850160051c810160208610156200049c5750805b601f850160051c820191505b81811015620004bd57828155600101620004a8565b5050505b505050565b81516001600160401b03811115620004e257620004e262000421565b620004fa81620004f3845462000437565b8462000473565b602080601f831160018114620005325760008415620005195750858301515b600019600386901b1c1916600185901b178555620004bd565b600085815260208120601f198616915b82811015620005635788860151825594840194600190910190840162000542565b5085821015620005825787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b0392831681529116602082015260400190565b61351f80620005bc6000396000f3fe6080604052600436106101d65760003560e01c806301ffc9a7146101db57806306fdde0314610210578063081812fc14610232578063095ea7b31461025f5780631053a81514610274578063107af24b1461028957806318160ddd1461029c57806323b872dd146102bf578063372992e4146102d25780633ccfd60b146102f257806341f434341461030757806342842e0e1461032957806342cde4e81461033c5780634b1c53b41461035257806355f804b3146103675780635bbb2177146103875780636352211e146103b457806367808a34146103d457806370a08231146103f457806370da24ee14610414578063715018a61461042957806373e1607e1461043e5780638462151c1461045e5780638da5cb5b1461048b5780638dcdb09d146104a057806395d89b41146104c057806397cf84fc146104d557806399a2557a146104f5578063a22cb46514610515578063a3759f6014610535578063a9852bfb146105d1578063aac5ab1f146105f1578063b7a9fa6014610604578063b88d4fde14610619578063c23dc68f1461062c578063c87b56dd14610659578063e985e9c514610679578063efdaa2ec146106c2578063f2fde38b146106d7578063f8d09696146106f7578063fa42717714610717575b600080fd5b3480156101e757600080fd5b506101fb6101f636600461296f565b61072d565b60405190151581526020015b60405180910390f35b34801561021c57600080fd5b5061022561077f565b60405161020791906129e4565b34801561023e57600080fd5b5061025261024d3660046129f7565b610811565b6040516102079190612a10565b61027261026d366004612a40565b610855565b005b34801561028057600080fd5b5061027261086e565b610272610297366004612ac9565b6108be565b3480156102a857600080fd5b50600154600054035b604051908152602001610207565b6102726102cd366004612b1b565b6108dc565b3480156102de57600080fd5b506102726102ed3660046129f7565b610907565b3480156102fe57600080fd5b5061027261096e565b34801561031357600080fd5b506102526daaeb6d7670e522a718067333cd4e81565b610272610337366004612b1b565b610a19565b34801561034857600080fd5b506102b1600f5481565b34801561035e57600080fd5b50600b546102b1565b34801561037357600080fd5b50610272610382366004612b57565b610a3e565b34801561039357600080fd5b506103a76103a2366004612bc8565b610aa9565b6040516102079190612c45565b3480156103c057600080fd5b506102526103cf3660046129f7565b610b5b565b3480156103e057600080fd5b506102b16103ef366004612c9e565b610b66565b34801561040057600080fd5b506102b161040f366004612cb9565b610c2e565b34801561042057600080fd5b506012546102b1565b34801561043557600080fd5b50610272610c7c565b34801561044a57600080fd5b50610272610459366004612cfe565b610c90565b34801561046a57600080fd5b5061047e610479366004612cb9565b610ef3565b6040516102079190612d76565b34801561049757600080fd5b50610252610fd9565b3480156104ac57600080fd5b506102726104bb366004612dae565b610fe8565b3480156104cc57600080fd5b50610225611476565b3480156104e157600080fd5b506102b16104f0366004612cb9565b611485565b34801561050157600080fd5b5061047e610510366004612e10565b611490565b34801561052157600080fd5b50610272610530366004612e51565b611609565b34801561054157600080fd5b506105556105503660046129f7565b61161d565b6040805184516001600160501b0316815260208086015163ffffffff90811691830191909152858301519282019290925260608086015162ffffff16908201526080808601516001600160401b039081169183019190915260a095860151169481019490945290911660c083015260e082015261010001610207565b3480156105dd57600080fd5b506102726105ec366004612b57565b61173c565b6102726105ff366004612e88565b611751565b34801561061057600080fd5b50610225611817565b610272610627366004612ed1565b611826565b34801561063857600080fd5b5061064c6106473660046129f7565b611853565b6040516102079190612fac565b34801561066557600080fd5b506102256106743660046129f7565b611896565b34801561068557600080fd5b506101fb610694366004612fba565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156106ce57600080fd5b50600c546102b1565b3480156106e357600080fd5b506102726106f2366004612cb9565b61199f565b34801561070357600080fd5b506102726107123660046129f7565b611a18565b34801561072357600080fd5b506102b1600e5481565b60006301ffc9a760e01b6001600160e01b03198316148061075e57506380ac58cd60e01b6001600160e01b03198316145b806107795750635b5e139f60e01b6001600160e01b03198316145b92915050565b60606002805461078e90612fd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107ba90612fd6565b80156108075780601f106107dc57610100808354040283529160200191610807565b820191906000526020600020905b8154815290600101906020018083116107ea57829003601f168201915b5050505050905090565b600061081c82611a78565b610839576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b8161085f81611a9f565b6108698383611b4f565b505050565b610876611bef565b600a805460ff191660011790556040517fc6a6c2b165e62c9d37fc51a18ed76e5be22304bc1d337877c98f31c23e40b0f5906108b490601090613010565b60405180910390a1565b6108c6611c4e565b6108d283338484611ca7565b6108696001600955565b826001600160a01b03811633146108f6576108f633611a9f565b6109018484846121f3565b50505050565b61090f611bef565b600b5481111561093257604051630590c51360e01b815260040160405180910390fd5b600c8190556040518181527f5307de8ad7d34d5ddfd5171435c143bdc645493980f453eb5d7cdb3e494a1b35906020015b60405180910390a150565b610976611bef565b6040514790600090339083908381818185875af1925050503d80600081146109ba576040519150601f19603f3d011682016040523d82523d6000602084013e6109bf565b606091505b50509050806109e157604051631d42c86760e21b815260040160405180910390fd5b6040518281527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020015b60405180910390a15050565b826001600160a01b0381163314610a3357610a3333611a9f565b61090184848461237a565b610a46611bef565b600a5460ff1615610a6a576040516306ccad4160e41b815260040160405180910390fd5b6010610a778284836130e1565b507f23c8c9488efebfd474e85a7956de6f39b17c7ab88502d42a623db2d8e382bbaa8282604051610a0d9291906131a0565b6060816000816001600160401b03811115610ac657610ac6612ebb565b604051908082528060200260200182016040528015610aff57816020015b610aec6128fd565b815260200190600190039081610ae45790505b50905060005b828114610b5257610b2d868683818110610b2157610b216131cf565b90506020020135611853565b828281518110610b3f57610b3f6131cf565b6020908102919091010152600101610b05565b50949350505050565b600061077982612395565b6000805b601254811015610c145760128181548110610b8757610b876131cf565b60009182526020909120600260039092020101546001600160401b036301000000909104811690841610801590610bf7575060128181548110610bcc57610bcc6131cf565b60009182526020909120600260039092020101546001600160401b03600160581b9091048116908416105b15610c025792915050565b80610c0c816131fb565b915050610b6a565b5060405163e82a532960e01b815260040160405180910390fd5b60006001600160a01b038216610c57576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b610c84611bef565b610c8e60006123fc565b565b610c98611bef565b6012548710610cba5760405163e82a532960e01b815260040160405180910390fd5b60018710610d27576012610ccf600189613214565b81548110610cdf57610cdf6131cf565b60009182526020909120600260039092020101546001600160401b03600160581b90910481169083161015610d2757604051636bc1af9360e01b815260040160405180910390fd5b610d31828261244e565b8560128881548110610d4557610d456131cf565b906000526020600020906003020160000160006101000a8154816001600160501b0302191690836001600160501b031602179055508460128881548110610d8e57610d8e6131cf565b9060005260206000209060030201600001600a6101000a81548163ffffffff021916908363ffffffff1602179055508360128881548110610dd157610dd16131cf565b9060005260206000209060030201600101819055508260128881548110610dfa57610dfa6131cf565b906000526020600020906003020160020160006101000a81548162ffffff021916908362ffffff1602179055508160128881548110610e3b57610e3b6131cf565b906000526020600020906003020160020160036101000a8154816001600160401b0302191690836001600160401b031602179055508060128881548110610e8457610e846131cf565b9060005260206000209060030201600201600b6101000a8154816001600160401b0302191690836001600160401b031602179055506000805160206134ca83398151915287878787878787604051610ee2979695949392919061322b565b60405180910390a150505050505050565b60606000806000610f0385610c2e565b90506000816001600160401b03811115610f1f57610f1f612ebb565b604051908082528060200260200182016040528015610f48578160200160208202803683370190505b509050610f536128fd565b60005b838614610fcd57610f6681612484565b91508160400151610fc55781516001600160a01b031615610f8657815194505b876001600160a01b0316856001600160a01b031603610fc55780838780600101985081518110610fb857610fb86131cf565b6020026020010181815250505b600101610f56565b50909695505050505050565b6008546001600160a01b031690565b610ff0611bef565b60125460005b8181101561105f57601280548061100f5761100f61327b565b60008281526020812060036000199093019283020180546001600160701b0319168155600181019190915560020180546001600160981b0319169055905580611057816131fb565b915050610ff6565b5060005b828110156109015760018110611102578383611080600184613214565b81811061108f5761108f6131cf565b905060c0020160a00160208101906110a79190612c9e565b6001600160401b03168484838181106110c2576110c26131cf565b905060c0020160800160208101906110da9190612c9e565b6001600160401b0316101561110257604051636bc1af9360e01b815260040160405180910390fd5b61115e848483818110611117576111176131cf565b905060c00201608001602081019061112f9190612c9e565b858584818110611141576111416131cf565b905060c0020160a00160208101906111599190612c9e565b61244e565b60126040518060c0016040528086868581811061117d5761117d6131cf565b61119392602060c0909202019081019150613291565b6001600160501b031681526020018686858181106111b3576111b36131cf565b905060c0020160200160208101906111cb91906132ac565b63ffffffff1681526020018686858181106111e8576111e86131cf565b905060c00201604001358152602001868685818110611209576112096131cf565b905060c00201606001602081019061122191906132c7565b62ffffff16815260200186868581811061123d5761123d6131cf565b905060c0020160800160208101906112559190612c9e565b6001600160401b03168152602001868685818110611275576112756131cf565b905060c0020160a001602081019061128d9190612c9e565b6001600160401b039081169091528254600181810185556000948552602094859020845160039093020180549585015163ffffffff16600160501b026001600160701b03199096166001600160501b0390931692909217949094178155604083015193810193909355606082015160029093018054608084015160a0909401518316600160581b02600160581b600160981b0319949093166301000000026001600160581b031990911662ffffff9095169490941793909317919091161790556000805160206134ca8339815191528185858281811061136f5761136f6131cf565b61138592602060c0909202019081019150613291565b868685818110611397576113976131cf565b905060c0020160200160208101906113af91906132ac565b8787868181106113c1576113c16131cf565b905060c00201604001358888878181106113dd576113dd6131cf565b905060c0020160600160208101906113f591906132c7565b898988818110611407576114076131cf565b905060c00201608001602081019061141f9190612c9e565b8a8a89818110611431576114316131cf565b905060c0020160a00160208101906114499190612c9e565b60405161145c979695949392919061322b565b60405180910390a18061146e816131fb565b915050611063565b60606003805461078e90612fd6565b6000610779826124a4565b60608183106114b257604051631960ccad60e11b815260040160405180910390fd5b6000806114be60005490565b9050808411156114cc578093505b60006114d787610c2e565b9050848610156114f657858503818110156114f0578091505b506114fa565b5060005b6000816001600160401b0381111561151457611514612ebb565b60405190808252806020026020018201604052801561153d578160200160208202803683370190505b5090508160000361155357935061160292505050565b600061155e88611853565b90506000816040015161156f575080515b885b8881141580156115815750848714155b156115f65761158f81612484565b925082604001516115ee5782516001600160a01b0316156115af57825191505b8a6001600160a01b0316826001600160a01b0316036115ee57808488806001019950815181106115e1576115e16131cf565b6020026020010181815250505b600101611571565b50505092835250909150505b9392505050565b8161161381611a9f565b61086983836124cc565b611625612924565b6012546000908190841061166f5760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964537461676560a01b60448201526064015b60405180910390fd5b60008481526013602090815260408083203384528252808320548784526014909252909120546012805463ffffffff90931692879081106116b2576116b26131cf565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b0381168452600160501b900463ffffffff169383019390935260018301549082015260029091015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152969195509350915050565b611744611bef565b60116108698284836130e1565b611759611bef565b8163ffffffff16600b54816117716001546000540390565b61177b91906132e2565b111561179a5760405163800113cb60e01b815260040160405180910390fd5b8263ffffffff16600e546117ae91906132fa565b3410156117ce57604051630717c22560e51b815260040160405180910390fd5b6117de828463ffffffff16612538565b600d546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015610901573d6000803e3d6000fd5b60606011805461078e90612fd6565b836001600160a01b03811633146118405761184033611a9f565b61184c85858585612552565b5050505050565b61185b6128fd565b6118636128fd565b60005483106118725792915050565b61187b83612484565b905080604001511561188d5792915050565b61160283612596565b60606118a182611a78565b6118be57604051630a14c4b560e41b815260040160405180910390fd5b6000601080546118cd90612fd6565b80601f01602080910402602001604051908101604052809291908181526020018280546118f990612fd6565b80156119465780601f1061191b57610100808354040283529160200191611946565b820191906000526020600020905b81548152906001019060200180831161192957829003601f168201915b50505050509050805160000361196b5760405180602001604052806000815250611602565b80611975846125af565b601160405160200161198993929190613319565b6040516020818303038152906040529392505050565b6119a7611bef565b6001600160a01b038116611a0c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401611666565b611a15816123fc565b50565b611a20611bef565b600b54811115611a435760405163430b83b160e11b815260040160405180910390fd5b600b8190556040518181527fc7bbc2b288fc13314546ea4aa51f6bcf71b7ba4740beeb3d32e9acef57b6668a90602001610963565b6000805482108015610779575050600090815260046020526040902054600160e01b161590565b6daaeb6d7670e522a718067333cd4e3b15611a1557604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611b0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3091906133b9565b611a155780604051633b79c77360e21b81526004016116669190612a10565b6000611b5a82610b5b565b9050336001600160a01b03821614611b9357611b768133610694565b611b93576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b33611bf8610fd9565b6001600160a01b031614610c8e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611666565b600260095403611ca05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611666565b6002600955565b8363ffffffff16600b5481611cbf6001546000540390565b611cc991906132e2565b1115611ce85760405163800113cb60e01b815260040160405180910390fd5b42611cf1612924565b6000611cfc83610b66565b905060128181548110611d1157611d116131cf565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b038116808552600160501b90910463ffffffff16948401949094526001810154918301919091526002015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152600f549093501115611ded57600e54825163ffffffff8a1691611dbe916001600160501b03166132e2565b611dc891906132fa565b341015611de857604051630717c22560e51b815260040160405180910390fd5b611e29565b8151611e009063ffffffff8a16906133d6565b6001600160501b0316341015611e2957604051630717c22560e51b815260040160405180910390fd5b606082015162ffffff1615611e8357606082015160008281526014602052604090205462ffffff90911690611e659063ffffffff8b16906132e2565b1115611e835760405162d0844960e21b815260040160405180910390fd5b600c5415611ec757600c548863ffffffff16611e9e896124a4565b611ea891906132e2565b1115611ec75760405163751304ed60e11b815260040160405180910390fd5b602082015163ffffffff1615611f395760208083015160008381526013835260408082206001600160a01b038c168352909352919091205463ffffffff91821691611f14918b9116613405565b63ffffffff161115611f395760405163b4f3729b60e01b815260040160405180910390fd5b604082015115611fd8578160400151611fba878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040516001600160601b031960608e901b1660208201526034019150611f9f9050565b604051602081830303815290604052805190602001206125f3565b14611fd8576040516309bde33960e01b815260040160405180910390fd5b60008181526013602090815260408083206001600160a01b038b168452909152812080548a929061201090849063ffffffff16613405565b92506101000a81548163ffffffff021916908363ffffffff1602179055508763ffffffff1660146000838152602001908152602001600020600082825461205791906132e2565b9091555061206d90508763ffffffff8a16612538565b600f5482516001600160501b0316101561213157600d54600e546001600160a01b03909116906108fc906120a89063ffffffff8c16906132fa565b6040518115909202916000818181858888f193505050501580156120d0573d6000803e3d6000fd5b506120d9610fd9565b6001600160a01b03166108fc8963ffffffff16600e546120f991906132fa565b6121039034613214565b6040518115909202916000818181858888f1935050505015801561212b573d6000803e3d6000fd5b506121e9565b600d546001600160a01b03166108fc63ffffffff8a1661215260423461342d565b61215c91906132fa565b6040518115909202916000818181858888f19350505050158015612184573d6000803e3d6000fd5b5061218d610fd9565b6001600160a01b03166108fc63ffffffff8a166121ab60423461342d565b6121b591906132fa565b6121bf9034613214565b6040518115909202916000818181858888f193505050501580156121e7573d6000803e3d6000fd5b505b5050505050505050565b60006121fe82612395565b9050836001600160a01b0316816001600160a01b0316146122315760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b0388169091141761227e576122618633610694565b61227e57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b0385166122a557604051633a954ecd60e21b815260040160405180910390fd5b80156122b057600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716815220805460010190556122ed85600160e11b612640565b600085815260046020526040812091909155600160e11b84169003612342576001840160008181526004602052604081205490036123405760005481146123405760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03166000805160206134aa83398151915260405160405180910390a45b505050505050565b61086983838360405180602001604052806000815250611826565b6000816000548110156123e35760008181526004602052604081205490600160e01b821690036123e1575b806000036116025750600019016000818152600460205260409020546123c0565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b806001600160401b0316826001600160401b03161061248057604051631750215560e11b815260040160405180910390fd5b5050565b61248c6128fd565b60008281526004602052604090205461077990612655565b6001600160a01b03166000908152600560205260409081902054901c6001600160401b031690565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b612480828260405180602001604052806000815250612698565b61255d8484846108dc565b6001600160a01b0383163b1561090157612579848484846126fe565b610901576040516368d2bf6b60e11b815260040160405180910390fd5b61259e6128fd565b6107796125aa83612395565b612655565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806125c95750819003601f19909101908152919050565b600081815b84518110156126385761262482868381518110612617576126176131cf565b60200260200101516127e9565b915080612630816131fb565b9150506125f8565b509392505050565b4260a01b176001600160a01b03919091161790565b61265d6128fd565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b6126a28383612815565b6001600160a01b0383163b15610869576000548281035b6126cc60008683806001019450866126fe565b6126e9576040516368d2bf6b60e11b815260040160405180910390fd5b8181106126b957816000541461184c57600080fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061273390339089908890889060040161344f565b6020604051808303816000875af192505050801561276e575060408051601f3d908101601f1916820190925261276b9181019061348c565b60015b6127cc573d80801561279c576040519150601f19603f3d011682016040523d82523d6000602084013e6127a1565b606091505b5080516000036127c4576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6000818310612805576000828152602084905260409020611602565b5060009182526020526040902090565b600080549082900361283a5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040902080546001600160401b018402019055612871836001841460e11b612640565b6000828152600460205260408120919091556001600160a01b0384169083830190839083906000805160206134aa8339815191528180a4600183015b8181146128d357808360006000805160206134aa833981519152600080a46001016128ad565b50816000036128f457604051622e076360e81b815260040160405180910390fd5b60005550505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6001600160e01b031981168114611a1557600080fd5b60006020828403121561298157600080fd5b813561160281612959565b60005b838110156129a757818101518382015260200161298f565b838111156109015750506000910152565b600081518084526129d081602086016020860161298c565b601f01601f19169290920160200192915050565b60208152600061160260208301846129b8565b600060208284031215612a0957600080fd5b5035919050565b6001600160a01b0391909116815260200190565b80356001600160a01b0381168114612a3b57600080fd5b919050565b60008060408385031215612a5357600080fd5b612a5c83612a24565b946020939093013593505050565b803563ffffffff81168114612a3b57600080fd5b60008083601f840112612a9057600080fd5b5081356001600160401b03811115612aa757600080fd5b6020830191508360208260051b8501011115612ac257600080fd5b9250929050565b600080600060408486031215612ade57600080fd5b612ae784612a6a565b925060208401356001600160401b03811115612b0257600080fd5b612b0e86828701612a7e565b9497909650939450505050565b600080600060608486031215612b3057600080fd5b612b3984612a24565b9250612b4760208501612a24565b9150604084013590509250925092565b60008060208385031215612b6a57600080fd5b82356001600160401b0380821115612b8157600080fd5b818501915085601f830112612b9557600080fd5b813581811115612ba457600080fd5b866020828501011115612bb657600080fd5b60209290920196919550909350505050565b60008060208385031215612bdb57600080fd5b82356001600160401b03811115612bf157600080fd5b612bfd85828601612a7e565b90969095509350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b81811015610fcd57612c74838551612c09565b9284019260809290920191600101612c61565b80356001600160401b0381168114612a3b57600080fd5b600060208284031215612cb057600080fd5b61160282612c87565b600060208284031215612ccb57600080fd5b61160282612a24565b80356001600160501b0381168114612a3b57600080fd5b803562ffffff81168114612a3b57600080fd5b600080600080600080600060e0888a031215612d1957600080fd5b87359650612d2960208901612cd4565b9550612d3760408901612a6a565b945060608801359350612d4c60808901612ceb565b9250612d5a60a08901612c87565b9150612d6860c08901612c87565b905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015610fcd57835183529284019291840191600101612d92565b60008060208385031215612dc157600080fd5b82356001600160401b0380821115612dd857600080fd5b818501915085601f830112612dec57600080fd5b813581811115612dfb57600080fd5b86602060c083028501011115612bb657600080fd5b600080600060608486031215612e2557600080fd5b612e2e84612a24565b95602085013595506040909401359392505050565b8015158114611a1557600080fd5b60008060408385031215612e6457600080fd5b612e6d83612a24565b91506020830135612e7d81612e43565b809150509250929050565b60008060408385031215612e9b57600080fd5b612ea483612a6a565b9150612eb260208401612a24565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612ee757600080fd5b612ef085612a24565b9350612efe60208601612a24565b92506040850135915060608501356001600160401b0380821115612f2157600080fd5b818701915087601f830112612f3557600080fd5b813581811115612f4757612f47612ebb565b604051601f8201601f19908116603f01168101908382118183101715612f6f57612f6f612ebb565b816040528281528a6020848701011115612f8857600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b608081016107798284612c09565b60008060408385031215612fcd57600080fd5b612ea483612a24565b600181811c90821680612fea57607f821691505b60208210810361300a57634e487b7160e01b600052602260045260246000fd5b50919050565b600060208083526000845461302481612fd6565b80848701526040600180841660008114613045576001811461305f5761308d565b60ff1985168984015283151560051b89018301955061308d565b896000528660002060005b858110156130855781548b820186015290830190880161306a565b8a0184019650505b509398975050505050505050565b601f82111561086957600081815260208120601f850160051c810160208610156130c25750805b601f850160051c820191505b81811015612372578281556001016130ce565b6001600160401b038311156130f8576130f8612ebb565b61310c836131068354612fd6565b8361309b565b6000601f84116001811461314057600085156131285750838201355b600019600387901b1c1916600186901b17835561184c565b600083815260209020601f19861690835b828110156131715786850135825560209485019460019092019101613151565b508682101561318e5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161320d5761320d6131e5565b5060010190565b600082821015613226576132266131e5565b500390565b9687526001600160501b0395909516602087015263ffffffff939093166040860152606085019190915262ffffff1660808401526001600160401b0390811660a08401521660c082015260e00190565b634e487b7160e01b600052603160045260246000fd5b6000602082840312156132a357600080fd5b61160282612cd4565b6000602082840312156132be57600080fd5b61160282612a6a565b6000602082840312156132d957600080fd5b61160282612ceb565b600082198211156132f5576132f56131e5565b500190565b6000816000190483118215151615613314576133146131e5565b500290565b60008451602061332c8285838a0161298c565b85519184019161333f8184848a0161298c565b855492019160009061335081612fd6565b60018281168015613368576001811461337d576133a9565b60ff19841687528215158302870194506133a9565b896000528560002060005b848110156133a157815489820152908301908701613388565b505082870194505b50929a9950505050505050505050565b6000602082840312156133cb57600080fd5b815161160281612e43565b60006001600160501b03828116848216811515828404821116156133fc576133fc6131e5565b02949350505050565b600063ffffffff808316818516808303821115613424576134246131e5565b01949350505050565b60008261344a57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613482908301846129b8565b9695505050505050565b60006020828403121561349e57600080fd5b81516116028161295956feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efb3268648542a1bb1b2dd12e3b14aeb5a3ab22c592de96bdd3e842154a5b394faa2646970667358221220a2a66850a790d91d2d9d54ac6b6a896612bbf26c4e3c6c41c8198584cf4c1cce64736f6c634300080f0033697066733a2f2f6261667962656964347a7065766972726d32656733686c776136366263646a657a77623537796b6c7467696a6e76326f6f737366377074676662752f
Deployed Bytecode
0x6080604052600436106101d65760003560e01c806301ffc9a7146101db57806306fdde0314610210578063081812fc14610232578063095ea7b31461025f5780631053a81514610274578063107af24b1461028957806318160ddd1461029c57806323b872dd146102bf578063372992e4146102d25780633ccfd60b146102f257806341f434341461030757806342842e0e1461032957806342cde4e81461033c5780634b1c53b41461035257806355f804b3146103675780635bbb2177146103875780636352211e146103b457806367808a34146103d457806370a08231146103f457806370da24ee14610414578063715018a61461042957806373e1607e1461043e5780638462151c1461045e5780638da5cb5b1461048b5780638dcdb09d146104a057806395d89b41146104c057806397cf84fc146104d557806399a2557a146104f5578063a22cb46514610515578063a3759f6014610535578063a9852bfb146105d1578063aac5ab1f146105f1578063b7a9fa6014610604578063b88d4fde14610619578063c23dc68f1461062c578063c87b56dd14610659578063e985e9c514610679578063efdaa2ec146106c2578063f2fde38b146106d7578063f8d09696146106f7578063fa42717714610717575b600080fd5b3480156101e757600080fd5b506101fb6101f636600461296f565b61072d565b60405190151581526020015b60405180910390f35b34801561021c57600080fd5b5061022561077f565b60405161020791906129e4565b34801561023e57600080fd5b5061025261024d3660046129f7565b610811565b6040516102079190612a10565b61027261026d366004612a40565b610855565b005b34801561028057600080fd5b5061027261086e565b610272610297366004612ac9565b6108be565b3480156102a857600080fd5b50600154600054035b604051908152602001610207565b6102726102cd366004612b1b565b6108dc565b3480156102de57600080fd5b506102726102ed3660046129f7565b610907565b3480156102fe57600080fd5b5061027261096e565b34801561031357600080fd5b506102526daaeb6d7670e522a718067333cd4e81565b610272610337366004612b1b565b610a19565b34801561034857600080fd5b506102b1600f5481565b34801561035e57600080fd5b50600b546102b1565b34801561037357600080fd5b50610272610382366004612b57565b610a3e565b34801561039357600080fd5b506103a76103a2366004612bc8565b610aa9565b6040516102079190612c45565b3480156103c057600080fd5b506102526103cf3660046129f7565b610b5b565b3480156103e057600080fd5b506102b16103ef366004612c9e565b610b66565b34801561040057600080fd5b506102b161040f366004612cb9565b610c2e565b34801561042057600080fd5b506012546102b1565b34801561043557600080fd5b50610272610c7c565b34801561044a57600080fd5b50610272610459366004612cfe565b610c90565b34801561046a57600080fd5b5061047e610479366004612cb9565b610ef3565b6040516102079190612d76565b34801561049757600080fd5b50610252610fd9565b3480156104ac57600080fd5b506102726104bb366004612dae565b610fe8565b3480156104cc57600080fd5b50610225611476565b3480156104e157600080fd5b506102b16104f0366004612cb9565b611485565b34801561050157600080fd5b5061047e610510366004612e10565b611490565b34801561052157600080fd5b50610272610530366004612e51565b611609565b34801561054157600080fd5b506105556105503660046129f7565b61161d565b6040805184516001600160501b0316815260208086015163ffffffff90811691830191909152858301519282019290925260608086015162ffffff16908201526080808601516001600160401b039081169183019190915260a095860151169481019490945290911660c083015260e082015261010001610207565b3480156105dd57600080fd5b506102726105ec366004612b57565b61173c565b6102726105ff366004612e88565b611751565b34801561061057600080fd5b50610225611817565b610272610627366004612ed1565b611826565b34801561063857600080fd5b5061064c6106473660046129f7565b611853565b6040516102079190612fac565b34801561066557600080fd5b506102256106743660046129f7565b611896565b34801561068557600080fd5b506101fb610694366004612fba565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156106ce57600080fd5b50600c546102b1565b3480156106e357600080fd5b506102726106f2366004612cb9565b61199f565b34801561070357600080fd5b506102726107123660046129f7565b611a18565b34801561072357600080fd5b506102b1600e5481565b60006301ffc9a760e01b6001600160e01b03198316148061075e57506380ac58cd60e01b6001600160e01b03198316145b806107795750635b5e139f60e01b6001600160e01b03198316145b92915050565b60606002805461078e90612fd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107ba90612fd6565b80156108075780601f106107dc57610100808354040283529160200191610807565b820191906000526020600020905b8154815290600101906020018083116107ea57829003601f168201915b5050505050905090565b600061081c82611a78565b610839576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b8161085f81611a9f565b6108698383611b4f565b505050565b610876611bef565b600a805460ff191660011790556040517fc6a6c2b165e62c9d37fc51a18ed76e5be22304bc1d337877c98f31c23e40b0f5906108b490601090613010565b60405180910390a1565b6108c6611c4e565b6108d283338484611ca7565b6108696001600955565b826001600160a01b03811633146108f6576108f633611a9f565b6109018484846121f3565b50505050565b61090f611bef565b600b5481111561093257604051630590c51360e01b815260040160405180910390fd5b600c8190556040518181527f5307de8ad7d34d5ddfd5171435c143bdc645493980f453eb5d7cdb3e494a1b35906020015b60405180910390a150565b610976611bef565b6040514790600090339083908381818185875af1925050503d80600081146109ba576040519150601f19603f3d011682016040523d82523d6000602084013e6109bf565b606091505b50509050806109e157604051631d42c86760e21b815260040160405180910390fd5b6040518281527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020015b60405180910390a15050565b826001600160a01b0381163314610a3357610a3333611a9f565b61090184848461237a565b610a46611bef565b600a5460ff1615610a6a576040516306ccad4160e41b815260040160405180910390fd5b6010610a778284836130e1565b507f23c8c9488efebfd474e85a7956de6f39b17c7ab88502d42a623db2d8e382bbaa8282604051610a0d9291906131a0565b6060816000816001600160401b03811115610ac657610ac6612ebb565b604051908082528060200260200182016040528015610aff57816020015b610aec6128fd565b815260200190600190039081610ae45790505b50905060005b828114610b5257610b2d868683818110610b2157610b216131cf565b90506020020135611853565b828281518110610b3f57610b3f6131cf565b6020908102919091010152600101610b05565b50949350505050565b600061077982612395565b6000805b601254811015610c145760128181548110610b8757610b876131cf565b60009182526020909120600260039092020101546001600160401b036301000000909104811690841610801590610bf7575060128181548110610bcc57610bcc6131cf565b60009182526020909120600260039092020101546001600160401b03600160581b9091048116908416105b15610c025792915050565b80610c0c816131fb565b915050610b6a565b5060405163e82a532960e01b815260040160405180910390fd5b60006001600160a01b038216610c57576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b610c84611bef565b610c8e60006123fc565b565b610c98611bef565b6012548710610cba5760405163e82a532960e01b815260040160405180910390fd5b60018710610d27576012610ccf600189613214565b81548110610cdf57610cdf6131cf565b60009182526020909120600260039092020101546001600160401b03600160581b90910481169083161015610d2757604051636bc1af9360e01b815260040160405180910390fd5b610d31828261244e565b8560128881548110610d4557610d456131cf565b906000526020600020906003020160000160006101000a8154816001600160501b0302191690836001600160501b031602179055508460128881548110610d8e57610d8e6131cf565b9060005260206000209060030201600001600a6101000a81548163ffffffff021916908363ffffffff1602179055508360128881548110610dd157610dd16131cf565b9060005260206000209060030201600101819055508260128881548110610dfa57610dfa6131cf565b906000526020600020906003020160020160006101000a81548162ffffff021916908362ffffff1602179055508160128881548110610e3b57610e3b6131cf565b906000526020600020906003020160020160036101000a8154816001600160401b0302191690836001600160401b031602179055508060128881548110610e8457610e846131cf565b9060005260206000209060030201600201600b6101000a8154816001600160401b0302191690836001600160401b031602179055506000805160206134ca83398151915287878787878787604051610ee2979695949392919061322b565b60405180910390a150505050505050565b60606000806000610f0385610c2e565b90506000816001600160401b03811115610f1f57610f1f612ebb565b604051908082528060200260200182016040528015610f48578160200160208202803683370190505b509050610f536128fd565b60005b838614610fcd57610f6681612484565b91508160400151610fc55781516001600160a01b031615610f8657815194505b876001600160a01b0316856001600160a01b031603610fc55780838780600101985081518110610fb857610fb86131cf565b6020026020010181815250505b600101610f56565b50909695505050505050565b6008546001600160a01b031690565b610ff0611bef565b60125460005b8181101561105f57601280548061100f5761100f61327b565b60008281526020812060036000199093019283020180546001600160701b0319168155600181019190915560020180546001600160981b0319169055905580611057816131fb565b915050610ff6565b5060005b828110156109015760018110611102578383611080600184613214565b81811061108f5761108f6131cf565b905060c0020160a00160208101906110a79190612c9e565b6001600160401b03168484838181106110c2576110c26131cf565b905060c0020160800160208101906110da9190612c9e565b6001600160401b0316101561110257604051636bc1af9360e01b815260040160405180910390fd5b61115e848483818110611117576111176131cf565b905060c00201608001602081019061112f9190612c9e565b858584818110611141576111416131cf565b905060c0020160a00160208101906111599190612c9e565b61244e565b60126040518060c0016040528086868581811061117d5761117d6131cf565b61119392602060c0909202019081019150613291565b6001600160501b031681526020018686858181106111b3576111b36131cf565b905060c0020160200160208101906111cb91906132ac565b63ffffffff1681526020018686858181106111e8576111e86131cf565b905060c00201604001358152602001868685818110611209576112096131cf565b905060c00201606001602081019061122191906132c7565b62ffffff16815260200186868581811061123d5761123d6131cf565b905060c0020160800160208101906112559190612c9e565b6001600160401b03168152602001868685818110611275576112756131cf565b905060c0020160a001602081019061128d9190612c9e565b6001600160401b039081169091528254600181810185556000948552602094859020845160039093020180549585015163ffffffff16600160501b026001600160701b03199096166001600160501b0390931692909217949094178155604083015193810193909355606082015160029093018054608084015160a0909401518316600160581b02600160581b600160981b0319949093166301000000026001600160581b031990911662ffffff9095169490941793909317919091161790556000805160206134ca8339815191528185858281811061136f5761136f6131cf565b61138592602060c0909202019081019150613291565b868685818110611397576113976131cf565b905060c0020160200160208101906113af91906132ac565b8787868181106113c1576113c16131cf565b905060c00201604001358888878181106113dd576113dd6131cf565b905060c0020160600160208101906113f591906132c7565b898988818110611407576114076131cf565b905060c00201608001602081019061141f9190612c9e565b8a8a89818110611431576114316131cf565b905060c0020160a00160208101906114499190612c9e565b60405161145c979695949392919061322b565b60405180910390a18061146e816131fb565b915050611063565b60606003805461078e90612fd6565b6000610779826124a4565b60608183106114b257604051631960ccad60e11b815260040160405180910390fd5b6000806114be60005490565b9050808411156114cc578093505b60006114d787610c2e565b9050848610156114f657858503818110156114f0578091505b506114fa565b5060005b6000816001600160401b0381111561151457611514612ebb565b60405190808252806020026020018201604052801561153d578160200160208202803683370190505b5090508160000361155357935061160292505050565b600061155e88611853565b90506000816040015161156f575080515b885b8881141580156115815750848714155b156115f65761158f81612484565b925082604001516115ee5782516001600160a01b0316156115af57825191505b8a6001600160a01b0316826001600160a01b0316036115ee57808488806001019950815181106115e1576115e16131cf565b6020026020010181815250505b600101611571565b50505092835250909150505b9392505050565b8161161381611a9f565b61086983836124cc565b611625612924565b6012546000908190841061166f5760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964537461676560a01b60448201526064015b60405180910390fd5b60008481526013602090815260408083203384528252808320548784526014909252909120546012805463ffffffff90931692879081106116b2576116b26131cf565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b0381168452600160501b900463ffffffff169383019390935260018301549082015260029091015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152969195509350915050565b611744611bef565b60116108698284836130e1565b611759611bef565b8163ffffffff16600b54816117716001546000540390565b61177b91906132e2565b111561179a5760405163800113cb60e01b815260040160405180910390fd5b8263ffffffff16600e546117ae91906132fa565b3410156117ce57604051630717c22560e51b815260040160405180910390fd5b6117de828463ffffffff16612538565b600d546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015610901573d6000803e3d6000fd5b60606011805461078e90612fd6565b836001600160a01b03811633146118405761184033611a9f565b61184c85858585612552565b5050505050565b61185b6128fd565b6118636128fd565b60005483106118725792915050565b61187b83612484565b905080604001511561188d5792915050565b61160283612596565b60606118a182611a78565b6118be57604051630a14c4b560e41b815260040160405180910390fd5b6000601080546118cd90612fd6565b80601f01602080910402602001604051908101604052809291908181526020018280546118f990612fd6565b80156119465780601f1061191b57610100808354040283529160200191611946565b820191906000526020600020905b81548152906001019060200180831161192957829003601f168201915b50505050509050805160000361196b5760405180602001604052806000815250611602565b80611975846125af565b601160405160200161198993929190613319565b6040516020818303038152906040529392505050565b6119a7611bef565b6001600160a01b038116611a0c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401611666565b611a15816123fc565b50565b611a20611bef565b600b54811115611a435760405163430b83b160e11b815260040160405180910390fd5b600b8190556040518181527fc7bbc2b288fc13314546ea4aa51f6bcf71b7ba4740beeb3d32e9acef57b6668a90602001610963565b6000805482108015610779575050600090815260046020526040902054600160e01b161590565b6daaeb6d7670e522a718067333cd4e3b15611a1557604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611b0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3091906133b9565b611a155780604051633b79c77360e21b81526004016116669190612a10565b6000611b5a82610b5b565b9050336001600160a01b03821614611b9357611b768133610694565b611b93576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b33611bf8610fd9565b6001600160a01b031614610c8e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611666565b600260095403611ca05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611666565b6002600955565b8363ffffffff16600b5481611cbf6001546000540390565b611cc991906132e2565b1115611ce85760405163800113cb60e01b815260040160405180910390fd5b42611cf1612924565b6000611cfc83610b66565b905060128181548110611d1157611d116131cf565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b038116808552600160501b90910463ffffffff16948401949094526001810154918301919091526002015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152600f549093501115611ded57600e54825163ffffffff8a1691611dbe916001600160501b03166132e2565b611dc891906132fa565b341015611de857604051630717c22560e51b815260040160405180910390fd5b611e29565b8151611e009063ffffffff8a16906133d6565b6001600160501b0316341015611e2957604051630717c22560e51b815260040160405180910390fd5b606082015162ffffff1615611e8357606082015160008281526014602052604090205462ffffff90911690611e659063ffffffff8b16906132e2565b1115611e835760405162d0844960e21b815260040160405180910390fd5b600c5415611ec757600c548863ffffffff16611e9e896124a4565b611ea891906132e2565b1115611ec75760405163751304ed60e11b815260040160405180910390fd5b602082015163ffffffff1615611f395760208083015160008381526013835260408082206001600160a01b038c168352909352919091205463ffffffff91821691611f14918b9116613405565b63ffffffff161115611f395760405163b4f3729b60e01b815260040160405180910390fd5b604082015115611fd8578160400151611fba878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040516001600160601b031960608e901b1660208201526034019150611f9f9050565b604051602081830303815290604052805190602001206125f3565b14611fd8576040516309bde33960e01b815260040160405180910390fd5b60008181526013602090815260408083206001600160a01b038b168452909152812080548a929061201090849063ffffffff16613405565b92506101000a81548163ffffffff021916908363ffffffff1602179055508763ffffffff1660146000838152602001908152602001600020600082825461205791906132e2565b9091555061206d90508763ffffffff8a16612538565b600f5482516001600160501b0316101561213157600d54600e546001600160a01b03909116906108fc906120a89063ffffffff8c16906132fa565b6040518115909202916000818181858888f193505050501580156120d0573d6000803e3d6000fd5b506120d9610fd9565b6001600160a01b03166108fc8963ffffffff16600e546120f991906132fa565b6121039034613214565b6040518115909202916000818181858888f1935050505015801561212b573d6000803e3d6000fd5b506121e9565b600d546001600160a01b03166108fc63ffffffff8a1661215260423461342d565b61215c91906132fa565b6040518115909202916000818181858888f19350505050158015612184573d6000803e3d6000fd5b5061218d610fd9565b6001600160a01b03166108fc63ffffffff8a166121ab60423461342d565b6121b591906132fa565b6121bf9034613214565b6040518115909202916000818181858888f193505050501580156121e7573d6000803e3d6000fd5b505b5050505050505050565b60006121fe82612395565b9050836001600160a01b0316816001600160a01b0316146122315760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b0388169091141761227e576122618633610694565b61227e57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b0385166122a557604051633a954ecd60e21b815260040160405180910390fd5b80156122b057600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716815220805460010190556122ed85600160e11b612640565b600085815260046020526040812091909155600160e11b84169003612342576001840160008181526004602052604081205490036123405760005481146123405760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03166000805160206134aa83398151915260405160405180910390a45b505050505050565b61086983838360405180602001604052806000815250611826565b6000816000548110156123e35760008181526004602052604081205490600160e01b821690036123e1575b806000036116025750600019016000818152600460205260409020546123c0565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b806001600160401b0316826001600160401b03161061248057604051631750215560e11b815260040160405180910390fd5b5050565b61248c6128fd565b60008281526004602052604090205461077990612655565b6001600160a01b03166000908152600560205260409081902054901c6001600160401b031690565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b612480828260405180602001604052806000815250612698565b61255d8484846108dc565b6001600160a01b0383163b1561090157612579848484846126fe565b610901576040516368d2bf6b60e11b815260040160405180910390fd5b61259e6128fd565b6107796125aa83612395565b612655565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806125c95750819003601f19909101908152919050565b600081815b84518110156126385761262482868381518110612617576126176131cf565b60200260200101516127e9565b915080612630816131fb565b9150506125f8565b509392505050565b4260a01b176001600160a01b03919091161790565b61265d6128fd565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b6126a28383612815565b6001600160a01b0383163b15610869576000548281035b6126cc60008683806001019450866126fe565b6126e9576040516368d2bf6b60e11b815260040160405180910390fd5b8181106126b957816000541461184c57600080fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061273390339089908890889060040161344f565b6020604051808303816000875af192505050801561276e575060408051601f3d908101601f1916820190925261276b9181019061348c565b60015b6127cc573d80801561279c576040519150601f19603f3d011682016040523d82523d6000602084013e6127a1565b606091505b5080516000036127c4576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6000818310612805576000828152602084905260409020611602565b5060009182526020526040902090565b600080549082900361283a5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040902080546001600160401b018402019055612871836001841460e11b612640565b6000828152600460205260408120919091556001600160a01b0384169083830190839083906000805160206134aa8339815191528180a4600183015b8181146128d357808360006000805160206134aa833981519152600080a46001016128ad565b50816000036128f457604051622e076360e81b815260040160405180910390fd5b60005550505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6001600160e01b031981168114611a1557600080fd5b60006020828403121561298157600080fd5b813561160281612959565b60005b838110156129a757818101518382015260200161298f565b838111156109015750506000910152565b600081518084526129d081602086016020860161298c565b601f01601f19169290920160200192915050565b60208152600061160260208301846129b8565b600060208284031215612a0957600080fd5b5035919050565b6001600160a01b0391909116815260200190565b80356001600160a01b0381168114612a3b57600080fd5b919050565b60008060408385031215612a5357600080fd5b612a5c83612a24565b946020939093013593505050565b803563ffffffff81168114612a3b57600080fd5b60008083601f840112612a9057600080fd5b5081356001600160401b03811115612aa757600080fd5b6020830191508360208260051b8501011115612ac257600080fd5b9250929050565b600080600060408486031215612ade57600080fd5b612ae784612a6a565b925060208401356001600160401b03811115612b0257600080fd5b612b0e86828701612a7e565b9497909650939450505050565b600080600060608486031215612b3057600080fd5b612b3984612a24565b9250612b4760208501612a24565b9150604084013590509250925092565b60008060208385031215612b6a57600080fd5b82356001600160401b0380821115612b8157600080fd5b818501915085601f830112612b9557600080fd5b813581811115612ba457600080fd5b866020828501011115612bb657600080fd5b60209290920196919550909350505050565b60008060208385031215612bdb57600080fd5b82356001600160401b03811115612bf157600080fd5b612bfd85828601612a7e565b90969095509350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b81811015610fcd57612c74838551612c09565b9284019260809290920191600101612c61565b80356001600160401b0381168114612a3b57600080fd5b600060208284031215612cb057600080fd5b61160282612c87565b600060208284031215612ccb57600080fd5b61160282612a24565b80356001600160501b0381168114612a3b57600080fd5b803562ffffff81168114612a3b57600080fd5b600080600080600080600060e0888a031215612d1957600080fd5b87359650612d2960208901612cd4565b9550612d3760408901612a6a565b945060608801359350612d4c60808901612ceb565b9250612d5a60a08901612c87565b9150612d6860c08901612c87565b905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015610fcd57835183529284019291840191600101612d92565b60008060208385031215612dc157600080fd5b82356001600160401b0380821115612dd857600080fd5b818501915085601f830112612dec57600080fd5b813581811115612dfb57600080fd5b86602060c083028501011115612bb657600080fd5b600080600060608486031215612e2557600080fd5b612e2e84612a24565b95602085013595506040909401359392505050565b8015158114611a1557600080fd5b60008060408385031215612e6457600080fd5b612e6d83612a24565b91506020830135612e7d81612e43565b809150509250929050565b60008060408385031215612e9b57600080fd5b612ea483612a6a565b9150612eb260208401612a24565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612ee757600080fd5b612ef085612a24565b9350612efe60208601612a24565b92506040850135915060608501356001600160401b0380821115612f2157600080fd5b818701915087601f830112612f3557600080fd5b813581811115612f4757612f47612ebb565b604051601f8201601f19908116603f01168101908382118183101715612f6f57612f6f612ebb565b816040528281528a6020848701011115612f8857600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b608081016107798284612c09565b60008060408385031215612fcd57600080fd5b612ea483612a24565b600181811c90821680612fea57607f821691505b60208210810361300a57634e487b7160e01b600052602260045260246000fd5b50919050565b600060208083526000845461302481612fd6565b80848701526040600180841660008114613045576001811461305f5761308d565b60ff1985168984015283151560051b89018301955061308d565b896000528660002060005b858110156130855781548b820186015290830190880161306a565b8a0184019650505b509398975050505050505050565b601f82111561086957600081815260208120601f850160051c810160208610156130c25750805b601f850160051c820191505b81811015612372578281556001016130ce565b6001600160401b038311156130f8576130f8612ebb565b61310c836131068354612fd6565b8361309b565b6000601f84116001811461314057600085156131285750838201355b600019600387901b1c1916600186901b17835561184c565b600083815260209020601f19861690835b828110156131715786850135825560209485019460019092019101613151565b508682101561318e5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161320d5761320d6131e5565b5060010190565b600082821015613226576132266131e5565b500390565b9687526001600160501b0395909516602087015263ffffffff939093166040860152606085019190915262ffffff1660808401526001600160401b0390811660a08401521660c082015260e00190565b634e487b7160e01b600052603160045260246000fd5b6000602082840312156132a357600080fd5b61160282612cd4565b6000602082840312156132be57600080fd5b61160282612a6a565b6000602082840312156132d957600080fd5b61160282612ceb565b600082198211156132f5576132f56131e5565b500190565b6000816000190483118215151615613314576133146131e5565b500290565b60008451602061332c8285838a0161298c565b85519184019161333f8184848a0161298c565b855492019160009061335081612fd6565b60018281168015613368576001811461337d576133a9565b60ff19841687528215158302870194506133a9565b896000528560002060005b848110156133a157815489820152908301908701613388565b505082870194505b50929a9950505050505050505050565b6000602082840312156133cb57600080fd5b815161160281612e43565b60006001600160501b03828116848216811515828404821116156133fc576133fc6131e5565b02949350505050565b600063ffffffff808316818516808303821115613424576134246131e5565b01949350505050565b60008261344a57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613482908301846129b8565b9695505050505050565b60006020828403121561349e57600080fd5b81516116028161295956feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efb3268648542a1bb1b2dd12e3b14aeb5a3ab22c592de96bdd3e842154a5b394faa2646970667358221220a2a66850a790d91d2d9d54ac6b6a896612bbf26c4e3c6c41c8198584cf4c1cce64736f6c634300080f0033
Deployed Bytecode Sourcemap
99385:16642:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32666:675;;;;;;;;;;-1:-1:-1;32666:675:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;32666:675:0;;;;;;;;33640:108;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;40811:234::-;;;;;;;;;;-1:-1:-1;40811:234:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;115068:192::-;;;;;;:::i;:::-;;:::i;:::-;;112453:154;;;;;;;;;;;;;:::i;108375:183::-;;;;;;:::i;:::-;;:::i;28975:347::-;;;;;;;;;;-1:-1:-1;29265:12:0;;29036:7;29249:13;:28;28975:347;;;3373:25:1;;;3361:2;3346:18;28975:347:0;3227:177:1;115276:198:0;;;;;;:::i;:::-;;:::i;105244:345::-;;;;;;;;;;-1:-1:-1;105244:345:0;;;;;:::i;:::-;;:::i;111771:257::-;;;;;;;;;;;;;:::i;8429:147::-;;;;;;;;;;;;177:42;8429:147;;115490:206;;;;;;:::i;:::-;;:::i;100017:38::-;;;;;;;;;;;;;;;;104215:125;;;;;;;;;;-1:-1:-1;104310:18:0;;104215:125;;112118:230;;;;;;;;;;-1:-1:-1;112118:230:0;;;;;:::i;:::-;;:::i;76229:588::-;;;;;;;;;;-1:-1:-1;76229:588:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;35197:160::-;;;;;;;;;;-1:-1:-1;35197:160:0;;;;;:::i;:::-;;:::i;113969:515::-;;;;;;;;;;-1:-1:-1;113969:515:0;;;;;:::i;:::-;;:::i;30291:245::-;;;;;;;;;;-1:-1:-1;30291:245:0;;;;;:::i;:::-;;:::i;104003:120::-;;;;;;;;;;-1:-1:-1;104093:11:0;:18;104003:120;;98341:111;;;;;;;;;;;;;:::i;106727:1422::-;;;;;;;;;;-1:-1:-1;106727:1422:0;;;;;:::i;:::-;;:::i;80505:984::-;;;;;;;;;;-1:-1:-1;80505:984:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;97621:95::-;;;;;;;;;;;;;:::i;102200:1718::-;;;;;;;;;;-1:-1:-1;102200:1718:0;;;;;:::i;:::-;;:::i;33844:112::-;;;;;;;;;;;;;:::i;105700:214::-;;;;;;;;;;-1:-1:-1;105700:214:0;;;;;:::i;:::-;;:::i;77261:2749::-;;;;;;;;;;-1:-1:-1;77261:2749:0;;;;;:::i;:::-;;:::i;114849:203::-;;;;;;;;;;-1:-1:-1;114849:203:0;;;;;:::i;:::-;;:::i;106038:565::-;;;;;;;;;;-1:-1:-1;106038:565:0;;;;;:::i;:::-;;:::i;:::-;;;;9964:13:1;;-1:-1:-1;;;;;9960:38:1;9942:57;;10046:4;10034:17;;;10028:24;10071:10;10119:21;;;10097:20;;;10090:51;;;;10185:17;;;10179:24;10157:20;;;10150:54;;;;10264:4;10252:17;;;10246:24;10272:8;10242:39;10220:20;;;10213:69;10331:4;10319:17;;;10313:24;-1:-1:-1;;;;;10412:23:1;;;10390:20;;;10383:53;;;;10496:4;10484:17;;;10478:24;10474:33;10452:20;;;10445:63;;;;10545:15;;;10539:3;10524:19;;10517:44;10592:3;10577:19;;10570:35;9929:3;9914:19;106038:565:0;9679:932:1;112974:121:0;;;;;;;;;;-1:-1:-1;112974:121:0;;;;;:::i;:::-;;:::i;111377:309::-;;;;;;:::i;:::-;;:::i;112692:186::-;;;;;;;;;;;;;:::i;115712:292::-;;;;;;:::i;:::-;;:::i;75578:468::-;;;;;;;;;;-1:-1:-1;75578:468:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;113204:653::-;;;;;;;;;;-1:-1:-1;113204:653:0;;;;;:::i;:::-;;:::i;41868:172::-;;;;;;;;;;-1:-1:-1;41868:172:0;;;;;:::i;:::-;-1:-1:-1;;;;;41993:25:0;;;41965:4;41993:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;41868:172;105034:125;;;;;;;;;;-1:-1:-1;105129:18:0;;105034:125;;98631:213;;;;;;;;;;-1:-1:-1;98631:213:0;;;;;:::i;:::-;;:::i;104495:389::-;;;;;;;;;;-1:-1:-1;104495:389:0;;;;;:::i;:::-;;:::i;99967:39::-;;;;;;;;;;;;;;;;32666:675;32751:4;-1:-1:-1;;;;;;;;;33099:25:0;;;;:106;;-1:-1:-1;;;;;;;;;;33180:25:0;;;33099:106;:187;;;-1:-1:-1;;;;;;;;;;33261:25:0;;;33099:187;33075:211;32666:675;-1:-1:-1;;32666:675:0:o;33640:108::-;33694:13;33731:5;33724:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33640:108;:::o;40811:234::-;40887:7;40916:16;40924:7;40916;:16::i;:::-;40911:64;;40941:34;;-1:-1:-1;;;40941:34:0;;;;;;;;;;;40911:64;-1:-1:-1;41003:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;41003:30:0;;40811:234::o;115068:192::-;115191:8;10363:30;10384:8;10363:20;:30::i;:::-;115216:32:::1;115230:8;115240:7;115216:13;:32::i;:::-;115068:192:::0;;;:::o;112453:154::-;97479:13;:11;:13::i;:::-;112518:17:::1;:24:::0;;-1:-1:-1;;112518:24:0::1;112538:4;112518:24;::::0;;112562:33:::1;::::0;::::1;::::0;::::1;::::0;112579:15:::1;::::0;112562:33:::1;:::i;:::-;;;;;;;;112453:154::o:0;108375:183::-;94532:21;:19;:21::i;:::-;108509:37:::1;108523:3;108528:10;108540:5;;108509:13;:37::i;:::-;94584:20:::0;93902:1;95160:7;:22;94965:229;115276:198;115404:4;-1:-1:-1;;;;;10049:18:0;;10057:10;10049:18;10045:91;;10088:32;10109:10;10088:20;:32::i;:::-;115425:37:::1;115444:4;115450:2;115454:7;115425:18;:37::i;:::-;115276:198:::0;;;;:::o;105244:345::-;97479:13;:11;:13::i;:::-;105394:18:::1;;105374:17;:38;105370:95;;;105438:27;;-1:-1:-1::0;;;105438:27:0::1;;;;;;;;;;;105370:95;105480:18;:38:::0;;;105538:39:::1;::::0;3373:25:1;;;105538:39:0::1;::::0;3361:2:1;3346:18;105538:39:0::1;;;;;;;;105244:345:::0;:::o;111771:257::-;97479:13;:11;:13::i;:::-;111896:33:::1;::::0;111841:21:::1;::::0;111825:13:::1;::::0;111896:10:::1;::::0;111841:21;;111825:13;111896:33;111825:13;111896:33;111841:21;111896:10;:33:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111877:52;;;111949:7;111944:37;;111965:16;;-1:-1:-1::0;;;111965:16:0::1;;;;;;;;;;;111944:37;112001:15;::::0;3373:25:1;;;112001:15:0::1;::::0;3361:2:1;3346:18;112001:15:0::1;;;;;;;;111810:218;;111771:257::o:0;115490:206::-;115622:4;-1:-1:-1;;;;;10049:18:0;;10057:10;10049:18;10045:91;;10088:32;10109:10;10088:20;:32::i;:::-;115643:41:::1;115666:4;115672:2;115676:7;115643:22;:41::i;112118:230::-:0;97479:13;:11;:13::i;:::-;112201:17:::1;::::0;::::1;;112197:60;;;112227:30;;-1:-1:-1::0;;;112227:30:0::1;;;;;;;;;;;112197:60;112272:15;:25;112290:7:::0;;112272:15;:25:::1;:::i;:::-;;112317:19;112328:7;;112317:19;;;;;;;:::i;76229:588::-:0;76393:23;76496:8;76471:22;76496:8;-1:-1:-1;;;;;76567:36:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;76530:73;;76627:9;76622:133;76643:14;76638:1;:19;76622:133;;76703:32;76723:8;;76732:1;76723:11;;;;;;;:::i;:::-;;;;;;;76703:19;:32::i;:::-;76687:10;76698:1;76687:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;76659:3;;76622:133;;;-1:-1:-1;76780:10:0;76229:588;-1:-1:-1;;;;76229:588:0:o;35197:160::-;35269:7;35316:27;35335:7;35316:18;:27::i;113969:515::-;114106:7;;114139:298;114163:11;:18;114159:22;;114139:298;;;114246:11;114258:1;114246:14;;;;;;;;:::i;:::-;;;;;;;;;:35;:14;;;;;:35;;-1:-1:-1;;;;;114246:35:0;;;;;;114233:48;;;;;;;:118;;;114318:11;114330:1;114318:14;;;;;;;;:::i;:::-;;;;;;;;;:33;:14;;;;;:33;;-1:-1:-1;;;;;;;;114318:33:0;;;;;114306:45;;;;114233:118;114207:215;;;114401:1;113969:515;-1:-1:-1;;113969:515:0:o;114207:215::-;114183:3;;;;:::i;:::-;;;;114139:298;;;;114458:14;;-1:-1:-1;;;114458:14:0;;;;;;;;;;;30291:245;30363:7;-1:-1:-1;;;;;30391:19:0;;30387:60;;30419:28;;-1:-1:-1;;;30419:28:0;;;;;;;;;;;30387:60;-1:-1:-1;;;;;;30469:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;30469:55:0;;30291:245::o;98341:111::-;97479:13;:11;:13::i;:::-;98410:30:::1;98437:1;98410:18;:30::i;:::-;98341:111::o:0;106727:1422::-;97479:13;:11;:13::i;:::-;107044:11:::1;:18:::0;107035:27;::::1;107031:54;;107071:14;;-1:-1:-1::0;;;107071:14:0::1;;;;;;;;;;;107031:54;107113:1;107104:5;:10;107100:257;;107205:11;107217:9;107225:1;107217:5:::0;:9:::1;:::i;:::-;107205:22;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;:41:::1;:22;::::0;;::::1;;:41;::::0;-1:-1:-1;;;;;;;;107205:41:0;;::::1;::::0;::::1;107161:85:::0;;::::1;;107135:207;;;107296:26;;-1:-1:-1::0;;;107296:26:0::1;;;;;;;;;;;107135:207;107371:123;107422:20;107461:18;107371:32;:123::i;:::-;107535:4;107509:11;107521:5;107509:18;;;;;;;;:::i;:::-;;;;;;;;;;;:23;;;:30;;;;;-1:-1:-1::0;;;;;107509:30:0::1;;;;;-1:-1:-1::0;;;;;107509:30:0::1;;;;;;107587:11;107554;107566:5;107554:18;;;;;;;;:::i;:::-;;;;;;;;;;;:30;;;:44;;;;;;;;;;;;;;;;;;107645:10;107613:11;107625:5;107613:18;;;;;;;;:::i;:::-;;;;;;;;;;;:29;;:42;;;;107706:14;107670:11;107682:5;107670:18;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;;:50;;;;;;;;;;;;;;;;;;107777:20;107735:11;107747:5;107735:18;;;;;;;;:::i;:::-;;;;;;;;;;;:39;;;:62;;;;;-1:-1:-1::0;;;;;107735:62:0::1;;;;;-1:-1:-1::0;;;;;107735:62:0::1;;;;;;107852:18;107812:11;107824:5;107812:18;;;;;;;;:::i;:::-;;;;;;;;;;;:37;;;:58;;;;;-1:-1:-1::0;;;;;107812:58:0::1;;;;;-1:-1:-1::0;;;;;107812:58:0::1;;;;;;-1:-1:-1::0;;;;;;;;;;;107926:5:0::1;107950:4;107973:11;108003:10;108032:14;108065:20;108104:18;107896:241;;;;;;;;;;;;:::i;:::-;;;;;;;;106727:1422:::0;;;;;;;:::o;80505:984::-;80583:16;80645:19;80683:25;80727:22;80752:16;80762:5;80752:9;:16::i;:::-;80727:41;;80787:25;80829:14;-1:-1:-1;;;;;80815:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80815:29:0;;80787:57;;80863:31;;:::i;:::-;80918:9;80913:516;80962:14;80947:11;:29;80913:516;;81018:15;81031:1;81018:12;:15::i;:::-;81006:27;;81060:9;:16;;;81105:8;81056:81;81163:14;;-1:-1:-1;;;;;81163:28:0;;81159:119;;81240:14;;;-1:-1:-1;81159:119:0;81325:5;-1:-1:-1;;;;;81304:26:0;:17;-1:-1:-1;;;;;81304:26:0;;81300:110;;81385:1;81359:8;81368:13;;;;;;81359:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;81300:110;80978:3;;80913:516;;;-1:-1:-1;81454:8:0;;80505:984;-1:-1:-1;;;;;;80505:984:0:o;97621:95::-;97698:6;;-1:-1:-1;;;;;97698:6:0;;97621:95::o;102200:1718::-;97479:13;:11;:13::i;:::-;102312:11:::1;:18:::0;102289:20:::1;102345:95;102369:12;102365:1;:16;102345:95;;;102407:11;:17;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;::::1;-1:-1:-1::0;;102407:17:0;;;;;::::1;;::::0;;-1:-1:-1;;;;;;102407:17:0;;;::::1;::::0;::::1;::::0;;;;::::1;;::::0;;-1:-1:-1;;;;;;102407:17:0;;;;;102383:3;::::1;::::0;::::1;:::i;:::-;;;;102345:95;;;;102471:9;102466:1441;102486:20:::0;;::::1;102466:1441;;;102541:1;102536;:6;102532:288;;102658:9:::0;;102668:5:::1;102672:1;102668::::0;:5:::1;:::i;:::-;102658:16;;;;;;;:::i;:::-;;;;;;:35;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;102597:96:0::1;:9;;102607:1;102597:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;102597:96:0::1;;102567:234;;;102751:26;;-1:-1:-1::0;;;102751:26:0::1;;;;;;;;;;;102567:234;102838:161;102893:9;;102903:1;102893:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;102949:9;;102959:1;102949:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;102838:32;:161::i;:::-;103018:11;103057:444;;;;;;;;103104:9;;103114:1;103104:12;;;;;;;:::i;:::-;:17;::::0;::::1;:12;::::0;;::::1;;:17:::0;;::::1;::::0;-1:-1:-1;103104:17:0::1;:::i;:::-;-1:-1:-1::0;;;;;103057:444:0::1;;;;;103161:9;;103171:1;103161:12;;;;;;;:::i;:::-;;;;;;:24;;;;;;;;;;:::i;:::-;103057:444;;;;;;103224:9;;103234:1;103224:12;;;;;;;:::i;:::-;;;;;;:23;;;103057:444;;;;103290:9;;103300:1;103290:12;;;;;;;:::i;:::-;;;;;;:27;;;;;;;;;;:::i;:::-;103057:444;;;;;;103366:9;;103376:1;103366:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;103057:444:0::1;;;;;103446:9;;103456:1;103446:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;103057:444:0;;::::1;::::0;;;103018:502;;::::1;::::0;;::::1;::::0;;-1:-1:-1;103018:502:0;;;::::1;::::0;;;;;;::::1;::::0;;::::1;;::::0;;;;::::1;::::0;::::1;;-1:-1:-1::0;;;103018:502:0::1;-1:-1:-1::0;;;;;;103018:502:0;;;-1:-1:-1;;;;;103018:502:0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;103018:502:0::1;-1:-1:-1::0;;;;;;;;103018:502:0;;;::::1;::::0;::::1;-1:-1:-1::0;;;;;;103018:502:0;;;::::1;::::0;;::::1;::::0;;;;;;;::::1;::::0;;;::::1;;::::0;;-1:-1:-1;;;;;;;;;;;103578:1:0;103602:9;;103578:1;103602:12;;::::1;;;;;:::i;:::-;:17;::::0;::::1;:12;::::0;;::::1;;:17:::0;;::::1;::::0;-1:-1:-1;103602:17:0::1;:::i;:::-;103642:9;;103652:1;103642:12;;;;;;;:::i;:::-;;;;;;:24;;;;;;;;;;:::i;:::-;103689:9;;103699:1;103689:12;;;;;;;:::i;:::-;;;;;;:23;;;103735:9;;103745:1;103735:12;;;;;;;:::i;:::-;;;;;;:27;;;;;;;;;;:::i;:::-;103785:9;;103795:1;103785:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;103841:9;;103851:1;103841:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;103544:347;;;;;;;;;;;;:::i;:::-;;;;;;;;102508:3:::0;::::1;::::0;::::1;:::i;:::-;;;;102466:1441;;33844:112:::0;33900:13;33937:7;33930:14;;;;;:::i;105700:214::-;105846:7;105886:16;105900:1;105886:13;:16::i;77261:2749::-;77420:16;77495:4;77486:5;:13;77482:45;;77508:19;;-1:-1:-1;;;77508:19:0;;;;;;;;;;;77482:45;77546:19;77584:17;77604:14;28681:7;28712:13;;28626:111;77604:14;77584:34;-1:-1:-1;77879:9:0;77872:4;:16;77868:81;;;77920:9;77913:16;;77868:81;77967:25;77995:16;78005:5;77995:9;:16::i;:::-;77967:44;;78201:4;78193:5;:12;78189:306;;;78252:12;;;78291:31;;;78287:119;;;78371:11;78351:31;;78287:119;78207:218;78189:306;;;-1:-1:-1;78474:1:0;78189:306;78513:25;78555:17;-1:-1:-1;;;;;78541:32:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78541:32:0;;78513:60;;78596:17;78617:1;78596:22;78592:86;;78650:8;-1:-1:-1;78643:15:0;;-1:-1:-1;;;78643:15:0;78592:86;78834:31;78868:26;78888:5;78868:19;:26::i;:::-;78834:60;;78913:25;79170:9;:16;;;79165:100;;-1:-1:-1;79231:14:0;;79165:100;79300:5;79283:522;79312:4;79307:1;:9;;:45;;;;;79335:17;79320:11;:32;;79307:45;79283:522;;;79394:15;79407:1;79394:12;:15::i;:::-;79382:27;;79436:9;:16;;;79481:8;79432:81;79539:14;;-1:-1:-1;;;;;79539:28:0;;79535:119;;79616:14;;;-1:-1:-1;79535:119:0;79701:5;-1:-1:-1;;;;;79680:26:0;:17;-1:-1:-1;;;;;79680:26:0;;79676:110;;79761:1;79735:8;79744:13;;;;;;79735:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;79676:110;79354:3;;79283:522;;;-1:-1:-1;;;79902:29:0;;;-1:-1:-1;79909:8:0;;-1:-1:-1;;77261:2749:0;;;;;;:::o;114849:203::-;114972:8;10363:30;10384:8;10363:20;:30::i;:::-;114997:43:::1;115021:8;115031;114997:23;:43::i;106038:565::-:0;106177:20;;:::i;:::-;106301:11;:18;106216:6;;;;106292:27;;106288:90;;106340:22;;-1:-1:-1;;;106340:22:0;;18855:2:1;106340:22:0;;;18837:21:1;18894:2;18874:18;;;18867:30;-1:-1:-1;;;18913:18:1;;;18906:42;18965:18;;106340:22:0;;;;;;;;106288:90;106392:19;106414:34;;;:27;:34;;;;;;;;106449:10;106414:46;;;;;;;;106497:25;;;:18;:25;;;;;;;106545:11;:18;;106414:46;;;;;106442:5;;106545:18;;;;;;:::i;:::-;;;;;;;;;;106537:54;;;;;;;;106545:18;;;;;;;;106537:54;;-1:-1:-1;;;;;106537:54:0;;;;-1:-1:-1;;;106537:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;106537:54:0;;;;;;;-1:-1:-1;;;106537:54:0;;;;;;;;;106565:12;;-1:-1:-1;106565:12:0;-1:-1:-1;106038:565:0;-1:-1:-1;;106038:565:0:o;112974:121::-;97479:13;:11;:13::i;:::-;113059:15:::1;:24;113077:6:::0;;113059:15;:24:::1;:::i;111377:309::-:0;97479:13;:11;:13::i;:::-;111509:3:::1;101105:142;;101178:18;;101172:3;101156:13;29265:12:::0;;29036:7;29249:13;:28;;28975:347;101156:13:::1;:19;;;;:::i;:::-;:40;101152:67;;;101205:14;;-1:-1:-1::0;;;101205:14:0::1;;;;;;;;;;;101152:67;111564:3:::2;111554:13;;:7;;:13;;;;:::i;:::-;111542:9;:25;111538:54;;;111576:16;;-1:-1:-1::0;;;111576:16:0::2;;;;;;;;;;;111538:54;111607:18;111617:2;111621:3;111607:18;;:9;:18::i;:::-;111648:5;::::0;111640:34:::2;::::0;-1:-1:-1;;;;;111648:5:0;;::::2;::::0;111664:9:::2;111640:34:::0;::::2;;;::::0;111648:5:::2;111640:34:::0;111648:5;111640:34;111664:9;111648:5;111640:34;::::2;;;;;;;;;;;;;::::0;::::2;;;;112692:186:::0;112805:13;112851:15;112844:22;;;;;:::i;115712:292::-;115915:4;-1:-1:-1;;;;;10049:18:0;;10057:10;10049:18;10045:91;;10088:32;10109:10;10088:20;:32::i;:::-;115945:47:::1;115968:4;115974:2;115978:7;115987:4;115945:22;:47::i;:::-;115712:292:::0;;;;;:::o;75578:468::-;75662:21;;:::i;:::-;75700:31;;:::i;:::-;28681:7;28712:13;75779:7;:25;75746:111;;75832:9;75578:468;-1:-1:-1;;75578:468:0:o;75746:111::-;75883:21;75896:7;75883:12;:21::i;:::-;75871:33;;75923:9;:16;;;75919:73;;;75967:9;75578:468;-1:-1:-1;;75578:468:0:o;75919:73::-;76013:21;76026:7;76013:12;:21::i;113204:653::-;113340:13;113384:16;113392:7;113384;:16::i;:::-;113379:59;;113409:29;;-1:-1:-1;;;113409:29:0;;;;;;;;;;;113379:59;113459:21;113483:15;113459:39;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113543:7;113537:21;113562:1;113537:26;:308;;;;;;;;;;;;;;;;;113667:7;113705:18;113715:7;113705:9;:18::i;:::-;113754:15;113620:176;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;113513:332;113204:653;-1:-1:-1;;;113204:653:0:o;98631:213::-;97479:13;:11;:13::i;:::-;-1:-1:-1;;;;;98724:22:0;::::1;98716:73;;;::::0;-1:-1:-1;;;98716:73:0;;20737:2:1;98716:73:0::1;::::0;::::1;20719:21:1::0;20776:2;20756:18;;;20749:30;20815:34;20795:18;;;20788:62;-1:-1:-1;;;20866:18:1;;;20859:36;20912:19;;98716:73:0::1;20535:402:1::0;98716:73:0::1;98804:28;98823:8;98804:18;:28::i;:::-;98631:213:::0;:::o;104495:389::-;97479:13;:11;:13::i;:::-;104666:18:::1;;104646:17;:38;104642:119;;;104712:33;;-1:-1:-1::0;;;104712:33:0::1;;;;;;;;;;;104642:119;104775:18;:38:::0;;;104833:39:::1;::::0;3373:25:1;;;104833:39:0::1;::::0;3361:2:1;3346:18;104833:39:0::1;3227:177:1::0;42334:302:0;42399:4;42501:13;;42491:7;:23;42444:161;;;;-1:-1:-1;;42556:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;42556:44:0;:49;;42334:302::o;10534:683::-;177:42;10733:45;:49;10729:477;;11044:67;;-1:-1:-1;;;11044:67:0;;11095:4;11044:67;;;21154:34:1;-1:-1:-1;;;;;21224:15:1;;21204:18;;;21197:43;177:42:0;;11044;;21089:18:1;;11044:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11039:152;;11162:8;11143:28;;-1:-1:-1;;;11143:28:0;;;;;;;;:::i;40168:448::-;40261:13;40277:16;40285:7;40277;:16::i;:::-;40261:32;-1:-1:-1;66989:10:0;-1:-1:-1;;;;;40318:28:0;;;40314:187;;40370:44;40387:5;66989:10;41868:172;:::i;40370:44::-;40365:136;;40446:35;;-1:-1:-1;;;40446:35:0;;;;;;;;;;;40365:136;40521:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;40521:35:0;-1:-1:-1;;;;;40521:35:0;;;;;;;;;40576:28;;40521:24;;40576:28;;;;;;;40246:370;40168:448;;:::o;97814:140::-;66989:10;97882:7;:5;:7::i;:::-;-1:-1:-1;;;;;97882:23:0;;97874:68;;;;-1:-1:-1;;;97874:68:0;;21703:2:1;97874:68:0;;;21685:21:1;;;21722:18;;;21715:30;21781:34;21761:18;;;21754:62;21833:18;;97874:68:0;21501:356:1;94632:317:0;93950:1;94774:7;;:19;94766:63;;;;-1:-1:-1;;;94766:63:0;;22064:2:1;94766:63:0;;;22046:21:1;22103:2;22083:18;;;22076:30;22142:33;22122:18;;;22115:61;22193:18;;94766:63:0;21862:355:1;94766:63:0;93950:1;94919:7;:18;94632:317::o;108650:2452::-;108792:3;101105:142;;101178:18;;101172:3;101156:13;29265:12;;29036:7;29249:13;:28;;28975:347;101156:13;:19;;;;:::i;:::-;:40;101152:67;;;101205:14;;-1:-1:-1;;;101205:14:0;;;;;;;;;;;101152:67;108843:15:::1;108880:26;;:::i;:::-;108927:19;108949:43;108977:14;108949:27;:43::i;:::-;108927:65;;109021:11;109033;109021:24;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;109013:32:::1;::::0;;::::1;::::0;::::1;::::0;;109021:24:::1;::::0;;;::::1;::::0;;::::1;109013:32:::0;;-1:-1:-1;;;;;109013:32:0;::::1;::::0;;;-1:-1:-1;;;109013:32:0;;::::1;;;::::0;;::::1;::::0;;;;;;::::1;::::0;;;;;;;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;;;::::1;-1:-1:-1::0;;;;;109013:32:0;;::::1;::::0;;;;-1:-1:-1;;;109013:32:0;;::::1;;::::0;;;;109110:9:::1;::::0;109013:32;;-1:-1:-1;;109094:230:0::1;;;109171:7;::::0;109158:10;;109157:28:::1;::::0;::::1;::::0;109158:20:::1;::::0;-1:-1:-1;;;;;109158:20:0::1;;:::i;:::-;109157:28;;;;:::i;:::-;109145:9;:40;109141:69;;;109194:16;;-1:-1:-1::0;;;109194:16:0::1;;;;;;;;;;;109141:69;109094:230;;;109267:10:::0;;:16:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;;;109255:28:0::1;:9;:28;109251:57;;;109292:16;;-1:-1:-1::0;;;109292:16:0::1;;;;;;;;;;;109251:57;109397:20;::::0;::::1;::::0;:24:::1;;::::0;109393:180:::1;;109486:20;::::0;::::1;::::0;109446:31:::1;::::0;;;:18:::1;:31;::::0;;;;;:60:::1;::::0;;::::1;::::0;:37:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;:60;109442:115;;;109536:21;;-1:-1:-1::0;;;109536:21:0::1;;;;;;;;;;;109442:115;109653:18;::::0;:22;109649:168:::1;;109726:18;;109720:3;109700:23;;:17;109714:2;109700:13;:17::i;:::-;:23;;;;:::i;:::-;:44;109696:105;;;109774:27;;-1:-1:-1::0;;;109774:27:0::1;;;;;;;;;;;109696:105;109936:17;::::0;::::1;::::0;:21:::1;;::::0;109932:232:::1;;110078:17;::::0;;::::1;::::0;110004:40:::1;::::0;;;:27:::1;:40:::0;;;;;;-1:-1:-1;;;;;110004:44:0;::::1;::::0;;;;;;;;;;:91:::1;::::0;;::::1;::::0;:50:::1;::::0;110051:3;;110004:44:::1;:50;:::i;:::-;:91;;;109978:170;;;110122:26;;-1:-1:-1::0;;;110122:26:0::1;;;;;;;;;;;109978:170;110286:16;::::0;::::1;::::0;:21;110282:286:::1;;110495:5;:16;;;110354:137;110405:5;;110354:137;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;110447:20:0::1;::::0;-1:-1:-1;;;;;;22904:2:1;22875:15;;;22871:45;110447:20:0::1;::::0;::::1;22859:58:1::0;22933:12;;;-1:-1:-1;110447:20:0::1;::::0;-1:-1:-1;22730:221:1;110447:20:0::1;;;;;;;;;;;;;110437:31;;;;;;110354:24;:137::i;:::-;:157;110328:224;;110538:14;;-1:-1:-1::0;;;110538:14:0::1;;;;;;;;;;;110328:224;110588:40;::::0;;;:27:::1;:40;::::0;;;;;;;-1:-1:-1;;;;;110588:44:0;::::1;::::0;;;;;;;:51;;110636:3;;110588:40;:51:::1;::::0;110636:3;;110588:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;110689:3;110654:38;;:18;:31;110673:11;110654:31;;;;;;;;;;;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;110707:18:0::1;::::0;-1:-1:-1;110717:2:0;110707:18:::1;::::0;::::1;:9;:18::i;:::-;110762:9;::::0;110749:10;;-1:-1:-1;;;;;110749:22:0::1;;110746:345;;;110801:5;::::0;110817:7:::1;::::0;-1:-1:-1;;;;;110801:5:0;;::::1;::::0;110793:38:::1;::::0;110817:13:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;110793:38;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;110858:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;110850:25:0::1;:54;110899:3;110889:13;;:7;;:13;;;;:::i;:::-;110876:27;::::0;:9:::1;:27;:::i;:::-;110850:54;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;110746:345;;;110953:5;::::0;-1:-1:-1;;;;;110953:5:0::1;110945:47;110969:22;::::0;::::1;110970:14;110982:2;110970:9;:14;:::i;:::-;110969:22;;;;:::i;:::-;110945:47;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;111019:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;111011:25:0::1;:64;111050:23;::::0;::::1;111051:14;111063:2;111051:9;:14;:::i;:::-;111050:23;;;;:::i;:::-;111037:37;::::0;:9:::1;:37;:::i;:::-;111011:64;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;110746:345;108797:2305;;;108650:2452:::0;;;;;:::o;44834:3069::-;44996:27;45026;45045:7;45026:18;:27::i;:::-;44996:57;;45119:4;-1:-1:-1;;;;;45078:45:0;45094:19;-1:-1:-1;;;;;45078:45:0;;45074:86;;45132:28;;-1:-1:-1;;;45132:28:0;;;;;;;;;;;45074:86;45182:27;43842:24;;;:15;:24;;;;;44086:26;;66989:10;43419:30;;;-1:-1:-1;;;;;43096:28:0;;43397:20;;;43394:56;45380:184;;45477:43;45494:4;66989:10;41868:172;:::i;45477:43::-;45472:92;;45529:35;;-1:-1:-1;;;45529:35:0;;;;;;;;;;;45472:92;-1:-1:-1;;;;;45589:16:0;;45585:52;;45614:23;;-1:-1:-1;;;45614:23:0;;;;;;;;;;;45585:52;45810:15;45807:172;;;45958:1;45937:19;45930:30;45807:172;-1:-1:-1;;;;;46391:24:0;;;;;;;:18;:24;;;;;;46389:26;;-1:-1:-1;;46389:26:0;;;46464:22;;;;;;46462:24;;-1:-1:-1;46462:24:0;;;46814:158;46464:22;-1:-1:-1;;;46814:18:0;:158::i;:::-;46785:26;;;;:17;:26;;;;;:187;;;;-1:-1:-1;;;47104:47:0;;:52;;47100:667;;47213:1;47203:11;;47181:19;47344:30;;;:17;:30;;;;;;:35;;47340:408;;47490:13;;47475:11;:28;47471:254;;47645:30;;;;:17;:30;;;;;:52;;;47471:254;47158:609;47100:667;47826:7;47822:2;-1:-1:-1;;;;;47807:27:0;47816:4;-1:-1:-1;;;;;47807:27:0;-1:-1:-1;;;;;;;;;;;47807:27:0;;;;;;;;;47849:42;44981:2922;;;44834:3069;;;:::o;48019:217::-;48185:39;48202:4;48208:2;48212:7;48185:39;;;;;;;;;;;;:16;:39::i;36476:1379::-;36543:7;36582;36700:13;;36693:4;:20;36689:1087;;;36742:14;36759:23;;;:17;:23;;;;;;;-1:-1:-1;;;36856:24:0;;:29;;36852:901;;37561:121;37568:6;37578:1;37568:11;37561:121;;-1:-1:-1;;;37643:6:0;37625:25;;;;:17;:25;;;;;;37561:121;;36852:901;36715:1061;36689:1087;37812:31;;-1:-1:-1;;;37812:31:0;;;;;;;;;;;99028:207;99125:6;;;-1:-1:-1;;;;;99146:17:0;;;-1:-1:-1;;;;;;99146:17:0;;;;;;;99183:40;;99125:6;;;99146:17;99125:6;;99183:40;;99106:16;;99183:40;99091:144;99028:207;:::o;114625:198::-;114770:3;-1:-1:-1;;;;;114761:12:0;:5;-1:-1:-1;;;;;114761:12:0;;114757:54;;114782:29;;-1:-1:-1;;;114782:29:0;;;;;;;;;;;114757:54;114625:198;;:::o;35860:169::-;35928:21;;:::i;:::-;35992:24;;;;:17;:24;;;;;;35973:44;;:18;:44::i;30638:186::-;-1:-1:-1;;;;;30731:25:0;30699:7;30731:25;;;:18;:25;;23976:2;30731:25;;;;;:50;;-1:-1:-1;;;;;30730:82:0;;30638:186::o;41437:246::-;66989:10;41536:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;41536:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;41536:60:0;;;;;;;;;;41616:55;;540:41:1;;;41536:49:0;;66989:10;41616:55;;513:18:1;41616:55:0;;;;;;;41437:246;;:::o;60114:120::-;60195:27;60205:2;60209:8;60195:27;;;;;;;;;;;;:9;:27::i;48902:451::-;49101:31;49114:4;49120:2;49124:7;49101:12;:31::i;:::-;-1:-1:-1;;;;;49151:14:0;;;:19;49147:195;;49194:56;49225:4;49231:2;49235:7;49244:5;49194:30;:56::i;:::-;49189:153;;49282:40;;-1:-1:-1;;;49282:40:0;;;;;;;;;;;35570:174;35640:21;;:::i;:::-;35685:47;35704:27;35723:7;35704:18;:27::i;:::-;35685:18;:47::i;67133:1893::-;67198:17;67656:4;67649;67643:11;67639:22;67756:1;67750:4;67743:15;67839:4;67836:1;67832:12;67825:19;;;67929:1;67924:3;67917:14;68045:3;68304:5;68286:464;68356:1;68351:3;68347:11;68340:18;;68539:2;68533:4;68529:13;68525:2;68521:22;68516:3;68508:36;68641:2;68631:13;;68706:25;68286:464;68706:25;-1:-1:-1;68788:13:0;;;-1:-1:-1;;68911:14:0;;;68981:19;;;68911:14;67133:1893;-1:-1:-1;67133:1893:0:o;83831:320::-;83914:7;83961:4;83914:7;83980:126;84004:5;:12;84000:1;:16;83980:126;;;84057:33;84067:12;84081:5;84087:1;84081:8;;;;;;;;:::i;:::-;;;;;;;84057:9;:33::i;:::-;84042:48;-1:-1:-1;84018:3:0;;;;:::i;:::-;;;;83980:126;;;-1:-1:-1;84127:12:0;83831:320;-1:-1:-1;;;83831:320:0:o;38463:478::-;38894:11;38869:23;38865:41;38862:52;-1:-1:-1;;;;;38712:28:0;;;;38852:63;;38463:478::o;37974:386::-;38040:31;;:::i;:::-;-1:-1:-1;;;;;38088:41:0;;;;-1:-1:-1;;;;;24545:3:0;38178:33;;;38144:68;:24;;;:68;-1:-1:-1;;;38246:24:0;;:29;;38227:16;;;:48;25114:3;38319:28;;;;38290:19;;;:58;38088:9;37974:386::o;59241:769::-;59392:19;59398:2;59402:8;59392:5;:19::i;:::-;-1:-1:-1;;;;;59465:14:0;;;:19;59461:523;;59509:11;59523:13;59575:14;;;59612:249;59647:62;59686:1;59690:2;59694:7;;;;;;59703:5;59647:30;:62::i;:::-;59642:175;;59749:40;;-1:-1:-1;;;59749:40:0;;;;;;;;;;;59642:175;59856:3;59848:5;:11;59612:249;;59951:3;59934:13;;:20;59930:34;;59956:8;;;51669:792;51877:88;;-1:-1:-1;;;51877:88:0;;51852:4;;-1:-1:-1;;;;;51877:45:0;;;;;:88;;66989:10;;51944:4;;51950:7;;51959:5;;51877:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51877:88:0;;;;;;;;-1:-1:-1;;51877:88:0;;;;;;;;;;;;:::i;:::-;;;51873:577;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52180:6;:13;52197:1;52180:18;52176:259;;52230:40;;-1:-1:-1;;;52230:40:0;;;;;;;;;;;52176:259;52385:6;52379:13;52370:6;52366:2;52362:15;52355:38;51873:577;-1:-1:-1;;;;;;52048:64:0;-1:-1:-1;;;52048:64:0;;-1:-1:-1;51669:792:0;;;;;;:::o;91491:157::-;91554:7;91589:1;91585;:5;:51;;91732:13;91838:15;;;91878:4;91871:15;;;91929:4;91913:21;;91585:51;;;-1:-1:-1;91732:13:0;91838:15;;;91878:4;91871:15;91929:4;91913:21;;;91491:157::o;52987:3222::-;53064:20;53087:13;;;53119;;;53115:44;;53141:18;;-1:-1:-1;;;53141:18:0;;;;;;;;;;;53115:44;-1:-1:-1;;;;;53699:22:0;;;;;;:18;:22;;23976:2;53699:22;;:71;;-1:-1:-1;;;;;53725:45:0;;53699:71;;;54075:151;53699:22;-1:-1:-1;39369:15:0;;39343:24;39339:46;54075:18;:151::i;:::-;54041:31;;;;:17;:31;;;;;:185;;;;-1:-1:-1;;;;;54860:25:0;;;54300:23;;;;54059:12;;54860:25;;-1:-1:-1;;;;;;;;;;;54041:31:0;;54958:363;55671:1;55657:12;55653:20;55607:374;55716:3;55707:7;55704:16;55607:374;;55950:7;55940:8;55937:1;-1:-1:-1;;;;;;;;;;;55907:1:0;55904;55899:59;55773:1;55760:15;55607:374;;;55611:85;56022:8;56034:1;56022:13;56018:45;;56044:19;;-1:-1:-1;;;56044:19:0;;;;;;;;;;;56018:45;56088:13;:19;-1:-1:-1;115068:192:0;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1528:203::-;-1:-1:-1;;;;;1692:32:1;;;;1674:51;;1662:2;1647:18;;1528:203::o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2173:163::-;2240:20;;2300:10;2289:22;;2279:33;;2269:61;;2326:1;2323;2316:12;2341:367;2404:8;2414:6;2468:3;2461:4;2453:6;2449:17;2445:27;2435:55;;2486:1;2483;2476:12;2435:55;-1:-1:-1;2509:20:1;;-1:-1:-1;;;;;2541:30:1;;2538:50;;;2584:1;2581;2574:12;2538:50;2621:4;2613:6;2609:17;2597:29;;2681:3;2674:4;2664:6;2661:1;2657:14;2649:6;2645:27;2641:38;2638:47;2635:67;;;2698:1;2695;2688:12;2635:67;2341:367;;;;;:::o;2713:509::-;2807:6;2815;2823;2876:2;2864:9;2855:7;2851:23;2847:32;2844:52;;;2892:1;2889;2882:12;2844:52;2915:28;2933:9;2915:28;:::i;:::-;2905:38;-1:-1:-1;2994:2:1;2979:18;;2966:32;-1:-1:-1;;;;;3010:30:1;;3007:50;;;3053:1;3050;3043:12;3007:50;3092:70;3154:7;3145:6;3134:9;3130:22;3092:70;:::i;:::-;2713:509;;3181:8;;-1:-1:-1;3066:96:1;;-1:-1:-1;;;;2713:509:1:o;3409:328::-;3486:6;3494;3502;3555:2;3543:9;3534:7;3530:23;3526:32;3523:52;;;3571:1;3568;3561:12;3523:52;3594:29;3613:9;3594:29;:::i;:::-;3584:39;;3642:38;3676:2;3665:9;3661:18;3642:38;:::i;:::-;3632:48;;3727:2;3716:9;3712:18;3699:32;3689:42;;3409:328;;;;;:::o;3981:592::-;4052:6;4060;4113:2;4101:9;4092:7;4088:23;4084:32;4081:52;;;4129:1;4126;4119:12;4081:52;4156:23;;-1:-1:-1;;;;;4228:14:1;;;4225:34;;;4255:1;4252;4245:12;4225:34;4293:6;4282:9;4278:22;4268:32;;4338:7;4331:4;4327:2;4323:13;4319:27;4309:55;;4360:1;4357;4350:12;4309:55;4400:2;4387:16;4426:2;4418:6;4415:14;4412:34;;;4442:1;4439;4432:12;4412:34;4487:7;4482:2;4473:6;4469:2;4465:15;4461:24;4458:37;4455:57;;;4508:1;4505;4498:12;4455:57;4539:2;4531:11;;;;;4561:6;;-1:-1:-1;3981:592:1;;-1:-1:-1;;;;3981:592:1:o;4578:437::-;4664:6;4672;4725:2;4713:9;4704:7;4700:23;4696:32;4693:52;;;4741:1;4738;4731:12;4693:52;4768:23;;-1:-1:-1;;;;;4803:30:1;;4800:50;;;4846:1;4843;4836:12;4800:50;4885:70;4947:7;4938:6;4927:9;4923:22;4885:70;:::i;:::-;4974:8;;4859:96;;-1:-1:-1;4578:437:1;-1:-1:-1;;;;4578:437:1:o;5020:349::-;5104:12;;-1:-1:-1;;;;;5100:38:1;5088:51;;5192:4;5181:16;;;5175:23;-1:-1:-1;;;;;5171:48:1;5155:14;;;5148:72;5208:2;5272:16;;;5266:23;5259:31;5252:39;5236:14;;;5229:63;5345:4;5334:16;;;5328:23;5353:8;5324:38;5308:14;;5301:62;5020:349::o;5374:722::-;5607:2;5659:21;;;5729:13;;5632:18;;;5751:22;;;5578:4;;5607:2;5830:15;;;;5804:2;5789:18;;;5578:4;5873:197;5887:6;5884:1;5881:13;5873:197;;;5936:52;5984:3;5975:6;5969:13;5936:52;:::i;:::-;6045:15;;;;6017:4;6008:14;;;;;5909:1;5902:9;5873:197;;6101:171;6168:20;;-1:-1:-1;;;;;6217:30:1;;6207:41;;6197:69;;6262:1;6259;6252:12;6277:184;6335:6;6388:2;6376:9;6367:7;6363:23;6359:32;6356:52;;;6404:1;6401;6394:12;6356:52;6427:28;6445:9;6427:28;:::i;6466:186::-;6525:6;6578:2;6566:9;6557:7;6553:23;6549:32;6546:52;;;6594:1;6591;6584:12;6546:52;6617:29;6636:9;6617:29;:::i;6657:171::-;6724:20;;-1:-1:-1;;;;;6773:30:1;;6763:41;;6753:69;;6818:1;6815;6808:12;6833:161;6900:20;;6960:8;6949:20;;6939:31;;6929:59;;6984:1;6981;6974:12;6999:612;7107:6;7115;7123;7131;7139;7147;7155;7208:3;7196:9;7187:7;7183:23;7179:33;7176:53;;;7225:1;7222;7215:12;7176:53;7261:9;7248:23;7238:33;;7290:37;7323:2;7312:9;7308:18;7290:37;:::i;:::-;7280:47;;7346:37;7379:2;7368:9;7364:18;7346:37;:::i;:::-;7336:47;;7430:2;7419:9;7415:18;7402:32;7392:42;;7453:38;7486:3;7475:9;7471:19;7453:38;:::i;:::-;7443:48;;7510:38;7543:3;7532:9;7528:19;7510:38;:::i;:::-;7500:48;;7567:38;7600:3;7589:9;7585:19;7567:38;:::i;:::-;7557:48;;6999:612;;;;;;;;;;:::o;7616:632::-;7787:2;7839:21;;;7909:13;;7812:18;;;7931:22;;;7758:4;;7787:2;8010:15;;;;7984:2;7969:18;;;7758:4;8053:169;8067:6;8064:1;8061:13;8053:169;;;8128:13;;8116:26;;8197:15;;;;8162:12;;;;8089:1;8082:9;8053:169;;8253:651;8372:6;8380;8433:2;8421:9;8412:7;8408:23;8404:32;8401:52;;;8449:1;8446;8439:12;8401:52;8476:23;;-1:-1:-1;;;;;8548:14:1;;;8545:34;;;8575:1;8572;8565:12;8545:34;8613:6;8602:9;8598:22;8588:32;;8658:7;8651:4;8647:2;8643:13;8639:27;8629:55;;8680:1;8677;8670:12;8629:55;8720:2;8707:16;8746:2;8738:6;8735:14;8732:34;;;8762:1;8759;8752:12;8732:34;8818:7;8813:2;8805:4;8797:6;8793:17;8789:2;8785:26;8781:35;8778:48;8775:68;;;8839:1;8836;8829:12;8909:322;8986:6;8994;9002;9055:2;9043:9;9034:7;9030:23;9026:32;9023:52;;;9071:1;9068;9061:12;9023:52;9094:29;9113:9;9094:29;:::i;:::-;9084:39;9170:2;9155:18;;9142:32;;-1:-1:-1;9221:2:1;9206:18;;;9193:32;;8909:322;-1:-1:-1;;;8909:322:1:o;9236:118::-;9322:5;9315:13;9308:21;9301:5;9298:32;9288:60;;9344:1;9341;9334:12;9359:315;9424:6;9432;9485:2;9473:9;9464:7;9460:23;9456:32;9453:52;;;9501:1;9498;9491:12;9453:52;9524:29;9543:9;9524:29;:::i;:::-;9514:39;;9603:2;9592:9;9588:18;9575:32;9616:28;9638:5;9616:28;:::i;:::-;9663:5;9653:15;;;9359:315;;;;;:::o;10616:258::-;10683:6;10691;10744:2;10732:9;10723:7;10719:23;10715:32;10712:52;;;10760:1;10757;10750:12;10712:52;10783:28;10801:9;10783:28;:::i;:::-;10773:38;;10830;10864:2;10853:9;10849:18;10830:38;:::i;:::-;10820:48;;10616:258;;;;;:::o;10879:127::-;10940:10;10935:3;10931:20;10928:1;10921:31;10971:4;10968:1;10961:15;10995:4;10992:1;10985:15;11011:1138;11106:6;11114;11122;11130;11183:3;11171:9;11162:7;11158:23;11154:33;11151:53;;;11200:1;11197;11190:12;11151:53;11223:29;11242:9;11223:29;:::i;:::-;11213:39;;11271:38;11305:2;11294:9;11290:18;11271:38;:::i;:::-;11261:48;-1:-1:-1;11356:2:1;11341:18;;11328:32;;-1:-1:-1;11411:2:1;11396:18;;11383:32;-1:-1:-1;;;;;11464:14:1;;;11461:34;;;11491:1;11488;11481:12;11461:34;11529:6;11518:9;11514:22;11504:32;;11574:7;11567:4;11563:2;11559:13;11555:27;11545:55;;11596:1;11593;11586:12;11545:55;11632:2;11619:16;11654:2;11650;11647:10;11644:36;;;11660:18;;:::i;:::-;11735:2;11729:9;11703:2;11789:13;;-1:-1:-1;;11785:22:1;;;11809:2;11781:31;11777:40;11765:53;;;11833:18;;;11853:22;;;11830:46;11827:72;;;11879:18;;:::i;:::-;11919:10;11915:2;11908:22;11954:2;11946:6;11939:18;11994:7;11989:2;11984;11980;11976:11;11972:20;11969:33;11966:53;;;12015:1;12012;12005:12;11966:53;12071:2;12066;12062;12058:11;12053:2;12045:6;12041:15;12028:46;12116:1;12111:2;12106;12098:6;12094:15;12090:24;12083:35;12137:6;12127:16;;;;;;;11011:1138;;;;;;;:::o;12154:266::-;12350:3;12335:19;;12363:51;12339:9;12396:6;12363:51;:::i;12425:260::-;12493:6;12501;12554:2;12542:9;12533:7;12529:23;12525:32;12522:52;;;12570:1;12567;12560:12;12522:52;12593:29;12612:9;12593:29;:::i;12690:380::-;12769:1;12765:12;;;;12812;;;12833:61;;12887:4;12879:6;12875:17;12865:27;;12833:61;12940:2;12932:6;12929:14;12909:18;12906:38;12903:161;;12986:10;12981:3;12977:20;12974:1;12967:31;13021:4;13018:1;13011:15;13049:4;13046:1;13039:15;12903:161;;12690:380;;;:::o;13201:963::-;13310:4;13339:2;13368;13357:9;13350:21;13391:1;13424:6;13418:13;13454:36;13480:9;13454:36;:::i;:::-;13526:6;13521:2;13510:9;13506:18;13499:34;13552:2;13573:1;13605:2;13594:9;13590:18;13622:1;13617:158;;;;13789:1;13784:354;;;;13583:555;;13617:158;-1:-1:-1;;13665:24:1;;13645:18;;;13638:52;13743:14;;13736:22;13733:1;13729:30;13714:46;;13710:55;;;-1:-1:-1;13617:158:1;;13784:354;13815:6;13812:1;13805:17;13863:2;13860:1;13850:16;13888:1;13902:180;13916:6;13913:1;13910:13;13902:180;;;14009:14;;13985:17;;;13981:26;;13974:50;14052:16;;;;13931:10;;13902:180;;;14106:17;;14102:26;;;-1:-1:-1;;13583:555:1;-1:-1:-1;14155:3:1;;13201:963;-1:-1:-1;;;;;;;;13201:963:1:o;14379:545::-;14481:2;14476:3;14473:11;14470:448;;;14517:1;14542:5;14538:2;14531:17;14587:4;14583:2;14573:19;14657:2;14645:10;14641:19;14638:1;14634:27;14628:4;14624:38;14693:4;14681:10;14678:20;14675:47;;;-1:-1:-1;14716:4:1;14675:47;14771:2;14766:3;14762:12;14759:1;14755:20;14749:4;14745:31;14735:41;;14826:82;14844:2;14837:5;14834:13;14826:82;;;14889:17;;;14870:1;14859:13;14826:82;;15100:1206;-1:-1:-1;;;;;15216:27:1;;15213:53;;;15246:18;;:::i;:::-;15275:94;15365:3;15325:38;15357:4;15351:11;15325:38;:::i;:::-;15319:4;15275:94;:::i;:::-;15395:1;15420:2;15415:3;15412:11;15437:1;15432:616;;;;16092:1;16109:3;16106:93;;;-1:-1:-1;16165:19:1;;;16152:33;16106:93;-1:-1:-1;;15057:1:1;15053:11;;;15049:24;15045:29;15035:40;15081:1;15077:11;;;15032:57;16212:78;;15405:895;;15432:616;13148:1;13141:14;;;13185:4;13172:18;;-1:-1:-1;;15468:17:1;;;15569:9;15591:229;15605:7;15602:1;15599:14;15591:229;;;15694:19;;;15681:33;15666:49;;15801:4;15786:20;;;;15754:1;15742:14;;;;15621:12;15591:229;;;15595:3;15848;15839:7;15836:16;15833:159;;;15972:1;15968:6;15962:3;15956;15953:1;15949:11;15945:21;15941:34;15937:39;15924:9;15919:3;15915:19;15902:33;15898:79;15890:6;15883:95;15833:159;;;16035:1;16029:3;16026:1;16022:11;16018:19;16012:4;16005:33;15405:895;;15100:1206;;;:::o;16311:390::-;16470:2;16459:9;16452:21;16509:6;16504:2;16493:9;16489:18;16482:34;16566:6;16558;16553:2;16542:9;16538:18;16525:48;16622:1;16593:22;;;16617:2;16589:31;;;16582:42;;;;16685:2;16664:15;;;-1:-1:-1;;16660:29:1;16645:45;16641:54;;16311:390;-1:-1:-1;16311:390:1:o;16706:127::-;16767:10;16762:3;16758:20;16755:1;16748:31;16798:4;16795:1;16788:15;16822:4;16819:1;16812:15;16838:127;16899:10;16894:3;16890:20;16887:1;16880:31;16930:4;16927:1;16920:15;16954:4;16951:1;16944:15;16970:135;17009:3;17030:17;;;17027:43;;17050:18;;:::i;:::-;-1:-1:-1;17097:1:1;17086:13;;16970:135::o;17110:125::-;17150:4;17178:1;17175;17172:8;17169:34;;;17183:18;;:::i;:::-;-1:-1:-1;17220:9:1;;17110:125::o;17240:709::-;17545:25;;;-1:-1:-1;;;;;17606:31:1;;;;17601:2;17586:18;;17579:59;17686:10;17674:23;;;;17669:2;17654:18;;17647:51;17729:2;17714:18;;17707:34;;;;17790:8;17778:21;17772:3;17757:19;;17750:50;-1:-1:-1;;;;;17874:15:1;;;17868:3;17853:19;;17846:44;17927:15;17921:3;17906:19;;17899:44;17532:3;17517:19;;17240:709::o;17954:127::-;18015:10;18010:3;18006:20;18003:1;17996:31;18046:4;18043:1;18036:15;18070:4;18067:1;18060:15;18086:184;18144:6;18197:2;18185:9;18176:7;18172:23;18168:32;18165:52;;;18213:1;18210;18203:12;18165:52;18236:28;18254:9;18236:28;:::i;18275:184::-;18333:6;18386:2;18374:9;18365:7;18361:23;18357:32;18354:52;;;18402:1;18399;18392:12;18354:52;18425:28;18443:9;18425:28;:::i;18464:184::-;18522:6;18575:2;18563:9;18554:7;18550:23;18546:32;18543:52;;;18591:1;18588;18581:12;18543:52;18614:28;18632:9;18614:28;:::i;18994:128::-;19034:3;19065:1;19061:6;19058:1;19055:13;19052:39;;;19071:18;;:::i;:::-;-1:-1:-1;19107:9:1;;18994:128::o;19127:168::-;19167:7;19233:1;19229;19225:6;19221:14;19218:1;19215:21;19210:1;19203:9;19196:17;19192:45;19189:71;;;19240:18;;:::i;:::-;-1:-1:-1;19280:9:1;;19127:168::o;19300:1230::-;19524:3;19562:6;19556:13;19588:4;19601:51;19645:6;19640:3;19635:2;19627:6;19623:15;19601:51;:::i;:::-;19715:13;;19674:16;;;;19737:55;19715:13;19674:16;19759:15;;;19737:55;:::i;:::-;19881:13;;19814:20;;;19854:1;;19919:36;19881:13;19919:36;:::i;:::-;19974:1;19991:18;;;20018:141;;;;20173:1;20168:337;;;;19984:521;;20018:141;-1:-1:-1;;20053:24:1;;20039:39;;20130:16;;20123:24;20109:39;;20098:51;;;-1:-1:-1;20018:141:1;;20168:337;20199:6;20196:1;20189:17;20247:2;20244:1;20234:16;20272:1;20286:169;20300:8;20297:1;20294:15;20286:169;;;20382:14;;20367:13;;;20360:37;20425:16;;;;20317:10;;20286:169;;;20290:3;;20486:8;20479:5;20475:20;20468:27;;19984:521;-1:-1:-1;20521:3:1;;19300:1230;-1:-1:-1;;;;;;;;;;19300:1230:1:o;21251:245::-;21318:6;21371:2;21359:9;21350:7;21346:23;21342:32;21339:52;;;21387:1;21384;21377:12;21339:52;21419:9;21413:16;21438:28;21460:5;21438:28;:::i;22222:270::-;22261:7;-1:-1:-1;;;;;22331:10:1;;;22361;;;22394:11;;22387:19;22416:12;;;22408:21;;22383:47;22380:73;;;22433:18;;:::i;:::-;22473:13;;22222:270;-1:-1:-1;;;;22222:270:1:o;22497:228::-;22536:3;22564:10;22601:2;22598:1;22594:10;22631:2;22628:1;22624:10;22662:3;22658:2;22654:12;22649:3;22646:21;22643:47;;;22670:18;;:::i;:::-;22706:13;;22497:228;-1:-1:-1;;;;22497:228:1:o;22956:217::-;22996:1;23022;23012:132;;23066:10;23061:3;23057:20;23054:1;23047:31;23101:4;23098:1;23091:15;23129:4;23126:1;23119:15;23012:132;-1:-1:-1;23158:9:1;;22956:217::o;23178:489::-;-1:-1:-1;;;;;23447:15:1;;;23429:34;;23499:15;;23494:2;23479:18;;23472:43;23546:2;23531:18;;23524:34;;;23594:3;23589:2;23574:18;;23567:31;;;23372:4;;23615:46;;23641:19;;23633:6;23615:46;:::i;:::-;23607:54;23178:489;-1:-1:-1;;;;;;23178:489:1:o;23672:249::-;23741:6;23794:2;23782:9;23773:7;23769:23;23765:32;23762:52;;;23810:1;23807;23800:12;23762:52;23842:9;23836:16;23861:30;23885:5;23861:30;:::i
Swarm Source
ipfs://a2a66850a790d91d2d9d54ac6b6a896612bbf26c4e3c6c41c8198584cf4c1cce
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.