ERC-721
Overview
Max Total Supply
1,000 LTTrail
Holders
753
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
6 LTTrailLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
LightTrails
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-12-22 */ // SPDX-License-Identifier: MIT // File: IOperatorFilterRegistry.sol pragma solidity ^0.8.13; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function unregister(address addr) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); } // File: 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. */ abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); 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)); } } } } modifier onlyAllowedOperator(address from) virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { // 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) { _; return; } if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), msg.sender)) { revert OperatorNotAllowed(msg.sender); } } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } _; } } // File: DefaultOperatorFilterer.sol pragma solidity ^0.8.13; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} } // File: whitelist_flat.sol // File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.4; /** * @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: https://github.com/chiru-labs/ERC721A/blob/main/contracts/IERC721A.sol // ERC721A Contracts v4.2.2 // 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; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @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; /** * @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; /** * @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: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol // ERC721A Contracts v4.2.2 // 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 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 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 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 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`. ) 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: https://github.com/chiru-labs/ERC721A/blob/main/contracts/extensions/IERC721AQueryable.sol // ERC721A Contracts v4.2.2 // 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: https://github.com/chiru-labs/ERC721A/blob/main/contracts/extensions/ERC721AQueryable.sol // ERC721A Contracts v4.2.2 // 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: https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol pragma solidity >=0.8.0; /// @notice Simple single owner authorization mixin. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol) abstract contract Owned { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event OwnerUpdated(address indexed user, address indexed newOwner); /*////////////////////////////////////////////////////////////// OWNERSHIP STORAGE //////////////////////////////////////////////////////////////*/ address public owner; modifier onlyOwner() virtual { require(msg.sender == owner, "UNAUTHORIZED"); _; } /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _owner) { owner = _owner; emit OwnerUpdated(address(0), _owner); } /*////////////////////////////////////////////////////////////// OWNERSHIP LOGIC //////////////////////////////////////////////////////////////*/ function setOwner(address newOwner) public virtual onlyOwner { owner = newOwner; emit OwnerUpdated(msg.sender, newOwner); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @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`. * * 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 calldata data ) external; /** * @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 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 ) external; /** * @dev Transfers `tokenId` token 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; /** * @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; /** * @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); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @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); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @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, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @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 (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * 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, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } // File: contracts/LightTrails_Flat.sol pragma solidity ^0.8.4; contract LightTrails is ERC721A, ERC721AQueryable, DefaultOperatorFilterer, Owned { uint256 public FIRST_MINT_PRICE = 0 ether; uint256 public EXTRA_MINT_PRICE = 0 ether; uint256 public FIRST_MINT_PRICE_PUBLIC = 0.02 ether; uint256 public EXTRA_MINT_PRICE_PUBLIC = 0.02 ether; uint256 constant MAX_SUPPLY_PLUS_ONE = 1001; uint256 constant MAX_PER_WALLET_PLUS_ONE = 6; uint256 RESERVED = 50; string tokenBaseUri = "ipfs://QmWowjx9HKytYNg9oPg96DtjJUvfx4ivg6p6bTXS1AeGhS/"; bool public paused = true; bool public openToPublic = false; bytes32 public merkleRoot; mapping(address => uint256) private _freeMintedCount; mapping(address => uint256) private _totalMintedCount; mapping(address => bool) private _wLMinted; constructor(bytes32 _merkleRoot) ERC721A("LightTrails", "LTTrail") Owned(msg.sender) { merkleRoot = _merkleRoot; } function checkInWhiteList(bytes32[] calldata proof, uint256 quantity) view public returns(bool) { bytes32 leaf = keccak256(abi.encodePacked(msg.sender, quantity)); bool verified = MerkleProof.verify(proof, merkleRoot, leaf); return verified; } // Rename mint function to optimize gas function mint_540(uint256 _quantity, bytes32[] calldata _proof) external payable { unchecked { require(!paused, "MINTING PAUSED"); bool isWhiteListed = checkInWhiteList(_proof, _quantity); uint256 firstMintPrice; uint256 extraMintPrice; if(isWhiteListed && !openToPublic) { require(!_wLMinted[msg.sender], "ALREADY MINTED"); firstMintPrice = FIRST_MINT_PRICE; extraMintPrice = EXTRA_MINT_PRICE; } else { require(openToPublic, "MINTING NOT YET OPEN FOR PUBLIC"); require(_totalMintedCount[msg.sender] + _quantity < MAX_PER_WALLET_PLUS_ONE, "MAX PER WALLET IS 5"); firstMintPrice = FIRST_MINT_PRICE_PUBLIC; extraMintPrice = EXTRA_MINT_PRICE_PUBLIC; } uint256 _totalSupply = totalSupply(); require(_totalSupply + _quantity + RESERVED < MAX_SUPPLY_PLUS_ONE, "MAX SUPPLY REACHED"); uint256 payForCount = _quantity; uint256 payForFirstMint = 0; uint256 freeMintCount = _freeMintedCount[msg.sender]; if (freeMintCount < 1) { if (_quantity > 1) { payForCount = _quantity - 1; } else { payForCount = 0; } payForFirstMint = 1; if(isWhiteListed && !openToPublic) { _freeMintedCount[msg.sender] = 0; } else { _freeMintedCount[msg.sender] = 1; } } if(isWhiteListed && !openToPublic) { _wLMinted[msg.sender] = true; } else { _totalMintedCount[msg.sender] += _quantity; } require( msg.value >= (payForCount * extraMintPrice + payForFirstMint * firstMintPrice), "INCORRECT ETH AMOUNT" ); _mint(msg.sender, _quantity); } } // Set first mint price function setFirstMintPrice(uint256 _newPrice) public onlyOwner { FIRST_MINT_PRICE = _newPrice; } // Set extra mint price function setExtraMintPrice(uint256 _newPrice) public onlyOwner { EXTRA_MINT_PRICE = _newPrice; } // Set first mint price for public function setFirstMintPricePublic(uint256 _newPrice) public onlyOwner { FIRST_MINT_PRICE_PUBLIC = _newPrice; } // Set extra mint price for public function setExtraMintPricePublic(uint256 _newPrice) public onlyOwner { EXTRA_MINT_PRICE_PUBLIC = _newPrice; } function freeMintedCount(address owner) external view returns (uint256) { return _freeMintedCount[owner]; } function totalMintedCount(address owner) external view returns (uint256) { return _totalMintedCount[owner]; } function _startTokenId() internal pure override returns (uint256) { return 1; } function _baseURI() internal view override returns (string memory) { return tokenBaseUri; } function setBaseURI(string calldata _newBaseUri) external onlyOwner { tokenBaseUri = _newBaseUri; } function flipSale() external onlyOwner { paused = !paused; } function flipOpenToPublic() external onlyOwner { openToPublic = !openToPublic; } function collectReserves() external onlyOwner { require(RESERVED > 0, "RESERVES TAKEN"); _mint(msg.sender, 50); RESERVED = 0; } function withdraw() external onlyOwner { require( payable(owner).send(address(this).balance), "UNSUCCESSFUL" ); } function setApprovalForAll(address operator, bool approved) public override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom(address from, address to, uint256 tokenId) public override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","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":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","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":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","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"},{"inputs":[],"name":"EXTRA_MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_MINT_PRICE_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FIRST_MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FIRST_MINT_PRICE_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"checkInWhiteList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectReserves","outputs":[],"stateMutability":"nonpayable","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":[],"name":"flipOpenToPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"freeMintedCount","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":[{"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":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"mint_540","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openToPublic","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"nonpayable","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setExtraMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setExtraMintPricePublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setFirstMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setFirstMintPricePublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":"owner","type":"address"}],"name":"totalMintedCount","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":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260006009556000600a5566470de4df820000600b5566470de4df820000600c556032600d5560405180606001604052806036815260200162004e0d60369139600e90805190602001906200005a9291906200043d565b506001600f60006101000a81548160ff0219169083151502179055506000600f60016101000a81548160ff0219169083151502179055503480156200009e57600080fd5b5060405162004e4338038062004e438339818101604052810190620000c491906200052d565b33733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600b81526020017f4c69676874547261696c730000000000000000000000000000000000000000008152506040518060400160405280600781526020017f4c54547261696c000000000000000000000000000000000000000000000000008152508160029080519060200190620001609291906200043d565b508060039080519060200190620001799291906200043d565b506200018a6200043460201b60201c565b600081905550505060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620003875780156200024d576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b815260040162000213929190620005a4565b600060405180830381600087803b1580156200022e57600080fd5b505af115801562000243573d6000803e3d6000fd5b5050505062000386565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000307576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620002cd929190620005a4565b600060405180830381600087803b158015620002e857600080fd5b505af1158015620002fd573d6000803e3d6000fd5b5050505062000385565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620003509190620005d1565b600060405180830381600087803b1580156200036b57600080fd5b505af115801562000380573d6000803e3d6000fd5b505050505b5b5b505080600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a350806010819055505062000652565b60006001905090565b8280546200044b906200061d565b90600052602060002090601f0160209004810192826200046f5760008555620004bb565b82601f106200048a57805160ff1916838001178555620004bb565b82800160010185558215620004bb579182015b82811115620004ba5782518255916020019190600101906200049d565b5b509050620004ca9190620004ce565b5090565b5b80821115620004e9576000816000905550600101620004cf565b5090565b600080fd5b6000819050919050565b6200050781620004f2565b81146200051357600080fd5b50565b6000815190506200052781620004fc565b92915050565b600060208284031215620005465762000545620004ed565b5b6000620005568482850162000516565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200058c826200055f565b9050919050565b6200059e816200057f565b82525050565b6000604082019050620005bb600083018562000593565b620005ca602083018462000593565b9392505050565b6000602082019050620005e8600083018462000593565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200063657607f821691505b6020821081036200064c576200064b620005ee565b5b50919050565b6147ab80620006626000396000f3fe60806040526004361061023b5760003560e01c80636352211e1161012e57806396b04c75116100ab578063b88d4fde1161006f578063b88d4fde14610850578063bfc28c0a14610879578063c23dc68f146108b6578063c87b56dd146108f3578063e985e9c5146109305761023b565b806396b04c7514610759578063981332351461078457806399a2557a146107c1578063a22cb465146107fe578063aaff97b4146108275761023b565b80638da5cb5b116100f25780638da5cb5b146106705780638ddbd1621461069b57806392ee4025146106d857806393b71a1a1461070357806395d89b411461072e5761023b565b80636352211e1461058657806367facf47146105c357806370a08231146105df5780637ba5e6211461061c5780638462151c146106335761023b565b80632052e89d116101bc5780634bda2fdc116101805780634bda2fdc146104a35780635401546b146104cc57806355f804b3146104f55780635bbb21771461051e5780635c975abb1461055b5761023b565b80632052e89d146103e657806323b872dd1461040f5780632eb4a7ab146104385780633ccfd60b1461046357806342842e0e1461047a5761023b565b8063081812fc11610203578063081812fc14610301578063095ea7b31461033e57806313af40351461036757806318160ddd146103905780631831ccf2146103bb5761023b565b806301ffc9a714610240578063029877b61461027d5780630370e1401461029457806303a7fef7146102ab57806306fdde03146102d6575b600080fd5b34801561024c57600080fd5b5061026760048036038101906102629190613547565b61096d565b604051610274919061358f565b60405180910390f35b34801561028957600080fd5b506102926109ff565b005b3480156102a057600080fd5b506102a9610ae9565b005b3480156102b757600080fd5b506102c0610ba5565b6040516102cd91906135c3565b60405180910390f35b3480156102e257600080fd5b506102eb610bab565b6040516102f89190613677565b60405180910390f35b34801561030d57600080fd5b50610328600480360381019061032391906136c5565b610c3d565b6040516103359190613733565b60405180910390f35b34801561034a57600080fd5b506103656004803603810190610360919061377a565b610cbc565b005b34801561037357600080fd5b5061038e600480360381019061038991906137ba565b610dc6565b005b34801561039c57600080fd5b506103a5610ef4565b6040516103b291906135c3565b60405180910390f35b3480156103c757600080fd5b506103d0610f0b565b6040516103dd919061358f565b60405180910390f35b3480156103f257600080fd5b5061040d600480360381019061040891906136c5565b610f1e565b005b34801561041b57600080fd5b50610436600480360381019061043191906137e7565b610fb8565b005b34801561044457600080fd5b5061044d611108565b60405161045a9190613853565b60405180910390f35b34801561046f57600080fd5b5061047861110e565b005b34801561048657600080fd5b506104a1600480360381019061049c91906137e7565b611236565b005b3480156104af57600080fd5b506104ca60048036038101906104c591906136c5565b611386565b005b3480156104d857600080fd5b506104f360048036038101906104ee91906136c5565b611420565b005b34801561050157600080fd5b5061051c600480360381019061051791906138d3565b6114ba565b005b34801561052a57600080fd5b5061054560048036038101906105409190613976565b611560565b6040516105529190613b26565b60405180910390f35b34801561056757600080fd5b50610570611623565b60405161057d919061358f565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a891906136c5565b611636565b6040516105ba9190613733565b60405180910390f35b6105dd60048036038101906105d89190613b9e565b611648565b005b3480156105eb57600080fd5b50610606600480360381019061060191906137ba565b611ae2565b60405161061391906135c3565b60405180910390f35b34801561062857600080fd5b50610631611b9a565b005b34801561063f57600080fd5b5061065a600480360381019061065591906137ba565b611c56565b6040516106679190613cbc565b60405180910390f35b34801561067c57600080fd5b50610685611d99565b6040516106929190613733565b60405180910390f35b3480156106a757600080fd5b506106c260048036038101906106bd9190613cde565b611dbf565b6040516106cf919061358f565b60405180910390f35b3480156106e457600080fd5b506106ed611e4b565b6040516106fa91906135c3565b60405180910390f35b34801561070f57600080fd5b50610718611e51565b60405161072591906135c3565b60405180910390f35b34801561073a57600080fd5b50610743611e57565b6040516107509190613677565b60405180910390f35b34801561076557600080fd5b5061076e611ee9565b60405161077b91906135c3565b60405180910390f35b34801561079057600080fd5b506107ab60048036038101906107a691906137ba565b611eef565b6040516107b891906135c3565b60405180910390f35b3480156107cd57600080fd5b506107e860048036038101906107e39190613d3e565b611f38565b6040516107f59190613cbc565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613dbd565b612144565b005b34801561083357600080fd5b5061084e600480360381019061084991906136c5565b61224e565b005b34801561085c57600080fd5b5061087760048036038101906108729190613f2d565b6122e8565b005b34801561088557600080fd5b506108a0600480360381019061089b91906137ba565b61243b565b6040516108ad91906135c3565b60405180910390f35b3480156108c257600080fd5b506108dd60048036038101906108d891906136c5565b612484565b6040516108ea9190614005565b60405180910390f35b3480156108ff57600080fd5b5061091a600480360381019061091591906136c5565b6124ee565b6040516109279190613677565b60405180910390f35b34801561093c57600080fd5b5061095760048036038101906109529190614020565b61258c565b604051610964919061358f565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109c857506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109f85750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a86906140ac565b60405180910390fd5b6000600d5411610ad4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acb90614118565b60405180910390fd5b610adf336032612620565b6000600d81905550565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b70906140ac565b60405180910390fd5b600f60019054906101000a900460ff1615600f60016101000a81548160ff021916908315150217905550565b600b5481565b606060028054610bba90614167565b80601f0160208091040260200160405190810160405280929190818152602001828054610be690614167565b8015610c335780601f10610c0857610100808354040283529160200191610c33565b820191906000526020600020905b815481529060010190602001808311610c1657829003601f168201915b5050505050905090565b6000610c48826127db565b610c7e576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610db7576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610d34929190614198565b602060405180830381865afa158015610d51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7591906141d6565b610db657806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610dad9190613733565b60405180910390fd5b5b610dc1838361283a565b505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4d906140ac565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a350565b6000610efe61297e565b6001546000540303905090565b600f60019054906101000a900460ff1681565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa5906140ac565b60405180910390fd5b8060098190555050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156110f6573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361102a57611025848484612987565b611102565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611073929190614198565b602060405180830381865afa158015611090573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b491906141d6565b6110f557336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016110ec9190613733565b60405180910390fd5b5b611101848484612987565b5b50505050565b60105481565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461119e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611195906140ac565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050611234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122b9061424f565b60405180910390fd5b565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611374573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112a8576112a3848484612ca9565b611380565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016112f1929190614198565b602060405180830381865afa15801561130e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133291906141d6565b61137357336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161136a9190613733565b60405180910390fd5b5b61137f848484612ca9565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140d906140ac565b60405180910390fd5b80600a8190555050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a7906140ac565b60405180910390fd5b80600b8190555050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461154a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611541906140ac565b60405180910390fd5b8181600e919061155b9291906133e9565b505050565b6060600083839050905060008167ffffffffffffffff81111561158657611585613e02565b5b6040519080825280602002602001820160405280156115bf57816020015b6115ac61346f565b8152602001906001900390816115a45790505b50905060005b828114611617576115ee8686838181106115e2576115e161426f565b5b90506020020135612484565b8282815181106116015761160061426f565b5b60200260200101819052508060010190506115c5565b50809250505092915050565b600f60009054906101000a900460ff1681565b600061164182612cc9565b9050919050565b600f60009054906101000a900460ff1615611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f906142ea565b60405180910390fd5b60006116a5838386611dbf565b90506000808280156116c45750600f60019054906101000a900460ff16155b1561176557601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174d90614356565b60405180910390fd5b6009549150600a549050611843565b600f60019054906101000a900460ff166117b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ab906143c2565b60405180910390fd5b600686601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110611838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182f9061442e565b60405180910390fd5b600b549150600c5490505b600061184d610ef4565b90506103e9600d548883010110611899576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118909061449a565b60405180910390fd5b6000879050600080601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060018110156119b95760018a11156119005760018a039250611905565b600092505b600191508680156119235750600f60019054906101000a900460ff16155b15611972576000601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506119b8565b6001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b8680156119d35750600f60019054906101000a900460ff16155b15611a35576001601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611a83565b89601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b85820285840201341015611acc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac390614506565b60405180910390fd5b611ad6338b612620565b50505050505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b49576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c21906140ac565b60405180910390fd5b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b60606000806000611c6685611ae2565b905060008167ffffffffffffffff811115611c8457611c83613e02565b5b604051908082528060200260200182016040528015611cb25781602001602082028036833780820191505090505b509050611cbd61346f565b6000611cc761297e565b90505b838614611d8b57611cda81612d95565b91508160400151611d8057600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1614611d2557816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611d7f5780838780600101985081518110611d7257611d7161426f565b5b6020026020010181815250505b5b806001019050611cca565b508195505050505050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803383604051602001611dd592919061458f565b6040516020818303038152906040528051906020012090506000611e3d868680806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505060105484612dc0565b905080925050509392505050565b60095481565b600c5481565b606060038054611e6690614167565b80601f0160208091040260200160405190810160405280929190818152602001828054611e9290614167565b8015611edf5780601f10611eb457610100808354040283529160200191611edf565b820191906000526020600020905b815481529060010190602001808311611ec257829003601f168201915b5050505050905090565b600a5481565b6000601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6060818310611f73576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611f7e612dd7565b9050611f8861297e565b851015611f9a57611f9761297e565b94505b80841115611fa6578093505b6000611fb187611ae2565b905084861015611fd4576000868603905081811015611fce578091505b50611fd9565b600090505b60008167ffffffffffffffff811115611ff557611ff4613e02565b5b6040519080825280602002602001820160405280156120235781602001602082028036833780820191505090505b5090506000820361203a578094505050505061213d565b600061204588612484565b90506000816040015161205a57816000015190505b60008990505b8881141580156120705750848714155b1561212f5761207e81612d95565b9250826040015161212457600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16146120c957826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361212357808488806001019950815181106121165761211561426f565b5b6020026020010181815250505b5b806001019050612060565b508583528296505050505050505b9392505050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561223f576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016121bc929190614198565b602060405180830381865afa1580156121d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fd91906141d6565b61223e57806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016122359190613733565b60405180910390fd5b5b6122498383612de0565b505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d5906140ac565b60405180910390fd5b80600c8190555050565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612427573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361235b5761235685858585612eeb565b612434565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016123a4929190614198565b602060405180830381865afa1580156123c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e591906141d6565b61242657336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161241d9190613733565b60405180910390fd5b5b61243385858585612eeb565b5b5050505050565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61248c61346f565b61249461346f565b61249c61297e565b8310806124b057506124ac612dd7565b8310155b156124be57809150506124e9565b6124c783612d95565b90508060400151156124dc57809150506124e9565b6124e583612f5e565b9150505b919050565b60606124f9826127db565b61252f576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612539612f7e565b905060008151036125595760405180602001604052806000815250612584565b8061256384613010565b6040516020016125749291906145f7565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008054905060008203612660576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61266d6000848385613060565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506126e4836126d56000866000613066565b6126de8561308e565b1761309e565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461278557808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061274a565b50600082036127c0576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506127d660008483856130c9565b505050565b6000816127e661297e565b111580156127f5575060005482105b8015612833575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600061284582611636565b90508073ffffffffffffffffffffffffffffffffffffffff166128666130cf565b73ffffffffffffffffffffffffffffffffffffffff16146128c9576128928161288d6130cf565b61258c565b6128c8576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b600061299282612cc9565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146129f9576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080612a05846130d7565b91509150612a1b8187612a166130cf565b6130fe565b612a6757612a3086612a2b6130cf565b61258c565b612a66576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612acd576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ada8686866001613060565b8015612ae557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550612bb385612b8f888887613066565b7c02000000000000000000000000000000000000000000000000000000001761309e565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603612c395760006001850190506000600460008381526020019081526020016000205403612c37576000548114612c36578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ca186868660016130c9565b505050505050565b612cc4838383604051806020016040528060008152506122e8565b505050565b60008082905080612cd861297e565b11612d5e57600054811015612d5d5760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612d5b575b60008103612d51576004600083600190039350838152602001908152602001600020549050612d27565b8092505050612d90565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b612d9d61346f565b612db96004600084815260200190815260200160002054613142565b9050919050565b600082612dcd85846131f8565b1490509392505050565b60008054905090565b8060076000612ded6130cf565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612e9a6130cf565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612edf919061358f565b60405180910390a35050565b612ef6848484610fb8565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612f5857612f218484848461324e565b612f57576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b612f6661346f565b612f77612f7283612cc9565b613142565b9050919050565b6060600e8054612f8d90614167565b80601f0160208091040260200160405190810160405280929190818152602001828054612fb990614167565b80156130065780601f10612fdb57610100808354040283529160200191613006565b820191906000526020600020905b815481529060010190602001808311612fe957829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561304b57600184039350600a81066030018453600a8104905080613029575b50828103602084039350808452505050919050565b50505050565b60008060e883901c905060e861307d86868461339e565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b61314a61346f565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008082905060005b84518110156132435761322e828683815181106132215761322061426f565b5b60200260200101516133a7565b9150808061323b9061464a565b915050613201565b508091505092915050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026132746130cf565b8786866040518563ffffffff1660e01b815260040161329694939291906146e7565b6020604051808303816000875af19250505080156132d257506040513d601f19601f820116820180604052508101906132cf9190614748565b60015b61334b573d8060008114613302576040519150601f19603f3d011682016040523d82523d6000602084013e613307565b606091505b506000815103613343576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b60008183106133bf576133ba82846133d2565b6133ca565b6133c983836133d2565b5b905092915050565b600082600052816020526040600020905092915050565b8280546133f590614167565b90600052602060002090601f016020900481019282613417576000855561345e565b82601f1061343057803560ff191683800117855561345e565b8280016001018555821561345e579182015b8281111561345d578235825591602001919060010190613442565b5b50905061346b91906134be565b5090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b5b808211156134d75760008160009055506001016134bf565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613524816134ef565b811461352f57600080fd5b50565b6000813590506135418161351b565b92915050565b60006020828403121561355d5761355c6134e5565b5b600061356b84828501613532565b91505092915050565b60008115159050919050565b61358981613574565b82525050565b60006020820190506135a46000830184613580565b92915050565b6000819050919050565b6135bd816135aa565b82525050565b60006020820190506135d860008301846135b4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156136185780820151818401526020810190506135fd565b83811115613627576000848401525b50505050565b6000601f19601f8301169050919050565b6000613649826135de565b61365381856135e9565b93506136638185602086016135fa565b61366c8161362d565b840191505092915050565b60006020820190508181036000830152613691818461363e565b905092915050565b6136a2816135aa565b81146136ad57600080fd5b50565b6000813590506136bf81613699565b92915050565b6000602082840312156136db576136da6134e5565b5b60006136e9848285016136b0565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061371d826136f2565b9050919050565b61372d81613712565b82525050565b60006020820190506137486000830184613724565b92915050565b61375781613712565b811461376257600080fd5b50565b6000813590506137748161374e565b92915050565b60008060408385031215613791576137906134e5565b5b600061379f85828601613765565b92505060206137b0858286016136b0565b9150509250929050565b6000602082840312156137d0576137cf6134e5565b5b60006137de84828501613765565b91505092915050565b600080600060608486031215613800576137ff6134e5565b5b600061380e86828701613765565b935050602061381f86828701613765565b9250506040613830868287016136b0565b9150509250925092565b6000819050919050565b61384d8161383a565b82525050565b60006020820190506138686000830184613844565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126138935761389261386e565b5b8235905067ffffffffffffffff8111156138b0576138af613873565b5b6020830191508360018202830111156138cc576138cb613878565b5b9250929050565b600080602083850312156138ea576138e96134e5565b5b600083013567ffffffffffffffff811115613908576139076134ea565b5b6139148582860161387d565b92509250509250929050565b60008083601f8401126139365761393561386e565b5b8235905067ffffffffffffffff81111561395357613952613873565b5b60208301915083602082028301111561396f5761396e613878565b5b9250929050565b6000806020838503121561398d5761398c6134e5565b5b600083013567ffffffffffffffff8111156139ab576139aa6134ea565b5b6139b785828601613920565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6139f881613712565b82525050565b600067ffffffffffffffff82169050919050565b613a1b816139fe565b82525050565b613a2a81613574565b82525050565b600062ffffff82169050919050565b613a4881613a30565b82525050565b608082016000820151613a6460008501826139ef565b506020820151613a776020850182613a12565b506040820151613a8a6040850182613a21565b506060820151613a9d6060850182613a3f565b50505050565b6000613aaf8383613a4e565b60808301905092915050565b6000602082019050919050565b6000613ad3826139c3565b613add81856139ce565b9350613ae8836139df565b8060005b83811015613b19578151613b008882613aa3565b9750613b0b83613abb565b925050600181019050613aec565b5085935050505092915050565b60006020820190508181036000830152613b408184613ac8565b905092915050565b60008083601f840112613b5e57613b5d61386e565b5b8235905067ffffffffffffffff811115613b7b57613b7a613873565b5b602083019150836020820283011115613b9757613b96613878565b5b9250929050565b600080600060408486031215613bb757613bb66134e5565b5b6000613bc5868287016136b0565b935050602084013567ffffffffffffffff811115613be657613be56134ea565b5b613bf286828701613b48565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613c33816135aa565b82525050565b6000613c458383613c2a565b60208301905092915050565b6000602082019050919050565b6000613c6982613bfe565b613c738185613c09565b9350613c7e83613c1a565b8060005b83811015613caf578151613c968882613c39565b9750613ca183613c51565b925050600181019050613c82565b5085935050505092915050565b60006020820190508181036000830152613cd68184613c5e565b905092915050565b600080600060408486031215613cf757613cf66134e5565b5b600084013567ffffffffffffffff811115613d1557613d146134ea565b5b613d2186828701613b48565b93509350506020613d34868287016136b0565b9150509250925092565b600080600060608486031215613d5757613d566134e5565b5b6000613d6586828701613765565b9350506020613d76868287016136b0565b9250506040613d87868287016136b0565b9150509250925092565b613d9a81613574565b8114613da557600080fd5b50565b600081359050613db781613d91565b92915050565b60008060408385031215613dd457613dd36134e5565b5b6000613de285828601613765565b9250506020613df385828601613da8565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613e3a8261362d565b810181811067ffffffffffffffff82111715613e5957613e58613e02565b5b80604052505050565b6000613e6c6134db565b9050613e788282613e31565b919050565b600067ffffffffffffffff821115613e9857613e97613e02565b5b613ea18261362d565b9050602081019050919050565b82818337600083830152505050565b6000613ed0613ecb84613e7d565b613e62565b905082815260208101848484011115613eec57613eeb613dfd565b5b613ef7848285613eae565b509392505050565b600082601f830112613f1457613f1361386e565b5b8135613f24848260208601613ebd565b91505092915050565b60008060008060808587031215613f4757613f466134e5565b5b6000613f5587828801613765565b9450506020613f6687828801613765565b9350506040613f77878288016136b0565b925050606085013567ffffffffffffffff811115613f9857613f976134ea565b5b613fa487828801613eff565b91505092959194509250565b608082016000820151613fc660008501826139ef565b506020820151613fd96020850182613a12565b506040820151613fec6040850182613a21565b506060820151613fff6060850182613a3f565b50505050565b600060808201905061401a6000830184613fb0565b92915050565b60008060408385031215614037576140366134e5565b5b600061404585828601613765565b925050602061405685828601613765565b9150509250929050565b7f554e415554484f52495a45440000000000000000000000000000000000000000600082015250565b6000614096600c836135e9565b91506140a182614060565b602082019050919050565b600060208201905081810360008301526140c581614089565b9050919050565b7f52455345525645532054414b454e000000000000000000000000000000000000600082015250565b6000614102600e836135e9565b915061410d826140cc565b602082019050919050565b60006020820190508181036000830152614131816140f5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061417f57607f821691505b60208210810361419257614191614138565b5b50919050565b60006040820190506141ad6000830185613724565b6141ba6020830184613724565b9392505050565b6000815190506141d081613d91565b92915050565b6000602082840312156141ec576141eb6134e5565b5b60006141fa848285016141c1565b91505092915050565b7f554e5355434345535346554c0000000000000000000000000000000000000000600082015250565b6000614239600c836135e9565b915061424482614203565b602082019050919050565b600060208201905081810360008301526142688161422c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4d494e54494e4720504155534544000000000000000000000000000000000000600082015250565b60006142d4600e836135e9565b91506142df8261429e565b602082019050919050565b60006020820190508181036000830152614303816142c7565b9050919050565b7f414c5245414459204d494e544544000000000000000000000000000000000000600082015250565b6000614340600e836135e9565b915061434b8261430a565b602082019050919050565b6000602082019050818103600083015261436f81614333565b9050919050565b7f4d494e54494e47204e4f5420594554204f50454e20464f52205055424c494300600082015250565b60006143ac601f836135e9565b91506143b782614376565b602082019050919050565b600060208201905081810360008301526143db8161439f565b9050919050565b7f4d4158205045522057414c4c4554204953203500000000000000000000000000600082015250565b60006144186013836135e9565b9150614423826143e2565b602082019050919050565b600060208201905081810360008301526144478161440b565b9050919050565b7f4d415820535550504c5920524541434845440000000000000000000000000000600082015250565b60006144846012836135e9565b915061448f8261444e565b602082019050919050565b600060208201905081810360008301526144b381614477565b9050919050565b7f494e434f52524543542045544820414d4f554e54000000000000000000000000600082015250565b60006144f06014836135e9565b91506144fb826144ba565b602082019050919050565b6000602082019050818103600083015261451f816144e3565b9050919050565b60008160601b9050919050565b600061453e82614526565b9050919050565b600061455082614533565b9050919050565b61456861456382613712565b614545565b82525050565b6000819050919050565b614589614584826135aa565b61456e565b82525050565b600061459b8285614557565b6014820191506145ab8284614578565b6020820191508190509392505050565b600081905092915050565b60006145d1826135de565b6145db81856145bb565b93506145eb8185602086016135fa565b80840191505092915050565b600061460382856145c6565b915061460f82846145c6565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614655826135aa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036146875761468661461b565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b60006146b982614692565b6146c3818561469d565b93506146d38185602086016135fa565b6146dc8161362d565b840191505092915050565b60006080820190506146fc6000830187613724565b6147096020830186613724565b61471660408301856135b4565b818103606083015261472881846146ae565b905095945050505050565b6000815190506147428161351b565b92915050565b60006020828403121561475e5761475d6134e5565b5b600061476c84828501614733565b9150509291505056fea26469706673582212205fa18252be9c00bebf740c7643df3691b882bb18c8e3afd3a4c0b5c7eb1965a664736f6c634300080d0033697066733a2f2f516d576f776a7839484b7974594e67396f5067393644746a4a5576667834697667367036625458533141654768532f74fe99a3f69aab96ccd399609157ada321b7375c0884efffa696c05ad1358aff
Deployed Bytecode
0x60806040526004361061023b5760003560e01c80636352211e1161012e57806396b04c75116100ab578063b88d4fde1161006f578063b88d4fde14610850578063bfc28c0a14610879578063c23dc68f146108b6578063c87b56dd146108f3578063e985e9c5146109305761023b565b806396b04c7514610759578063981332351461078457806399a2557a146107c1578063a22cb465146107fe578063aaff97b4146108275761023b565b80638da5cb5b116100f25780638da5cb5b146106705780638ddbd1621461069b57806392ee4025146106d857806393b71a1a1461070357806395d89b411461072e5761023b565b80636352211e1461058657806367facf47146105c357806370a08231146105df5780637ba5e6211461061c5780638462151c146106335761023b565b80632052e89d116101bc5780634bda2fdc116101805780634bda2fdc146104a35780635401546b146104cc57806355f804b3146104f55780635bbb21771461051e5780635c975abb1461055b5761023b565b80632052e89d146103e657806323b872dd1461040f5780632eb4a7ab146104385780633ccfd60b1461046357806342842e0e1461047a5761023b565b8063081812fc11610203578063081812fc14610301578063095ea7b31461033e57806313af40351461036757806318160ddd146103905780631831ccf2146103bb5761023b565b806301ffc9a714610240578063029877b61461027d5780630370e1401461029457806303a7fef7146102ab57806306fdde03146102d6575b600080fd5b34801561024c57600080fd5b5061026760048036038101906102629190613547565b61096d565b604051610274919061358f565b60405180910390f35b34801561028957600080fd5b506102926109ff565b005b3480156102a057600080fd5b506102a9610ae9565b005b3480156102b757600080fd5b506102c0610ba5565b6040516102cd91906135c3565b60405180910390f35b3480156102e257600080fd5b506102eb610bab565b6040516102f89190613677565b60405180910390f35b34801561030d57600080fd5b50610328600480360381019061032391906136c5565b610c3d565b6040516103359190613733565b60405180910390f35b34801561034a57600080fd5b506103656004803603810190610360919061377a565b610cbc565b005b34801561037357600080fd5b5061038e600480360381019061038991906137ba565b610dc6565b005b34801561039c57600080fd5b506103a5610ef4565b6040516103b291906135c3565b60405180910390f35b3480156103c757600080fd5b506103d0610f0b565b6040516103dd919061358f565b60405180910390f35b3480156103f257600080fd5b5061040d600480360381019061040891906136c5565b610f1e565b005b34801561041b57600080fd5b50610436600480360381019061043191906137e7565b610fb8565b005b34801561044457600080fd5b5061044d611108565b60405161045a9190613853565b60405180910390f35b34801561046f57600080fd5b5061047861110e565b005b34801561048657600080fd5b506104a1600480360381019061049c91906137e7565b611236565b005b3480156104af57600080fd5b506104ca60048036038101906104c591906136c5565b611386565b005b3480156104d857600080fd5b506104f360048036038101906104ee91906136c5565b611420565b005b34801561050157600080fd5b5061051c600480360381019061051791906138d3565b6114ba565b005b34801561052a57600080fd5b5061054560048036038101906105409190613976565b611560565b6040516105529190613b26565b60405180910390f35b34801561056757600080fd5b50610570611623565b60405161057d919061358f565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a891906136c5565b611636565b6040516105ba9190613733565b60405180910390f35b6105dd60048036038101906105d89190613b9e565b611648565b005b3480156105eb57600080fd5b50610606600480360381019061060191906137ba565b611ae2565b60405161061391906135c3565b60405180910390f35b34801561062857600080fd5b50610631611b9a565b005b34801561063f57600080fd5b5061065a600480360381019061065591906137ba565b611c56565b6040516106679190613cbc565b60405180910390f35b34801561067c57600080fd5b50610685611d99565b6040516106929190613733565b60405180910390f35b3480156106a757600080fd5b506106c260048036038101906106bd9190613cde565b611dbf565b6040516106cf919061358f565b60405180910390f35b3480156106e457600080fd5b506106ed611e4b565b6040516106fa91906135c3565b60405180910390f35b34801561070f57600080fd5b50610718611e51565b60405161072591906135c3565b60405180910390f35b34801561073a57600080fd5b50610743611e57565b6040516107509190613677565b60405180910390f35b34801561076557600080fd5b5061076e611ee9565b60405161077b91906135c3565b60405180910390f35b34801561079057600080fd5b506107ab60048036038101906107a691906137ba565b611eef565b6040516107b891906135c3565b60405180910390f35b3480156107cd57600080fd5b506107e860048036038101906107e39190613d3e565b611f38565b6040516107f59190613cbc565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613dbd565b612144565b005b34801561083357600080fd5b5061084e600480360381019061084991906136c5565b61224e565b005b34801561085c57600080fd5b5061087760048036038101906108729190613f2d565b6122e8565b005b34801561088557600080fd5b506108a0600480360381019061089b91906137ba565b61243b565b6040516108ad91906135c3565b60405180910390f35b3480156108c257600080fd5b506108dd60048036038101906108d891906136c5565b612484565b6040516108ea9190614005565b60405180910390f35b3480156108ff57600080fd5b5061091a600480360381019061091591906136c5565b6124ee565b6040516109279190613677565b60405180910390f35b34801561093c57600080fd5b5061095760048036038101906109529190614020565b61258c565b604051610964919061358f565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109c857506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109f85750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a86906140ac565b60405180910390fd5b6000600d5411610ad4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acb90614118565b60405180910390fd5b610adf336032612620565b6000600d81905550565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b70906140ac565b60405180910390fd5b600f60019054906101000a900460ff1615600f60016101000a81548160ff021916908315150217905550565b600b5481565b606060028054610bba90614167565b80601f0160208091040260200160405190810160405280929190818152602001828054610be690614167565b8015610c335780601f10610c0857610100808354040283529160200191610c33565b820191906000526020600020905b815481529060010190602001808311610c1657829003601f168201915b5050505050905090565b6000610c48826127db565b610c7e576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610db7576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610d34929190614198565b602060405180830381865afa158015610d51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7591906141d6565b610db657806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610dad9190613733565b60405180910390fd5b5b610dc1838361283a565b505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4d906140ac565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a350565b6000610efe61297e565b6001546000540303905090565b600f60019054906101000a900460ff1681565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa5906140ac565b60405180910390fd5b8060098190555050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156110f6573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361102a57611025848484612987565b611102565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611073929190614198565b602060405180830381865afa158015611090573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b491906141d6565b6110f557336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016110ec9190613733565b60405180910390fd5b5b611101848484612987565b5b50505050565b60105481565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461119e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611195906140ac565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050611234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122b9061424f565b60405180910390fd5b565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611374573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112a8576112a3848484612ca9565b611380565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016112f1929190614198565b602060405180830381865afa15801561130e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133291906141d6565b61137357336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161136a9190613733565b60405180910390fd5b5b61137f848484612ca9565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140d906140ac565b60405180910390fd5b80600a8190555050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a7906140ac565b60405180910390fd5b80600b8190555050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461154a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611541906140ac565b60405180910390fd5b8181600e919061155b9291906133e9565b505050565b6060600083839050905060008167ffffffffffffffff81111561158657611585613e02565b5b6040519080825280602002602001820160405280156115bf57816020015b6115ac61346f565b8152602001906001900390816115a45790505b50905060005b828114611617576115ee8686838181106115e2576115e161426f565b5b90506020020135612484565b8282815181106116015761160061426f565b5b60200260200101819052508060010190506115c5565b50809250505092915050565b600f60009054906101000a900460ff1681565b600061164182612cc9565b9050919050565b600f60009054906101000a900460ff1615611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f906142ea565b60405180910390fd5b60006116a5838386611dbf565b90506000808280156116c45750600f60019054906101000a900460ff16155b1561176557601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174d90614356565b60405180910390fd5b6009549150600a549050611843565b600f60019054906101000a900460ff166117b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ab906143c2565b60405180910390fd5b600686601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110611838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182f9061442e565b60405180910390fd5b600b549150600c5490505b600061184d610ef4565b90506103e9600d548883010110611899576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118909061449a565b60405180910390fd5b6000879050600080601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060018110156119b95760018a11156119005760018a039250611905565b600092505b600191508680156119235750600f60019054906101000a900460ff16155b15611972576000601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506119b8565b6001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b8680156119d35750600f60019054906101000a900460ff16155b15611a35576001601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611a83565b89601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b85820285840201341015611acc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac390614506565b60405180910390fd5b611ad6338b612620565b50505050505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b49576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c21906140ac565b60405180910390fd5b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b60606000806000611c6685611ae2565b905060008167ffffffffffffffff811115611c8457611c83613e02565b5b604051908082528060200260200182016040528015611cb25781602001602082028036833780820191505090505b509050611cbd61346f565b6000611cc761297e565b90505b838614611d8b57611cda81612d95565b91508160400151611d8057600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1614611d2557816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611d7f5780838780600101985081518110611d7257611d7161426f565b5b6020026020010181815250505b5b806001019050611cca565b508195505050505050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803383604051602001611dd592919061458f565b6040516020818303038152906040528051906020012090506000611e3d868680806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505060105484612dc0565b905080925050509392505050565b60095481565b600c5481565b606060038054611e6690614167565b80601f0160208091040260200160405190810160405280929190818152602001828054611e9290614167565b8015611edf5780601f10611eb457610100808354040283529160200191611edf565b820191906000526020600020905b815481529060010190602001808311611ec257829003601f168201915b5050505050905090565b600a5481565b6000601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6060818310611f73576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611f7e612dd7565b9050611f8861297e565b851015611f9a57611f9761297e565b94505b80841115611fa6578093505b6000611fb187611ae2565b905084861015611fd4576000868603905081811015611fce578091505b50611fd9565b600090505b60008167ffffffffffffffff811115611ff557611ff4613e02565b5b6040519080825280602002602001820160405280156120235781602001602082028036833780820191505090505b5090506000820361203a578094505050505061213d565b600061204588612484565b90506000816040015161205a57816000015190505b60008990505b8881141580156120705750848714155b1561212f5761207e81612d95565b9250826040015161212457600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16146120c957826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361212357808488806001019950815181106121165761211561426f565b5b6020026020010181815250505b5b806001019050612060565b508583528296505050505050505b9392505050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561223f576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016121bc929190614198565b602060405180830381865afa1580156121d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fd91906141d6565b61223e57806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016122359190613733565b60405180910390fd5b5b6122498383612de0565b505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d5906140ac565b60405180910390fd5b80600c8190555050565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612427573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361235b5761235685858585612eeb565b612434565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016123a4929190614198565b602060405180830381865afa1580156123c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e591906141d6565b61242657336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161241d9190613733565b60405180910390fd5b5b61243385858585612eeb565b5b5050505050565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61248c61346f565b61249461346f565b61249c61297e565b8310806124b057506124ac612dd7565b8310155b156124be57809150506124e9565b6124c783612d95565b90508060400151156124dc57809150506124e9565b6124e583612f5e565b9150505b919050565b60606124f9826127db565b61252f576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612539612f7e565b905060008151036125595760405180602001604052806000815250612584565b8061256384613010565b6040516020016125749291906145f7565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008054905060008203612660576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61266d6000848385613060565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506126e4836126d56000866000613066565b6126de8561308e565b1761309e565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461278557808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061274a565b50600082036127c0576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506127d660008483856130c9565b505050565b6000816127e661297e565b111580156127f5575060005482105b8015612833575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600061284582611636565b90508073ffffffffffffffffffffffffffffffffffffffff166128666130cf565b73ffffffffffffffffffffffffffffffffffffffff16146128c9576128928161288d6130cf565b61258c565b6128c8576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b600061299282612cc9565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146129f9576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080612a05846130d7565b91509150612a1b8187612a166130cf565b6130fe565b612a6757612a3086612a2b6130cf565b61258c565b612a66576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612acd576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ada8686866001613060565b8015612ae557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550612bb385612b8f888887613066565b7c02000000000000000000000000000000000000000000000000000000001761309e565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603612c395760006001850190506000600460008381526020019081526020016000205403612c37576000548114612c36578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ca186868660016130c9565b505050505050565b612cc4838383604051806020016040528060008152506122e8565b505050565b60008082905080612cd861297e565b11612d5e57600054811015612d5d5760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612d5b575b60008103612d51576004600083600190039350838152602001908152602001600020549050612d27565b8092505050612d90565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b612d9d61346f565b612db96004600084815260200190815260200160002054613142565b9050919050565b600082612dcd85846131f8565b1490509392505050565b60008054905090565b8060076000612ded6130cf565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612e9a6130cf565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612edf919061358f565b60405180910390a35050565b612ef6848484610fb8565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612f5857612f218484848461324e565b612f57576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b612f6661346f565b612f77612f7283612cc9565b613142565b9050919050565b6060600e8054612f8d90614167565b80601f0160208091040260200160405190810160405280929190818152602001828054612fb990614167565b80156130065780601f10612fdb57610100808354040283529160200191613006565b820191906000526020600020905b815481529060010190602001808311612fe957829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561304b57600184039350600a81066030018453600a8104905080613029575b50828103602084039350808452505050919050565b50505050565b60008060e883901c905060e861307d86868461339e565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b61314a61346f565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008082905060005b84518110156132435761322e828683815181106132215761322061426f565b5b60200260200101516133a7565b9150808061323b9061464a565b915050613201565b508091505092915050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026132746130cf565b8786866040518563ffffffff1660e01b815260040161329694939291906146e7565b6020604051808303816000875af19250505080156132d257506040513d601f19601f820116820180604052508101906132cf9190614748565b60015b61334b573d8060008114613302576040519150601f19603f3d011682016040523d82523d6000602084013e613307565b606091505b506000815103613343576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b60008183106133bf576133ba82846133d2565b6133ca565b6133c983836133d2565b5b905092915050565b600082600052816020526040600020905092915050565b8280546133f590614167565b90600052602060002090601f016020900481019282613417576000855561345e565b82601f1061343057803560ff191683800117855561345e565b8280016001018555821561345e579182015b8281111561345d578235825591602001919060010190613442565b5b50905061346b91906134be565b5090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b5b808211156134d75760008160009055506001016134bf565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613524816134ef565b811461352f57600080fd5b50565b6000813590506135418161351b565b92915050565b60006020828403121561355d5761355c6134e5565b5b600061356b84828501613532565b91505092915050565b60008115159050919050565b61358981613574565b82525050565b60006020820190506135a46000830184613580565b92915050565b6000819050919050565b6135bd816135aa565b82525050565b60006020820190506135d860008301846135b4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156136185780820151818401526020810190506135fd565b83811115613627576000848401525b50505050565b6000601f19601f8301169050919050565b6000613649826135de565b61365381856135e9565b93506136638185602086016135fa565b61366c8161362d565b840191505092915050565b60006020820190508181036000830152613691818461363e565b905092915050565b6136a2816135aa565b81146136ad57600080fd5b50565b6000813590506136bf81613699565b92915050565b6000602082840312156136db576136da6134e5565b5b60006136e9848285016136b0565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061371d826136f2565b9050919050565b61372d81613712565b82525050565b60006020820190506137486000830184613724565b92915050565b61375781613712565b811461376257600080fd5b50565b6000813590506137748161374e565b92915050565b60008060408385031215613791576137906134e5565b5b600061379f85828601613765565b92505060206137b0858286016136b0565b9150509250929050565b6000602082840312156137d0576137cf6134e5565b5b60006137de84828501613765565b91505092915050565b600080600060608486031215613800576137ff6134e5565b5b600061380e86828701613765565b935050602061381f86828701613765565b9250506040613830868287016136b0565b9150509250925092565b6000819050919050565b61384d8161383a565b82525050565b60006020820190506138686000830184613844565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126138935761389261386e565b5b8235905067ffffffffffffffff8111156138b0576138af613873565b5b6020830191508360018202830111156138cc576138cb613878565b5b9250929050565b600080602083850312156138ea576138e96134e5565b5b600083013567ffffffffffffffff811115613908576139076134ea565b5b6139148582860161387d565b92509250509250929050565b60008083601f8401126139365761393561386e565b5b8235905067ffffffffffffffff81111561395357613952613873565b5b60208301915083602082028301111561396f5761396e613878565b5b9250929050565b6000806020838503121561398d5761398c6134e5565b5b600083013567ffffffffffffffff8111156139ab576139aa6134ea565b5b6139b785828601613920565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6139f881613712565b82525050565b600067ffffffffffffffff82169050919050565b613a1b816139fe565b82525050565b613a2a81613574565b82525050565b600062ffffff82169050919050565b613a4881613a30565b82525050565b608082016000820151613a6460008501826139ef565b506020820151613a776020850182613a12565b506040820151613a8a6040850182613a21565b506060820151613a9d6060850182613a3f565b50505050565b6000613aaf8383613a4e565b60808301905092915050565b6000602082019050919050565b6000613ad3826139c3565b613add81856139ce565b9350613ae8836139df565b8060005b83811015613b19578151613b008882613aa3565b9750613b0b83613abb565b925050600181019050613aec565b5085935050505092915050565b60006020820190508181036000830152613b408184613ac8565b905092915050565b60008083601f840112613b5e57613b5d61386e565b5b8235905067ffffffffffffffff811115613b7b57613b7a613873565b5b602083019150836020820283011115613b9757613b96613878565b5b9250929050565b600080600060408486031215613bb757613bb66134e5565b5b6000613bc5868287016136b0565b935050602084013567ffffffffffffffff811115613be657613be56134ea565b5b613bf286828701613b48565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613c33816135aa565b82525050565b6000613c458383613c2a565b60208301905092915050565b6000602082019050919050565b6000613c6982613bfe565b613c738185613c09565b9350613c7e83613c1a565b8060005b83811015613caf578151613c968882613c39565b9750613ca183613c51565b925050600181019050613c82565b5085935050505092915050565b60006020820190508181036000830152613cd68184613c5e565b905092915050565b600080600060408486031215613cf757613cf66134e5565b5b600084013567ffffffffffffffff811115613d1557613d146134ea565b5b613d2186828701613b48565b93509350506020613d34868287016136b0565b9150509250925092565b600080600060608486031215613d5757613d566134e5565b5b6000613d6586828701613765565b9350506020613d76868287016136b0565b9250506040613d87868287016136b0565b9150509250925092565b613d9a81613574565b8114613da557600080fd5b50565b600081359050613db781613d91565b92915050565b60008060408385031215613dd457613dd36134e5565b5b6000613de285828601613765565b9250506020613df385828601613da8565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613e3a8261362d565b810181811067ffffffffffffffff82111715613e5957613e58613e02565b5b80604052505050565b6000613e6c6134db565b9050613e788282613e31565b919050565b600067ffffffffffffffff821115613e9857613e97613e02565b5b613ea18261362d565b9050602081019050919050565b82818337600083830152505050565b6000613ed0613ecb84613e7d565b613e62565b905082815260208101848484011115613eec57613eeb613dfd565b5b613ef7848285613eae565b509392505050565b600082601f830112613f1457613f1361386e565b5b8135613f24848260208601613ebd565b91505092915050565b60008060008060808587031215613f4757613f466134e5565b5b6000613f5587828801613765565b9450506020613f6687828801613765565b9350506040613f77878288016136b0565b925050606085013567ffffffffffffffff811115613f9857613f976134ea565b5b613fa487828801613eff565b91505092959194509250565b608082016000820151613fc660008501826139ef565b506020820151613fd96020850182613a12565b506040820151613fec6040850182613a21565b506060820151613fff6060850182613a3f565b50505050565b600060808201905061401a6000830184613fb0565b92915050565b60008060408385031215614037576140366134e5565b5b600061404585828601613765565b925050602061405685828601613765565b9150509250929050565b7f554e415554484f52495a45440000000000000000000000000000000000000000600082015250565b6000614096600c836135e9565b91506140a182614060565b602082019050919050565b600060208201905081810360008301526140c581614089565b9050919050565b7f52455345525645532054414b454e000000000000000000000000000000000000600082015250565b6000614102600e836135e9565b915061410d826140cc565b602082019050919050565b60006020820190508181036000830152614131816140f5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061417f57607f821691505b60208210810361419257614191614138565b5b50919050565b60006040820190506141ad6000830185613724565b6141ba6020830184613724565b9392505050565b6000815190506141d081613d91565b92915050565b6000602082840312156141ec576141eb6134e5565b5b60006141fa848285016141c1565b91505092915050565b7f554e5355434345535346554c0000000000000000000000000000000000000000600082015250565b6000614239600c836135e9565b915061424482614203565b602082019050919050565b600060208201905081810360008301526142688161422c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4d494e54494e4720504155534544000000000000000000000000000000000000600082015250565b60006142d4600e836135e9565b91506142df8261429e565b602082019050919050565b60006020820190508181036000830152614303816142c7565b9050919050565b7f414c5245414459204d494e544544000000000000000000000000000000000000600082015250565b6000614340600e836135e9565b915061434b8261430a565b602082019050919050565b6000602082019050818103600083015261436f81614333565b9050919050565b7f4d494e54494e47204e4f5420594554204f50454e20464f52205055424c494300600082015250565b60006143ac601f836135e9565b91506143b782614376565b602082019050919050565b600060208201905081810360008301526143db8161439f565b9050919050565b7f4d4158205045522057414c4c4554204953203500000000000000000000000000600082015250565b60006144186013836135e9565b9150614423826143e2565b602082019050919050565b600060208201905081810360008301526144478161440b565b9050919050565b7f4d415820535550504c5920524541434845440000000000000000000000000000600082015250565b60006144846012836135e9565b915061448f8261444e565b602082019050919050565b600060208201905081810360008301526144b381614477565b9050919050565b7f494e434f52524543542045544820414d4f554e54000000000000000000000000600082015250565b60006144f06014836135e9565b91506144fb826144ba565b602082019050919050565b6000602082019050818103600083015261451f816144e3565b9050919050565b60008160601b9050919050565b600061453e82614526565b9050919050565b600061455082614533565b9050919050565b61456861456382613712565b614545565b82525050565b6000819050919050565b614589614584826135aa565b61456e565b82525050565b600061459b8285614557565b6014820191506145ab8284614578565b6020820191508190509392505050565b600081905092915050565b60006145d1826135de565b6145db81856145bb565b93506145eb8185602086016135fa565b80840191505092915050565b600061460382856145c6565b915061460f82846145c6565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614655826135aa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036146875761468661461b565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b60006146b982614692565b6146c3818561469d565b93506146d38185602086016135fa565b6146dc8161362d565b840191505092915050565b60006080820190506146fc6000830187613724565b6147096020830186613724565b61471660408301856135b4565b818103606083015261472881846146ae565b905095945050505050565b6000815190506147428161351b565b92915050565b60006020828403121561475e5761475d6134e5565b5b600061476c84828501614733565b9150509291505056fea26469706673582212205fa18252be9c00bebf740c7643df3691b882bb18c8e3afd3a4c0b5c7eb1965a664736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
74fe99a3f69aab96ccd399609157ada321b7375c0884efffa696c05ad1358aff
-----Decoded View---------------
Arg [0] : _merkleRoot (bytes32): 0x74fe99a3f69aab96ccd399609157ada321b7375c0884efffa696c05ad1358aff
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 74fe99a3f69aab96ccd399609157ada321b7375c0884efffa696c05ad1358aff
Deployed Bytecode Sourcemap
114915:5653:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33339:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119248:147;;;;;;;;;;;;;:::i;:::-;;119154:88;;;;;;;;;;;;;:::i;:::-;;115094:51;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34241:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40724:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119746:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76524:148;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;29992:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115446:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117956:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;119930:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;115485:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119401:140;;;;;;;;;;;;;:::i;:::-;;120120:190;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118093:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118241:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118967:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70364:528;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115416:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35634:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;116121:1802;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31176:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119080:68;;;;;;;;;;;;;:::i;:::-;;74240:900;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75888:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115809:263;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115002:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115150:51;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34417:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115048:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118525:115;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71280:2513;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119547:191;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118402:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120318:247;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118646:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69777:428;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34627:318;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41673:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33339:639;33424:4;33763:10;33748:25;;:11;:25;;;;:102;;;;33840:10;33825:25;;:11;:25;;;;33748:102;:179;;;;33917:10;33902:25;;:11;:25;;;;33748:179;33728:199;;33339:639;;;:::o;119248:147::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;119320:1:::1;119309:8;;:12;119301:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;119349:21;119355:10;119367:2;119349:5;:21::i;:::-;119388:1;119377:8;:12;;;;119248:147::o:0;119154:88::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;119224:12:::1;;;;;;;;;;;119223:13;119208:12;;:28;;;;;;;;;;;;;;;;;;119154:88::o:0;115094:51::-;;;;:::o;34241:100::-;34295:13;34328:5;34321:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34241:100;:::o;40724:218::-;40800:7;40825:16;40833:7;40825;:16::i;:::-;40820:64;;40850:34;;;;;;;;;;;;;;40820:64;40904:15;:24;40920:7;40904:24;;;;;;;;;;;:30;;;;;;;;;;;;40897:37;;40724:218;;;:::o;119746:176::-;119861:8;4634:1;2692:42;4586:45;;;:49;4582:225;;;2692:42;4657;;;4708:4;4715:8;4657:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4652:144;;4771:8;4752:28;;;;;;;;;;;:::i;:::-;;;;;;;;4652:144;4582:225;119882:32:::1;119896:8;119906:7;119882:13;:32::i;:::-;119746:176:::0;;;:::o;76524:148::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;76604:8:::1;76596:5;;:16;;;;;;;;;;;;;;;;;;76655:8;76630:34;;76643:10;76630:34;;;;;;;;;;;;76524:148:::0;:::o;29992:323::-;30053:7;30281:15;:13;:15::i;:::-;30266:12;;30250:13;;:28;:46;30243:53;;29992:323;:::o;115446:32::-;;;;;;;;;;;;;:::o;117956:104::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;118045:9:::1;118026:16;:28;;;;117956:104:::0;:::o;119930:182::-;120050:4;3888:1;2692:42;3840:45;;;:49;3836:539;;;4129:10;4121:18;;:4;:18;;;4117:85;;120067:37:::1;120086:4;120092:2;120096:7;120067:18;:37::i;:::-;4180:7:::0;;4117:85;2692:42;4221;;;4272:4;4279:10;4221:69;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4216:148;;4337:10;4318:30;;;;;;;;;;;:::i;:::-;;;;;;;;4216:148;3836:539;120067:37:::1;120086:4;120092:2;120096:7;120067:18;:37::i;:::-;119930:182:::0;;;;;:::o;115485:25::-;;;;:::o;119401:140::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;119471:5:::1;;;;;;;;;;;119463:19;;:42;119483:21;119463:42;;;;;;;;;;;;;;;;;;;;;;;119447:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;119401:140::o:0;120120:190::-;120244:4;3888:1;2692:42;3840:45;;;:49;3836:539;;;4129:10;4121:18;;:4;:18;;;4117:85;;120261:41:::1;120284:4;120290:2;120294:7;120261:22;:41::i;:::-;4180:7:::0;;4117:85;2692:42;4221;;;4272:4;4279:10;4221:69;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4216:148;;4337:10;4318:30;;;;;;;;;;;:::i;:::-;;;;;;;;4216:148;3836:539;120261:41:::1;120284:4;120290:2;120294:7;120261:22;:41::i;:::-;120120:190:::0;;;;;:::o;118093:104::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;118182:9:::1;118163:16;:28;;;;118093:104:::0;:::o;118241:117::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;118343:9:::1;118317:23;:35;;;;118241:117:::0;:::o;118967:107::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;119057:11:::1;;119042:12;:26;;;;;;;:::i;:::-;;118967:107:::0;;:::o;70364:528::-;70508:23;70574:22;70599:8;;:15;;70574:40;;70629:34;70687:14;70666:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;70629:73;;70722:9;70717:125;70738:14;70733:1;:19;70717:125;;70794:32;70814:8;;70823:1;70814:11;;;;;;;:::i;:::-;;;;;;;;70794:19;:32::i;:::-;70778:10;70789:1;70778:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;70754:3;;;;;70717:125;;;;70863:10;70856:17;;;;70364:528;;;;:::o;115416:25::-;;;;;;;;;;;;;:::o;35634:152::-;35706:7;35749:27;35768:7;35749:18;:27::i;:::-;35726:52;;35634:152;;;:::o;116121:1802::-;116237:6;;;;;;;;;;;116236:7;116228:34;;;;;;;;;;;;:::i;:::-;;;;;;;;;116273:18;116294:35;116311:6;;116319:9;116294:16;:35::i;:::-;116273:56;;116346:22;116377;116413:13;:30;;;;;116431:12;;;;;;;;;;;116430:13;116413:30;116410:490;;;116465:9;:21;116475:10;116465:21;;;;;;;;;;;;;;;;;;;;;;;;;116464:22;116456:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;116533:16;;116516:33;;116577:16;;116560:33;;116410:490;;;116630:12;;;;;;;;;;;116622:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;115297:1;116729:9;116697:17;:29;116715:10;116697:29;;;;;;;;;;;;;;;;:41;:67;116689:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;116816:23;;116799:40;;116867:23;;116850:40;;116410:490;116916:20;116939:13;:11;:13::i;:::-;116916:36;;115245:4;116998:8;;116986:9;116971:12;:24;:35;:57;116963:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;117062:19;117084:9;117062:31;;117102:23;117138:21;117162:16;:28;117179:10;117162:28;;;;;;;;;;;;;;;;117138:52;;117221:1;117205:13;:17;117201:361;;;117251:1;117239:9;:13;117235:117;;;117293:1;117281:9;:13;117267:27;;117235:117;;;117339:1;117325:15;;117235:117;117380:1;117362:19;;117397:13;:30;;;;;117415:12;;;;;;;;;;;117414:13;117397:30;117394:159;;;117475:1;117444:16;:28;117461:10;117444:28;;;;;;;;;;;;;;;:32;;;;117394:159;;;117540:1;117509:16;:28;117526:10;117509:28;;;;;;;;;;;;;;;:32;;;;117394:159;117201:361;117573:13;:30;;;;;117591:12;;;;;;;;;;;117590:13;117573:30;117570:153;;;117640:4;117616:9;:21;117626:10;117616:21;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;117570:153;;;117704:9;117671:17;:29;117689:10;117671:29;;;;;;;;;;;;;;;;:42;;;;;;;;;;;117570:153;117814:14;117796:15;:32;117779:14;117765:11;:28;:63;117751:9;:78;;117733:138;;;;;;;;;;;;:::i;:::-;;;;;;;;;117882:28;117888:10;117900:9;117882:5;:28::i;:::-;116209:1709;;;;;;;116121:1802;;;:::o;31176:233::-;31248:7;31289:1;31272:19;;:5;:19;;;31268:60;;31300:28;;;;;;;;;;;;;;31268:60;25335:13;31346:18;:25;31365:5;31346:25;;;;;;;;;;;;;;;;:55;31339:62;;31176:233;;;:::o;119080:68::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;119136:6:::1;;;;;;;;;;;119135:7;119126:6;;:16;;;;;;;;;;;;;;;;;;119080:68::o:0;74240:900::-;74318:16;74372:19;74406:25;74446:22;74471:16;74481:5;74471:9;:16::i;:::-;74446:41;;74502:25;74544:14;74530:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74502:57;;74574:31;;:::i;:::-;74625:9;74637:15;:13;:15::i;:::-;74625:27;;74620:472;74669:14;74654:11;:29;74620:472;;74721:15;74734:1;74721:12;:15::i;:::-;74709:27;;74759:9;:16;;;74800:8;74755:73;74876:1;74850:28;;:9;:14;;;:28;;;74846:111;;74923:9;:14;;;74903:34;;74846:111;75000:5;74979:26;;:17;:26;;;74975:102;;75056:1;75030:8;75039:13;;;;;;75030:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;74975:102;74620:472;74685:3;;;;;74620:472;;;;75113:8;75106:15;;;;;;;74240:900;;;:::o;75888:20::-;;;;;;;;;;;;;:::o;115809:263::-;115899:4;115912:12;115954:10;115966:8;115937:38;;;;;;;;;:::i;:::-;;;;;;;;;;;;;115927:49;;;;;;115912:64;;115983:13;115999:43;116018:5;;115999:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116025:10;;116037:4;115999:18;:43::i;:::-;115983:59;;116058:8;116051:15;;;;115809:263;;;;;:::o;115002:41::-;;;;:::o;115150:51::-;;;;:::o;34417:104::-;34473:13;34506:7;34499:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34417:104;:::o;115048:41::-;;;;:::o;118525:115::-;118588:7;118611:16;:23;118628:5;118611:23;;;;;;;;;;;;;;;;118604:30;;118525:115;;;:::o;71280:2513::-;71423:16;71490:4;71481:5;:13;71477:45;;71503:19;;;;;;;;;;;;;;71477:45;71537:19;71571:17;71591:14;:12;:14::i;:::-;71571:34;;71691:15;:13;:15::i;:::-;71683:5;:23;71679:87;;;71735:15;:13;:15::i;:::-;71727:23;;71679:87;71842:9;71835:4;:16;71831:73;;;71879:9;71872:16;;71831:73;71918:25;71946:16;71956:5;71946:9;:16::i;:::-;71918:44;;72140:4;72132:5;:12;72128:278;;;72165:19;72194:5;72187:4;:12;72165:34;;72236:17;72222:11;:31;72218:111;;;72298:11;72278:31;;72218:111;72146:198;72128:278;;;72389:1;72369:21;;72128:278;72420:25;72462:17;72448:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72420:60;;72520:1;72499:17;:22;72495:78;;72549:8;72542:15;;;;;;;;72495:78;72717:31;72751:26;72771:5;72751:19;:26::i;:::-;72717:60;;72792:25;73037:9;:16;;;73032:92;;73094:9;:14;;;73074:34;;73032:92;73143:9;73155:5;73143:17;;73138:478;73167:4;73162:1;:9;;:45;;;;;73190:17;73175:11;:32;;73162:45;73138:478;;;73245:15;73258:1;73245:12;:15::i;:::-;73233:27;;73283:9;:16;;;73324:8;73279:73;73400:1;73374:28;;:9;:14;;;:28;;;73370:111;;73447:9;:14;;;73427:34;;73370:111;73524:5;73503:26;;:17;:26;;;73499:102;;73580:1;73554:8;73563:13;;;;;;73554:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;73499:102;73138:478;73209:3;;;;;73138:478;;;;73718:11;73708:8;73701:29;73766:8;73759:15;;;;;;;;71280:2513;;;;;;:::o;119547:191::-;119670:8;4634:1;2692:42;4586:45;;;:49;4582:225;;;2692:42;4657;;;4708:4;4715:8;4657:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4652:144;;4771:8;4752:28;;;;;;;;;;;:::i;:::-;;;;;;;;4652:144;4582:225;119687:43:::1;119711:8;119721;119687:23;:43::i;:::-;119547:191:::0;;;:::o;118402:117::-;75979:5;;;;;;;;;;;75965:19;;:10;:19;;;75957:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;118504:9:::1;118478:23;:35;;;;118402:117:::0;:::o;120318:247::-;120488:4;3888:1;2692:42;3840:45;;;:49;3836:539;;;4129:10;4121:18;;:4;:18;;;4117:85;;120510:47:::1;120533:4;120539:2;120543:7;120552:4;120510:22;:47::i;:::-;4180:7:::0;;4117:85;2692:42;4221;;;4272:4;4279:10;4221:69;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4216:148;;4337:10;4318:30;;;;;;;;;;;:::i;:::-;;;;;;;;4216:148;3836:539;120510:47:::1;120533:4;120539:2;120543:7;120552:4;120510:22;:47::i;:::-;120318:247:::0;;;;;;:::o;118646:117::-;118710:7;118733:17;:24;118751:5;118733:24;;;;;;;;;;;;;;;;118726:31;;118646:117;;;:::o;69777:428::-;69861:21;;:::i;:::-;69895:31;;:::i;:::-;69951:15;:13;:15::i;:::-;69941:7;:25;:54;;;;69981:14;:12;:14::i;:::-;69970:7;:25;;69941:54;69937:103;;;70019:9;70012:16;;;;;69937:103;70062:21;70075:7;70062:12;:21::i;:::-;70050:33;;70098:9;:16;;;70094:65;;;70138:9;70131:16;;;;;70094:65;70176:21;70189:7;70176:12;:21::i;:::-;70169:28;;;69777:428;;;;:::o;34627:318::-;34700:13;34731:16;34739:7;34731;:16::i;:::-;34726:59;;34756:29;;;;;;;;;;;;;;34726:59;34798:21;34822:10;:8;:10::i;:::-;34798:34;;34875:1;34856:7;34850:21;:26;:87;;;;;;;;;;;;;;;;;34903:7;34912:18;34922:7;34912:9;:18::i;:::-;34886:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;34850:87;34843:94;;;34627:318;;;:::o;41673:164::-;41770:4;41794:18;:25;41813:5;41794:25;;;;;;;;;;;;;;;:35;41820:8;41794:35;;;;;;;;;;;;;;;;;;;;;;;;;41787:42;;41673:164;;;;:::o;51720:2720::-;51793:20;51816:13;;51793:36;;51856:1;51844:8;:13;51840:44;;51866:18;;;;;;;;;;;;;;51840:44;51897:61;51927:1;51931:2;51935:12;51949:8;51897:21;:61::i;:::-;52441:1;25473:2;52411:1;:26;;52410:32;52398:8;:45;52372:18;:22;52391:2;52372:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;52720:139;52757:2;52811:33;52834:1;52838:2;52842:1;52811:14;:33::i;:::-;52778:30;52799:8;52778:20;:30::i;:::-;:66;52720:18;:139::i;:::-;52686:17;:31;52704:12;52686:31;;;;;;;;;;;:173;;;;52876:16;52907:11;52936:8;52921:12;:23;52907:37;;53457:16;53453:2;53449:25;53437:37;;53829:12;53789:8;53748:1;53686:25;53627:1;53566;53539:335;53954:1;53940:12;53936:20;53894:346;53995:3;53986:7;53983:16;53894:346;;54213:7;54203:8;54200:1;54173:25;54170:1;54167;54162:59;54048:1;54039:7;54035:15;54024:26;;53894:346;;;53898:77;54285:1;54273:8;:13;54269:45;;54295:19;;;;;;;;;;;;;;54269:45;54347:3;54331:13;:19;;;;52146:2216;;54372:60;54401:1;54405:2;54409:12;54423:8;54372:20;:60::i;:::-;51782:2658;51720:2720;;:::o;42095:282::-;42160:4;42216:7;42197:15;:13;:15::i;:::-;:26;;:66;;;;;42250:13;;42240:7;:23;42197:66;:153;;;;;42349:1;26111:8;42301:17;:26;42319:7;42301:26;;;;;;;;;;;;:44;:49;42197:153;42177:173;;42095:282;;;:::o;40165:400::-;40246:13;40262:16;40270:7;40262;:16::i;:::-;40246:32;;40318:5;40295:28;;:19;:17;:19::i;:::-;:28;;;40291:175;;40343:44;40360:5;40367:19;:17;:19::i;:::-;40343:16;:44::i;:::-;40338:128;;40415:35;;;;;;;;;;;;;;40338:128;40291:175;40511:2;40478:15;:24;40494:7;40478:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;40549:7;40545:2;40529:28;;40538:5;40529:28;;;;;;;;;;;;40235:330;40165:400;;:::o;118769:87::-;118826:7;118849:1;118842:8;;118769:87;:::o;44363:2817::-;44497:27;44527;44546:7;44527:18;:27::i;:::-;44497:57;;44612:4;44571:45;;44587:19;44571:45;;;44567:86;;44625:28;;;;;;;;;;;;;;44567:86;44667:27;44696:23;44723:35;44750:7;44723:26;:35::i;:::-;44666:92;;;;44858:68;44883:15;44900:4;44906:19;:17;:19::i;:::-;44858:24;:68::i;:::-;44853:180;;44946:43;44963:4;44969:19;:17;:19::i;:::-;44946:16;:43::i;:::-;44941:92;;44998:35;;;;;;;;;;;;;;44941:92;44853:180;45064:1;45050:16;;:2;:16;;;45046:52;;45075:23;;;;;;;;;;;;;;45046:52;45111:43;45133:4;45139:2;45143:7;45152:1;45111:21;:43::i;:::-;45247:15;45244:160;;;45387:1;45366:19;45359:30;45244:160;45784:18;:24;45803:4;45784:24;;;;;;;;;;;;;;;;45782:26;;;;;;;;;;;;45853:18;:22;45872:2;45853:22;;;;;;;;;;;;;;;;45851:24;;;;;;;;;;;46175:146;46212:2;46261:45;46276:4;46282:2;46286:19;46261:14;:45::i;:::-;26391:8;46233:73;46175:18;:146::i;:::-;46146:17;:26;46164:7;46146:26;;;;;;;;;;;:175;;;;46492:1;26391:8;46441:19;:47;:52;46437:627;;46514:19;46546:1;46536:7;:11;46514:33;;46703:1;46669:17;:30;46687:11;46669:30;;;;;;;;;;;;:35;46665:384;;46807:13;;46792:11;:28;46788:242;;46987:19;46954:17;:30;46972:11;46954:30;;;;;;;;;;;:52;;;;46788:242;46665:384;46495:569;46437:627;47111:7;47107:2;47092:27;;47101:4;47092:27;;;;;;;;;;;;47130:42;47151:4;47157:2;47161:7;47170:1;47130:20;:42::i;:::-;44486:2694;;;44363:2817;;;:::o;47276:185::-;47414:39;47431:4;47437:2;47441:7;47414:39;;;;;;;;;;;;:16;:39::i;:::-;47276:185;;;:::o;36789:1275::-;36856:7;36876:12;36891:7;36876:22;;36959:4;36940:15;:13;:15::i;:::-;:23;36936:1061;;36993:13;;36986:4;:20;36982:1015;;;37031:14;37048:17;:23;37066:4;37048:23;;;;;;;;;;;;37031:40;;37165:1;26111:8;37137:6;:24;:29;37133:845;;37802:113;37819:1;37809:6;:11;37802:113;;37862:17;:25;37880:6;;;;;;;37862:25;;;;;;;;;;;;37853:34;;37802:113;;;37948:6;37941:13;;;;;;37133:845;37008:989;36982:1015;36936:1061;38025:31;;;;;;;;;;;;;;36789:1275;;;;:::o;36237:161::-;36305:21;;:::i;:::-;36346:44;36365:17;:24;36383:5;36365:24;;;;;;;;;;;;36346:18;:44::i;:::-;36339:51;;36237:161;;;:::o;6548:190::-;6673:4;6726;6697:25;6710:5;6717:4;6697:12;:25::i;:::-;:33;6690:40;;6548:190;;;;;:::o;29679:103::-;29734:7;29761:13;;29754:20;;29679:103;:::o;41282:234::-;41429:8;41377:18;:39;41396:19;:17;:19::i;:::-;41377:39;;;;;;;;;;;;;;;:49;41417:8;41377:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;41489:8;41453:55;;41468:19;:17;:19::i;:::-;41453:55;;;41499:8;41453:55;;;;;;:::i;:::-;;;;;;;;41282:234;;:::o;48059:399::-;48226:31;48239:4;48245:2;48249:7;48226:12;:31::i;:::-;48290:1;48272:2;:14;;;:19;48268:183;;48311:56;48342:4;48348:2;48352:7;48361:5;48311:30;:56::i;:::-;48306:145;;48395:40;;;;;;;;;;;;;;48306:145;48268:183;48059:399;;;;:::o;35975:166::-;36045:21;;:::i;:::-;36086:47;36105:27;36124:7;36105:18;:27::i;:::-;36086:18;:47::i;:::-;36079:54;;35975:166;;;:::o;118862:99::-;118914:13;118943:12;118936:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;118862:99;:::o;64340:1745::-;64405:17;64839:4;64832;64826:11;64822:22;64931:1;64925:4;64918:15;65006:4;65003:1;64999:12;64992:19;;65088:1;65083:3;65076:14;65192:3;65431:5;65413:428;65439:1;65413:428;;;65479:1;65474:3;65470:11;65463:18;;65650:2;65644:4;65640:13;65636:2;65632:22;65627:3;65619:36;65744:2;65738:4;65734:13;65726:21;;65811:4;65413:428;65801:25;65413:428;65417:21;65880:3;65875;65871:13;65995:4;65990:3;65986:14;65979:21;;66060:6;66055:3;66048:19;64444:1634;;;64340:1745;;;:::o;49120:159::-;;;;;:::o;63442:311::-;63577:7;63597:16;26515:3;63623:19;:41;;63597:68;;26515:3;63691:31;63702:4;63708:2;63712:9;63691:10;:31::i;:::-;63683:40;;:62;;63676:69;;;63442:311;;;;;:::o;39164:324::-;39234:14;39467:1;39457:8;39454:15;39428:24;39424:46;39414:56;;39164:324;;;:::o;38612:450::-;38692:14;38860:16;38853:5;38849:28;38840:37;;39037:5;39023:11;38998:23;38994:41;38991:52;38984:5;38981:63;38971:73;;38612:450;;;;:::o;49944:158::-;;;;;:::o;64133:105::-;64193:7;64220:10;64213:17;;64133:105;:::o;43258:485::-;43360:27;43389:23;43430:38;43471:15;:24;43487:7;43471:24;;;;;;;;;;;43430:65;;43648:18;43625:41;;43705:19;43699:26;43680:45;;43610:126;43258:485;;;:::o;42486:659::-;42635:11;42800:16;42793:5;42789:28;42780:37;;42960:16;42949:9;42945:32;42932:45;;43110:15;43099:9;43096:30;43088:5;43077:9;43074:20;43071:56;43061:66;;42486:659;;;;;:::o;38163:366::-;38229:31;;:::i;:::-;38306:6;38273:9;:14;;:41;;;;;;;;;;;25994:3;38359:6;:33;;38325:9;:24;;:68;;;;;;;;;;;38451:1;26111:8;38423:6;:24;:29;;38404:9;:16;;:48;;;;;;;;;;;26515:3;38492:6;:28;;38463:9;:19;;:58;;;;;;;;;;;38163:366;;;:::o;7415:296::-;7498:7;7518:20;7541:4;7518:27;;7561:9;7556:118;7580:5;:12;7576:1;:16;7556:118;;;7629:33;7639:12;7653:5;7659:1;7653:8;;;;;;;;:::i;:::-;;;;;;;;7629:9;:33::i;:::-;7614:48;;7594:3;;;;;:::i;:::-;;;;7556:118;;;;7691:12;7684:19;;;7415:296;;;;:::o;50542:716::-;50705:4;50751:2;50726:45;;;50772:19;:17;:19::i;:::-;50793:4;50799:7;50808:5;50726:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;50722:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51026:1;51009:6;:13;:18;51005:235;;51055:40;;;;;;;;;;;;;;51005:235;51198:6;51192:13;51183:6;51179:2;51175:15;51168:38;50722:529;50895:54;;;50885:64;;;:6;:64;;;;50878:71;;;50542:716;;;;;;:::o;63143:147::-;63280:6;63143:147;;;;;:::o;14455:149::-;14518:7;14549:1;14545;:5;:51;;14576:20;14591:1;14594;14576:14;:20::i;:::-;14545:51;;;14553:20;14568:1;14571;14553:14;:20::i;:::-;14545:51;14538:58;;14455:149;;;;:::o;14612:268::-;14680:13;14787:1;14781:4;14774:15;14816:1;14810:4;14803:15;14857:4;14851;14841:21;14832:30;;14612:268;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:118::-;1688:24;1706:5;1688:24;:::i;:::-;1683:3;1676:37;1601:118;;:::o;1725:222::-;1818:4;1856:2;1845:9;1841:18;1833:26;;1869:71;1937:1;1926:9;1922:17;1913:6;1869:71;:::i;:::-;1725:222;;;;:::o;1953:99::-;2005:6;2039:5;2033:12;2023:22;;1953:99;;;:::o;2058:169::-;2142:11;2176:6;2171:3;2164:19;2216:4;2211:3;2207:14;2192:29;;2058:169;;;;:::o;2233:307::-;2301:1;2311:113;2325:6;2322:1;2319:13;2311:113;;;2410:1;2405:3;2401:11;2395:18;2391:1;2386:3;2382:11;2375:39;2347:2;2344:1;2340:10;2335:15;;2311:113;;;2442:6;2439:1;2436:13;2433:101;;;2522:1;2513:6;2508:3;2504:16;2497:27;2433:101;2282:258;2233:307;;;:::o;2546:102::-;2587:6;2638:2;2634:7;2629:2;2622:5;2618:14;2614:28;2604:38;;2546:102;;;:::o;2654:364::-;2742:3;2770:39;2803:5;2770:39;:::i;:::-;2825:71;2889:6;2884:3;2825:71;:::i;:::-;2818:78;;2905:52;2950:6;2945:3;2938:4;2931:5;2927:16;2905:52;:::i;:::-;2982:29;3004:6;2982:29;:::i;:::-;2977:3;2973:39;2966:46;;2746:272;2654:364;;;;:::o;3024:313::-;3137:4;3175:2;3164:9;3160:18;3152:26;;3224:9;3218:4;3214:20;3210:1;3199:9;3195:17;3188:47;3252:78;3325:4;3316:6;3252:78;:::i;:::-;3244:86;;3024:313;;;;:::o;3343:122::-;3416:24;3434:5;3416:24;:::i;:::-;3409:5;3406:35;3396:63;;3455:1;3452;3445:12;3396:63;3343:122;:::o;3471:139::-;3517:5;3555:6;3542:20;3533:29;;3571:33;3598:5;3571:33;:::i;:::-;3471:139;;;;:::o;3616:329::-;3675:6;3724:2;3712:9;3703:7;3699:23;3695:32;3692:119;;;3730:79;;:::i;:::-;3692:119;3850:1;3875:53;3920:7;3911:6;3900:9;3896:22;3875:53;:::i;:::-;3865:63;;3821:117;3616:329;;;;:::o;3951:126::-;3988:7;4028:42;4021:5;4017:54;4006:65;;3951:126;;;:::o;4083:96::-;4120:7;4149:24;4167:5;4149:24;:::i;:::-;4138:35;;4083:96;;;:::o;4185:118::-;4272:24;4290:5;4272:24;:::i;:::-;4267:3;4260:37;4185:118;;:::o;4309:222::-;4402:4;4440:2;4429:9;4425:18;4417:26;;4453:71;4521:1;4510:9;4506:17;4497:6;4453:71;:::i;:::-;4309:222;;;;:::o;4537:122::-;4610:24;4628:5;4610:24;:::i;:::-;4603:5;4600:35;4590:63;;4649:1;4646;4639:12;4590:63;4537:122;:::o;4665:139::-;4711:5;4749:6;4736:20;4727:29;;4765:33;4792:5;4765:33;:::i;:::-;4665:139;;;;:::o;4810:474::-;4878:6;4886;4935:2;4923:9;4914:7;4910:23;4906:32;4903:119;;;4941:79;;:::i;:::-;4903:119;5061:1;5086:53;5131:7;5122:6;5111:9;5107:22;5086:53;:::i;:::-;5076:63;;5032:117;5188:2;5214:53;5259:7;5250:6;5239:9;5235:22;5214:53;:::i;:::-;5204:63;;5159:118;4810:474;;;;;:::o;5290:329::-;5349:6;5398:2;5386:9;5377:7;5373:23;5369:32;5366:119;;;5404:79;;:::i;:::-;5366:119;5524:1;5549:53;5594:7;5585:6;5574:9;5570:22;5549:53;:::i;:::-;5539:63;;5495:117;5290:329;;;;:::o;5625:619::-;5702:6;5710;5718;5767:2;5755:9;5746:7;5742:23;5738:32;5735:119;;;5773:79;;:::i;:::-;5735:119;5893:1;5918:53;5963:7;5954:6;5943:9;5939:22;5918:53;:::i;:::-;5908:63;;5864:117;6020:2;6046:53;6091:7;6082:6;6071:9;6067:22;6046:53;:::i;:::-;6036:63;;5991:118;6148:2;6174:53;6219:7;6210:6;6199:9;6195:22;6174:53;:::i;:::-;6164:63;;6119:118;5625:619;;;;;:::o;6250:77::-;6287:7;6316:5;6305:16;;6250:77;;;:::o;6333:118::-;6420:24;6438:5;6420:24;:::i;:::-;6415:3;6408:37;6333:118;;:::o;6457:222::-;6550:4;6588:2;6577:9;6573:18;6565:26;;6601:71;6669:1;6658:9;6654:17;6645:6;6601:71;:::i;:::-;6457:222;;;;:::o;6685:117::-;6794:1;6791;6784:12;6808:117;6917:1;6914;6907:12;6931:117;7040:1;7037;7030:12;7068:553;7126:8;7136:6;7186:3;7179:4;7171:6;7167:17;7163:27;7153:122;;7194:79;;:::i;:::-;7153:122;7307:6;7294:20;7284:30;;7337:18;7329:6;7326:30;7323:117;;;7359:79;;:::i;:::-;7323:117;7473:4;7465:6;7461:17;7449:29;;7527:3;7519:4;7511:6;7507:17;7497:8;7493:32;7490:41;7487:128;;;7534:79;;:::i;:::-;7487:128;7068:553;;;;;:::o;7627:529::-;7698:6;7706;7755:2;7743:9;7734:7;7730:23;7726:32;7723:119;;;7761:79;;:::i;:::-;7723:119;7909:1;7898:9;7894:17;7881:31;7939:18;7931:6;7928:30;7925:117;;;7961:79;;:::i;:::-;7925:117;8074:65;8131:7;8122:6;8111:9;8107:22;8074:65;:::i;:::-;8056:83;;;;7852:297;7627:529;;;;;:::o;8179:568::-;8252:8;8262:6;8312:3;8305:4;8297:6;8293:17;8289:27;8279:122;;8320:79;;:::i;:::-;8279:122;8433:6;8420:20;8410:30;;8463:18;8455:6;8452:30;8449:117;;;8485:79;;:::i;:::-;8449:117;8599:4;8591:6;8587:17;8575:29;;8653:3;8645:4;8637:6;8633:17;8623:8;8619:32;8616:41;8613:128;;;8660:79;;:::i;:::-;8613:128;8179:568;;;;;:::o;8753:559::-;8839:6;8847;8896:2;8884:9;8875:7;8871:23;8867:32;8864:119;;;8902:79;;:::i;:::-;8864:119;9050:1;9039:9;9035:17;9022:31;9080:18;9072:6;9069:30;9066:117;;;9102:79;;:::i;:::-;9066:117;9215:80;9287:7;9278:6;9267:9;9263:22;9215:80;:::i;:::-;9197:98;;;;8993:312;8753:559;;;;;:::o;9318:145::-;9416:6;9450:5;9444:12;9434:22;;9318:145;;;:::o;9469:215::-;9599:11;9633:6;9628:3;9621:19;9673:4;9668:3;9664:14;9649:29;;9469:215;;;;:::o;9690:163::-;9788:4;9811:3;9803:11;;9841:4;9836:3;9832:14;9824:22;;9690:163;;;:::o;9859:108::-;9936:24;9954:5;9936:24;:::i;:::-;9931:3;9924:37;9859:108;;:::o;9973:101::-;10009:7;10049:18;10042:5;10038:30;10027:41;;9973:101;;;:::o;10080:105::-;10155:23;10172:5;10155:23;:::i;:::-;10150:3;10143:36;10080:105;;:::o;10191:99::-;10262:21;10277:5;10262:21;:::i;:::-;10257:3;10250:34;10191:99;;:::o;10296:91::-;10332:7;10372:8;10365:5;10361:20;10350:31;;10296:91;;;:::o;10393:105::-;10468:23;10485:5;10468:23;:::i;:::-;10463:3;10456:36;10393:105;;:::o;10576:864::-;10725:4;10720:3;10716:14;10812:4;10805:5;10801:16;10795:23;10831:63;10888:4;10883:3;10879:14;10865:12;10831:63;:::i;:::-;10740:164;10996:4;10989:5;10985:16;10979:23;11015:61;11070:4;11065:3;11061:14;11047:12;11015:61;:::i;:::-;10914:172;11170:4;11163:5;11159:16;11153:23;11189:57;11240:4;11235:3;11231:14;11217:12;11189:57;:::i;:::-;11096:160;11343:4;11336:5;11332:16;11326:23;11362:61;11417:4;11412:3;11408:14;11394:12;11362:61;:::i;:::-;11266:167;10694:746;10576:864;;:::o;11446:303::-;11577:10;11598:108;11702:3;11694:6;11598:108;:::i;:::-;11738:4;11733:3;11729:14;11715:28;;11446:303;;;;:::o;11755:144::-;11856:4;11888;11883:3;11879:14;11871:22;;11755:144;;;:::o;11981:980::-;12162:3;12191:85;12270:5;12191:85;:::i;:::-;12292:117;12402:6;12397:3;12292:117;:::i;:::-;12285:124;;12433:87;12514:5;12433:87;:::i;:::-;12543:7;12574:1;12559:377;12584:6;12581:1;12578:13;12559:377;;;12660:6;12654:13;12687:125;12808:3;12793:13;12687:125;:::i;:::-;12680:132;;12835:91;12919:6;12835:91;:::i;:::-;12825:101;;12619:317;12606:1;12603;12599:9;12594:14;;12559:377;;;12563:14;12952:3;12945:10;;12167:794;;;11981:980;;;;:::o;12967:497::-;13172:4;13210:2;13199:9;13195:18;13187:26;;13259:9;13253:4;13249:20;13245:1;13234:9;13230:17;13223:47;13287:170;13452:4;13443:6;13287:170;:::i;:::-;13279:178;;12967:497;;;;:::o;13487:568::-;13560:8;13570:6;13620:3;13613:4;13605:6;13601:17;13597:27;13587:122;;13628:79;;:::i;:::-;13587:122;13741:6;13728:20;13718:30;;13771:18;13763:6;13760:30;13757:117;;;13793:79;;:::i;:::-;13757:117;13907:4;13899:6;13895:17;13883:29;;13961:3;13953:4;13945:6;13941:17;13931:8;13927:32;13924:41;13921:128;;;13968:79;;:::i;:::-;13921:128;13487:568;;;;;:::o;14061:704::-;14156:6;14164;14172;14221:2;14209:9;14200:7;14196:23;14192:32;14189:119;;;14227:79;;:::i;:::-;14189:119;14347:1;14372:53;14417:7;14408:6;14397:9;14393:22;14372:53;:::i;:::-;14362:63;;14318:117;14502:2;14491:9;14487:18;14474:32;14533:18;14525:6;14522:30;14519:117;;;14555:79;;:::i;:::-;14519:117;14668:80;14740:7;14731:6;14720:9;14716:22;14668:80;:::i;:::-;14650:98;;;;14445:313;14061:704;;;;;:::o;14771:114::-;14838:6;14872:5;14866:12;14856:22;;14771:114;;;:::o;14891:184::-;14990:11;15024:6;15019:3;15012:19;15064:4;15059:3;15055:14;15040:29;;14891:184;;;;:::o;15081:132::-;15148:4;15171:3;15163:11;;15201:4;15196:3;15192:14;15184:22;;15081:132;;;:::o;15219:108::-;15296:24;15314:5;15296:24;:::i;:::-;15291:3;15284:37;15219:108;;:::o;15333:179::-;15402:10;15423:46;15465:3;15457:6;15423:46;:::i;:::-;15501:4;15496:3;15492:14;15478:28;;15333:179;;;;:::o;15518:113::-;15588:4;15620;15615:3;15611:14;15603:22;;15518:113;;;:::o;15667:732::-;15786:3;15815:54;15863:5;15815:54;:::i;:::-;15885:86;15964:6;15959:3;15885:86;:::i;:::-;15878:93;;15995:56;16045:5;15995:56;:::i;:::-;16074:7;16105:1;16090:284;16115:6;16112:1;16109:13;16090:284;;;16191:6;16185:13;16218:63;16277:3;16262:13;16218:63;:::i;:::-;16211:70;;16304:60;16357:6;16304:60;:::i;:::-;16294:70;;16150:224;16137:1;16134;16130:9;16125:14;;16090:284;;;16094:14;16390:3;16383:10;;15791:608;;;15667:732;;;;:::o;16405:373::-;16548:4;16586:2;16575:9;16571:18;16563:26;;16635:9;16629:4;16625:20;16621:1;16610:9;16606:17;16599:47;16663:108;16766:4;16757:6;16663:108;:::i;:::-;16655:116;;16405:373;;;;:::o;16784:704::-;16879:6;16887;16895;16944:2;16932:9;16923:7;16919:23;16915:32;16912:119;;;16950:79;;:::i;:::-;16912:119;17098:1;17087:9;17083:17;17070:31;17128:18;17120:6;17117:30;17114:117;;;17150:79;;:::i;:::-;17114:117;17263:80;17335:7;17326:6;17315:9;17311:22;17263:80;:::i;:::-;17245:98;;;;17041:312;17392:2;17418:53;17463:7;17454:6;17443:9;17439:22;17418:53;:::i;:::-;17408:63;;17363:118;16784:704;;;;;:::o;17494:619::-;17571:6;17579;17587;17636:2;17624:9;17615:7;17611:23;17607:32;17604:119;;;17642:79;;:::i;:::-;17604:119;17762:1;17787:53;17832:7;17823:6;17812:9;17808:22;17787:53;:::i;:::-;17777:63;;17733:117;17889:2;17915:53;17960:7;17951:6;17940:9;17936:22;17915:53;:::i;:::-;17905:63;;17860:118;18017:2;18043:53;18088:7;18079:6;18068:9;18064:22;18043:53;:::i;:::-;18033:63;;17988:118;17494:619;;;;;:::o;18119:116::-;18189:21;18204:5;18189:21;:::i;:::-;18182:5;18179:32;18169:60;;18225:1;18222;18215:12;18169:60;18119:116;:::o;18241:133::-;18284:5;18322:6;18309:20;18300:29;;18338:30;18362:5;18338:30;:::i;:::-;18241:133;;;;:::o;18380:468::-;18445:6;18453;18502:2;18490:9;18481:7;18477:23;18473:32;18470:119;;;18508:79;;:::i;:::-;18470:119;18628:1;18653:53;18698:7;18689:6;18678:9;18674:22;18653:53;:::i;:::-;18643:63;;18599:117;18755:2;18781:50;18823:7;18814:6;18803:9;18799:22;18781:50;:::i;:::-;18771:60;;18726:115;18380:468;;;;;:::o;18854:117::-;18963:1;18960;18953:12;18977:180;19025:77;19022:1;19015:88;19122:4;19119:1;19112:15;19146:4;19143:1;19136:15;19163:281;19246:27;19268:4;19246:27;:::i;:::-;19238:6;19234:40;19376:6;19364:10;19361:22;19340:18;19328:10;19325:34;19322:62;19319:88;;;19387:18;;:::i;:::-;19319:88;19427:10;19423:2;19416:22;19206:238;19163:281;;:::o;19450:129::-;19484:6;19511:20;;:::i;:::-;19501:30;;19540:33;19568:4;19560:6;19540:33;:::i;:::-;19450:129;;;:::o;19585:307::-;19646:4;19736:18;19728:6;19725:30;19722:56;;;19758:18;;:::i;:::-;19722:56;19796:29;19818:6;19796:29;:::i;:::-;19788:37;;19880:4;19874;19870:15;19862:23;;19585:307;;;:::o;19898:154::-;19982:6;19977:3;19972;19959:30;20044:1;20035:6;20030:3;20026:16;20019:27;19898:154;;;:::o;20058:410::-;20135:5;20160:65;20176:48;20217:6;20176:48;:::i;:::-;20160:65;:::i;:::-;20151:74;;20248:6;20241:5;20234:21;20286:4;20279:5;20275:16;20324:3;20315:6;20310:3;20306:16;20303:25;20300:112;;;20331:79;;:::i;:::-;20300:112;20421:41;20455:6;20450:3;20445;20421:41;:::i;:::-;20141:327;20058:410;;;;;:::o;20487:338::-;20542:5;20591:3;20584:4;20576:6;20572:17;20568:27;20558:122;;20599:79;;:::i;:::-;20558:122;20716:6;20703:20;20741:78;20815:3;20807:6;20800:4;20792:6;20788:17;20741:78;:::i;:::-;20732:87;;20548:277;20487:338;;;;:::o;20831:943::-;20926:6;20934;20942;20950;20999:3;20987:9;20978:7;20974:23;20970:33;20967:120;;;21006:79;;:::i;:::-;20967:120;21126:1;21151:53;21196:7;21187:6;21176:9;21172:22;21151:53;:::i;:::-;21141:63;;21097:117;21253:2;21279:53;21324:7;21315:6;21304:9;21300:22;21279:53;:::i;:::-;21269:63;;21224:118;21381:2;21407:53;21452:7;21443:6;21432:9;21428:22;21407:53;:::i;:::-;21397:63;;21352:118;21537:2;21526:9;21522:18;21509:32;21568:18;21560:6;21557:30;21554:117;;;21590:79;;:::i;:::-;21554:117;21695:62;21749:7;21740:6;21729:9;21725:22;21695:62;:::i;:::-;21685:72;;21480:287;20831:943;;;;;;;:::o;21852:874::-;22011:4;22006:3;22002:14;22098:4;22091:5;22087:16;22081:23;22117:63;22174:4;22169:3;22165:14;22151:12;22117:63;:::i;:::-;22026:164;22282:4;22275:5;22271:16;22265:23;22301:61;22356:4;22351:3;22347:14;22333:12;22301:61;:::i;:::-;22200:172;22456:4;22449:5;22445:16;22439:23;22475:57;22526:4;22521:3;22517:14;22503:12;22475:57;:::i;:::-;22382:160;22629:4;22622:5;22618:16;22612:23;22648:61;22703:4;22698:3;22694:14;22680:12;22648:61;:::i;:::-;22552:167;21980:746;21852:874;;:::o;22732:347::-;22887:4;22925:3;22914:9;22910:19;22902:27;;22939:133;23069:1;23058:9;23054:17;23045:6;22939:133;:::i;:::-;22732:347;;;;:::o;23085:474::-;23153:6;23161;23210:2;23198:9;23189:7;23185:23;23181:32;23178:119;;;23216:79;;:::i;:::-;23178:119;23336:1;23361:53;23406:7;23397:6;23386:9;23382:22;23361:53;:::i;:::-;23351:63;;23307:117;23463:2;23489:53;23534:7;23525:6;23514:9;23510:22;23489:53;:::i;:::-;23479:63;;23434:118;23085:474;;;;;:::o;23565:162::-;23705:14;23701:1;23693:6;23689:14;23682:38;23565:162;:::o;23733:366::-;23875:3;23896:67;23960:2;23955:3;23896:67;:::i;:::-;23889:74;;23972:93;24061:3;23972:93;:::i;:::-;24090:2;24085:3;24081:12;24074:19;;23733:366;;;:::o;24105:419::-;24271:4;24309:2;24298:9;24294:18;24286:26;;24358:9;24352:4;24348:20;24344:1;24333:9;24329:17;24322:47;24386:131;24512:4;24386:131;:::i;:::-;24378:139;;24105:419;;;:::o;24530:164::-;24670:16;24666:1;24658:6;24654:14;24647:40;24530:164;:::o;24700:366::-;24842:3;24863:67;24927:2;24922:3;24863:67;:::i;:::-;24856:74;;24939:93;25028:3;24939:93;:::i;:::-;25057:2;25052:3;25048:12;25041:19;;24700:366;;;:::o;25072:419::-;25238:4;25276:2;25265:9;25261:18;25253:26;;25325:9;25319:4;25315:20;25311:1;25300:9;25296:17;25289:47;25353:131;25479:4;25353:131;:::i;:::-;25345:139;;25072:419;;;:::o;25497:180::-;25545:77;25542:1;25535:88;25642:4;25639:1;25632:15;25666:4;25663:1;25656:15;25683:320;25727:6;25764:1;25758:4;25754:12;25744:22;;25811:1;25805:4;25801:12;25832:18;25822:81;;25888:4;25880:6;25876:17;25866:27;;25822:81;25950:2;25942:6;25939:14;25919:18;25916:38;25913:84;;25969:18;;:::i;:::-;25913:84;25734:269;25683:320;;;:::o;26009:332::-;26130:4;26168:2;26157:9;26153:18;26145:26;;26181:71;26249:1;26238:9;26234:17;26225:6;26181:71;:::i;:::-;26262:72;26330:2;26319:9;26315:18;26306:6;26262:72;:::i;:::-;26009:332;;;;;:::o;26347:137::-;26401:5;26432:6;26426:13;26417:22;;26448:30;26472:5;26448:30;:::i;:::-;26347:137;;;;:::o;26490:345::-;26557:6;26606:2;26594:9;26585:7;26581:23;26577:32;26574:119;;;26612:79;;:::i;:::-;26574:119;26732:1;26757:61;26810:7;26801:6;26790:9;26786:22;26757:61;:::i;:::-;26747:71;;26703:125;26490:345;;;;:::o;26841:162::-;26981:14;26977:1;26969:6;26965:14;26958:38;26841:162;:::o;27009:366::-;27151:3;27172:67;27236:2;27231:3;27172:67;:::i;:::-;27165:74;;27248:93;27337:3;27248:93;:::i;:::-;27366:2;27361:3;27357:12;27350:19;;27009:366;;;:::o;27381:419::-;27547:4;27585:2;27574:9;27570:18;27562:26;;27634:9;27628:4;27624:20;27620:1;27609:9;27605:17;27598:47;27662:131;27788:4;27662:131;:::i;:::-;27654:139;;27381:419;;;:::o;27806:180::-;27854:77;27851:1;27844:88;27951:4;27948:1;27941:15;27975:4;27972:1;27965:15;27992:164;28132:16;28128:1;28120:6;28116:14;28109:40;27992:164;:::o;28162:366::-;28304:3;28325:67;28389:2;28384:3;28325:67;:::i;:::-;28318:74;;28401:93;28490:3;28401:93;:::i;:::-;28519:2;28514:3;28510:12;28503:19;;28162:366;;;:::o;28534:419::-;28700:4;28738:2;28727:9;28723:18;28715:26;;28787:9;28781:4;28777:20;28773:1;28762:9;28758:17;28751:47;28815:131;28941:4;28815:131;:::i;:::-;28807:139;;28534:419;;;:::o;28959:164::-;29099:16;29095:1;29087:6;29083:14;29076:40;28959:164;:::o;29129:366::-;29271:3;29292:67;29356:2;29351:3;29292:67;:::i;:::-;29285:74;;29368:93;29457:3;29368:93;:::i;:::-;29486:2;29481:3;29477:12;29470:19;;29129:366;;;:::o;29501:419::-;29667:4;29705:2;29694:9;29690:18;29682:26;;29754:9;29748:4;29744:20;29740:1;29729:9;29725:17;29718:47;29782:131;29908:4;29782:131;:::i;:::-;29774:139;;29501:419;;;:::o;29926:181::-;30066:33;30062:1;30054:6;30050:14;30043:57;29926:181;:::o;30113:366::-;30255:3;30276:67;30340:2;30335:3;30276:67;:::i;:::-;30269:74;;30352:93;30441:3;30352:93;:::i;:::-;30470:2;30465:3;30461:12;30454:19;;30113:366;;;:::o;30485:419::-;30651:4;30689:2;30678:9;30674:18;30666:26;;30738:9;30732:4;30728:20;30724:1;30713:9;30709:17;30702:47;30766:131;30892:4;30766:131;:::i;:::-;30758:139;;30485:419;;;:::o;30910:169::-;31050:21;31046:1;31038:6;31034:14;31027:45;30910:169;:::o;31085:366::-;31227:3;31248:67;31312:2;31307:3;31248:67;:::i;:::-;31241:74;;31324:93;31413:3;31324:93;:::i;:::-;31442:2;31437:3;31433:12;31426:19;;31085:366;;;:::o;31457:419::-;31623:4;31661:2;31650:9;31646:18;31638:26;;31710:9;31704:4;31700:20;31696:1;31685:9;31681:17;31674:47;31738:131;31864:4;31738:131;:::i;:::-;31730:139;;31457:419;;;:::o;31882:168::-;32022:20;32018:1;32010:6;32006:14;31999:44;31882:168;:::o;32056:366::-;32198:3;32219:67;32283:2;32278:3;32219:67;:::i;:::-;32212:74;;32295:93;32384:3;32295:93;:::i;:::-;32413:2;32408:3;32404:12;32397:19;;32056:366;;;:::o;32428:419::-;32594:4;32632:2;32621:9;32617:18;32609:26;;32681:9;32675:4;32671:20;32667:1;32656:9;32652:17;32645:47;32709:131;32835:4;32709:131;:::i;:::-;32701:139;;32428:419;;;:::o;32853:170::-;32993:22;32989:1;32981:6;32977:14;32970:46;32853:170;:::o;33029:366::-;33171:3;33192:67;33256:2;33251:3;33192:67;:::i;:::-;33185:74;;33268:93;33357:3;33268:93;:::i;:::-;33386:2;33381:3;33377:12;33370:19;;33029:366;;;:::o;33401:419::-;33567:4;33605:2;33594:9;33590:18;33582:26;;33654:9;33648:4;33644:20;33640:1;33629:9;33625:17;33618:47;33682:131;33808:4;33682:131;:::i;:::-;33674:139;;33401:419;;;:::o;33826:94::-;33859:8;33907:5;33903:2;33899:14;33878:35;;33826:94;;;:::o;33926:::-;33965:7;33994:20;34008:5;33994:20;:::i;:::-;33983:31;;33926:94;;;:::o;34026:100::-;34065:7;34094:26;34114:5;34094:26;:::i;:::-;34083:37;;34026:100;;;:::o;34132:157::-;34237:45;34257:24;34275:5;34257:24;:::i;:::-;34237:45;:::i;:::-;34232:3;34225:58;34132:157;;:::o;34295:79::-;34334:7;34363:5;34352:16;;34295:79;;;:::o;34380:157::-;34485:45;34505:24;34523:5;34505:24;:::i;:::-;34485:45;:::i;:::-;34480:3;34473:58;34380:157;;:::o;34543:397::-;34683:3;34698:75;34769:3;34760:6;34698:75;:::i;:::-;34798:2;34793:3;34789:12;34782:19;;34811:75;34882:3;34873:6;34811:75;:::i;:::-;34911:2;34906:3;34902:12;34895:19;;34931:3;34924:10;;34543:397;;;;;:::o;34946:148::-;35048:11;35085:3;35070:18;;34946:148;;;;:::o;35100:377::-;35206:3;35234:39;35267:5;35234:39;:::i;:::-;35289:89;35371:6;35366:3;35289:89;:::i;:::-;35282:96;;35387:52;35432:6;35427:3;35420:4;35413:5;35409:16;35387:52;:::i;:::-;35464:6;35459:3;35455:16;35448:23;;35210:267;35100:377;;;;:::o;35483:435::-;35663:3;35685:95;35776:3;35767:6;35685:95;:::i;:::-;35678:102;;35797:95;35888:3;35879:6;35797:95;:::i;:::-;35790:102;;35909:3;35902:10;;35483:435;;;;;:::o;35924:180::-;35972:77;35969:1;35962:88;36069:4;36066:1;36059:15;36093:4;36090:1;36083:15;36110:233;36149:3;36172:24;36190:5;36172:24;:::i;:::-;36163:33;;36218:66;36211:5;36208:77;36205:103;;36288:18;;:::i;:::-;36205:103;36335:1;36328:5;36324:13;36317:20;;36110:233;;;:::o;36349:98::-;36400:6;36434:5;36428:12;36418:22;;36349:98;;;:::o;36453:168::-;36536:11;36570:6;36565:3;36558:19;36610:4;36605:3;36601:14;36586:29;;36453:168;;;;:::o;36627:360::-;36713:3;36741:38;36773:5;36741:38;:::i;:::-;36795:70;36858:6;36853:3;36795:70;:::i;:::-;36788:77;;36874:52;36919:6;36914:3;36907:4;36900:5;36896:16;36874:52;:::i;:::-;36951:29;36973:6;36951:29;:::i;:::-;36946:3;36942:39;36935:46;;36717:270;36627:360;;;;:::o;36993:640::-;37188:4;37226:3;37215:9;37211:19;37203:27;;37240:71;37308:1;37297:9;37293:17;37284:6;37240:71;:::i;:::-;37321:72;37389:2;37378:9;37374:18;37365:6;37321:72;:::i;:::-;37403;37471:2;37460:9;37456:18;37447:6;37403:72;:::i;:::-;37522:9;37516:4;37512:20;37507:2;37496:9;37492:18;37485:48;37550:76;37621:4;37612:6;37550:76;:::i;:::-;37542:84;;36993:640;;;;;;;:::o;37639:141::-;37695:5;37726:6;37720:13;37711:22;;37742:32;37768:5;37742:32;:::i;:::-;37639:141;;;;:::o;37786:349::-;37855:6;37904:2;37892:9;37883:7;37879:23;37875:32;37872:119;;;37910:79;;:::i;:::-;37872:119;38030:1;38055:63;38110:7;38101:6;38090:9;38086:22;38055:63;:::i;:::-;38045:73;;38001:127;37786:349;;;;:::o
Swarm Source
ipfs://5fa18252be9c00bebf740c7643df3691b882bb18c8e3afd3a4c0b5c7eb1965a6
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.