Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
998 TNK
Holders
420
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
2 TNKLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
NorthKoreanNFT
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-07-20 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * 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. */ 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 proved to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * _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} * * _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 the sibling nodes in `proof`, * consuming from one or the other at each step according to the instructions given by * `proofFlags`. * * _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} * * _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: contracts/NortKoreanNFT.sol // File @openzeppelin/contracts/utils/[email protected] pragma solidity ^0.8.0; library Address { function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } 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"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/utils/[email protected] pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @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); } } // File @openzeppelin/contracts/utils/[email protected] pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File @openzeppelin/contracts/utils/introspection/[email protected] 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 @openzeppelin/contracts/token/ERC721/[email protected] 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`, 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 ) 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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; } // File @openzeppelin/contracts/token/ERC721/[email protected] 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 `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] 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 @openzeppelin/contracts/utils/introspection/[email protected] 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 @openzeppelin/contracts/token/ERC721/[email protected] 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: balance query for the zero address"); 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: owner query for nonexistent token"); 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) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); 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 overriden 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 owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_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: transfer caller is not owner nor 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: transfer caller is not owner nor 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) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, 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); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(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 of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @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 { 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 {} } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @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` cannot be the zero address. * - `to` cannot be the zero address. * * 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 override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata and Enumerable extension. Built to optimize for lower gas during batch mints. * * Assumes serials are sequentially minted starting at 0 (e.g. 0, 1, 2, 3..). * * Does not support burning tokens to address(0). */ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using Address for address; using Strings for uint256; struct TokenOwnership { address addr; uint64 startTimestamp; } struct AddressData { uint128 balance; uint128 numberMinted; } uint256 private currentIndex = 0; uint256 internal immutable maxBatchSize; // 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 ownershipOf implementation for details. mapping(uint256 => TokenOwnership) private _ownerships; // Mapping owner address to address data mapping(address => AddressData) private _addressData; // 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 * `maxBatchSize` refers to how much a minter can mint at a time. */ constructor( string memory name_, string memory symbol_, uint256 maxBatchSize_ ) { require(maxBatchSize_ > 0, "ERC721A: max batch size must be nonzero"); _name = name_; _symbol = symbol_; maxBatchSize = maxBatchSize_; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view override returns (uint256) { return currentIndex; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view override returns (uint256) { require(index < totalSupply(), "ERC721A: global index out of bounds"); return index; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. * This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first. * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) { require(index < balanceOf(owner), "ERC721A: owner index out of bounds"); uint256 numMintedSoFar = totalSupply(); uint256 tokenIdsIdx = 0; address currOwnershipAddr = address(0); for (uint256 i = 0; i < numMintedSoFar; i++) { TokenOwnership memory ownership = _ownerships[i]; if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { if (tokenIdsIdx == index) { return i; } tokenIdsIdx++; } } revert("ERC721A: unable to get token of owner by index"); } /** * @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 || interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view override returns (uint256) { require(owner != address(0), "ERC721A: balance query for the zero address"); return uint256(_addressData[owner].balance); } function _numberMinted(address owner) internal view returns (uint256) { require(owner != address(0), "ERC721A: number minted query for the zero address"); return uint256(_addressData[owner].numberMinted); } function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { require(_exists(tokenId), "ERC721A: owner query for nonexistent token"); uint256 lowestTokenToCheck; if (tokenId >= maxBatchSize) { lowestTokenToCheck = tokenId - maxBatchSize + 1; } for (uint256 curr = tokenId; curr >= lowestTokenToCheck; curr--) { TokenOwnership memory ownership = _ownerships[curr]; if (ownership.addr != address(0)) { return ownership; } } revert("ERC721A: unable to determine the owner of token"); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return ownershipOf(tokenId).addr; } /** * @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) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); 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 overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public override { address owner = ERC721A.ownerOf(tokenId); require(to != owner, "ERC721A: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721A: approve caller is not owner nor approved for all" ); _approve(to, tokenId, owner); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { require(_exists(tokenId), "ERC721A: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public override { require(operator != _msgSender(), "ERC721A: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_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 override { _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public override { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, _data), "ERC721A: 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`), */ function _exists(uint256 tokenId) internal view returns (bool) { return tokenId < currentIndex; } function _safeMint(address to, uint256 quantity) internal { _safeMint(to, quantity, ""); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` cannot be larger than the max batch size. * * Emits a {Transfer} event. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal { uint256 startTokenId = currentIndex; require(to != address(0), "ERC721A: mint to the zero address"); // We know if the first token in the batch doesn't exist, the other ones don't as well, because of serial ordering. require(!_exists(startTokenId), "ERC721A: token already minted"); require(quantity <= maxBatchSize, "ERC721A: quantity to mint too high"); _beforeTokenTransfers(address(0), to, startTokenId, quantity); AddressData memory addressData = _addressData[to]; _addressData[to] = AddressData( addressData.balance + uint128(quantity), addressData.numberMinted + uint128(quantity) ); _ownerships[startTokenId] = TokenOwnership(to, uint64(block.timestamp)); uint256 updatedIndex = startTokenId; for (uint256 i = 0; i < quantity; i++) { emit Transfer(address(0), to, updatedIndex); require( _checkOnERC721Received(address(0), to, updatedIndex, _data), "ERC721A: transfer to non ERC721Receiver implementer" ); updatedIndex++; } currentIndex = updatedIndex; _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) private { TokenOwnership memory prevOwnership = ownershipOf(tokenId); bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr || getApproved(tokenId) == _msgSender() || isApprovedForAll(prevOwnership.addr, _msgSender())); require(isApprovedOrOwner, "ERC721A: transfer caller is not owner nor approved"); require(prevOwnership.addr == from, "ERC721A: transfer from incorrect owner"); require(to != address(0), "ERC721A: transfer to the zero address"); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner _approve(address(0), tokenId, prevOwnership.addr); _addressData[from].balance -= 1; _addressData[to].balance += 1; _ownerships[tokenId] = TokenOwnership(to, uint64(block.timestamp)); // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it. // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls. uint256 nextTokenId = tokenId + 1; if (_ownerships[nextTokenId].addr == address(0)) { if (_exists(nextTokenId)) { _ownerships[nextTokenId] = TokenOwnership(prevOwnership.addr, prevOwnership.startTimestamp); } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve( address to, uint256 tokenId, address owner ) private { _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } uint256 public nextOwnerToExplicitlySet = 0; /** * @dev Explicitly set `owners` to eliminate loops in future calls of ownerOf(). */ function _setOwnersExplicit(uint256 quantity) internal { uint256 oldNextOwnerToSet = nextOwnerToExplicitlySet; require(quantity > 0, "quantity must be nonzero"); uint256 endIndex = oldNextOwnerToSet + quantity - 1; if (endIndex > currentIndex - 1) { endIndex = currentIndex - 1; } // We know if the last one in the group exists, all in the group exist, due to serial ordering. require(_exists(endIndex), "not enough minted yet for this cleanup"); for (uint256 i = oldNextOwnerToSet; i <= endIndex; i++) { if (_ownerships[i].addr == address(0)) { TokenOwnership memory ownership = ownershipOf(i); _ownerships[i] = TokenOwnership(ownership.addr, ownership.startTimestamp); } } nextOwnerToExplicitlySet = endIndex + 1; } /** * @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(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721A: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting. * * 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`. */ 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. * * 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` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} } pragma solidity ^0.8.0; contract NorthKoreanNFT is ERC721A, Ownable { using Strings for uint256; address public withdrawl_address = 0x6896504e8a6cD20f49D25Ff3C2C6f7352C42990a; string public baseURI; string public unrevealedURI; uint256 public tier1_limit; uint256 public tier1_price; uint256 public tier2_price; uint256 public maxSupply; uint256 public maxMintAmount = 2; uint256 public maxMintPerTransaction = 2; uint256 public ownerReserved; bool public saleOpen = true; bool public revealed = true; bool public whitelistOnly = false; bytes32 MerkleRoot; mapping(address => uint256) private mintCount; modifier mintIsLive() { require(saleOpen, "mint not live"); _; } constructor() ERC721A("The North Korean NFT", "TNK", maxMintAmount) { maxSupply = 6666; ownerReserved = 666; tier1_limit = 2000; tier1_price = 0.25 ether; tier2_price; } function mintedByAddressCount(address _address) public view returns (uint256){ return mintCount[_address]; } function setWhitelistOnly(bool _whitelistStatus) external onlyOwner{ whitelistOnly = _whitelistStatus; } function setTier1Limit(uint256 _tier1_limit) public onlyOwner { tier1_limit = _tier1_limit; } function setTier1Price(uint256 _tier1_price) public onlyOwner { tier1_price = _tier1_price; } function setTier2Price(uint256 _tier2_price) public onlyOwner { tier2_price = _tier2_price; } function getCost() public view returns(uint256){ if(totalSupply() <= tier1_limit){ return tier1_price; } else { return tier2_price; } } // Minting functions function mint(uint256 _mintAmount) external payable mintIsLive { require(whitelistOnly == false,"Whitelisted only allowed"); address _to = msg.sender; uint256 minted = mintCount[_to]; require(minted + _mintAmount <= maxMintAmount, "mint over max"); require(_mintAmount <= maxMintPerTransaction, "amount must < max"); require(totalSupply() + _mintAmount <= (maxSupply - ownerReserved), "mint over supply"); uint256 price = getCost(); require(msg.value >= price * _mintAmount, "insufficient funds"); mintCount[_to] = minted + _mintAmount; _safeMint(msg.sender, _mintAmount); } // Minting functions function whitelistMint(uint256 _mintAmount, bytes32[] calldata _merkleProof) external payable mintIsLive { require(whitelistOnly == true,"Whitelisted only allowed"); bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); require(MerkleProof.verify(_merkleProof, MerkleRoot, leaf), "Incorrect proof"); address _to = msg.sender; uint256 minted = mintCount[_to]; require(minted + _mintAmount <= maxMintAmount, "mint over max"); require(_mintAmount <= maxMintPerTransaction, "amount must < max"); require(totalSupply() + _mintAmount <= (maxSupply - ownerReserved), "mint over supply"); uint256 price = getCost(); require(msg.value >= price * _mintAmount, "insufficient funds"); mintCount[_to] = minted + _mintAmount; _safeMint(msg.sender, _mintAmount); } function setMerkleRoot(bytes32 _MerkleRoot) external onlyOwner { MerkleRoot = _MerkleRoot; } // Only Owner executable functions function claimReserved(address _to, uint256 _mintAmount) external onlyOwner { require((ownerReserved - _mintAmount) > 0, "over owner reserved supply"); require(totalSupply() + _mintAmount <= maxSupply, "mint over supply"); if (_mintAmount <= maxBatchSize) { _safeMint(_to, _mintAmount); return; } uint256 leftToMint = _mintAmount; while (leftToMint > 0) { if (leftToMint <= maxBatchSize) { _safeMint(_to, leftToMint); return; } _safeMint(_to, maxBatchSize); leftToMint = leftToMint - maxBatchSize; ownerReserved-- ; } } // Only Owner executable functions function airdropByAccount(address _to, uint256 _mintAmount) external onlyOwner { require(totalSupply() + _mintAmount <= maxSupply, "mint over supply"); if (_mintAmount <= maxBatchSize) { _safeMint(_to, _mintAmount); return; } uint256 leftToMint = _mintAmount; while (leftToMint > 0) { if (leftToMint <= maxBatchSize) { _safeMint(_to, leftToMint); return; } _safeMint(_to, maxBatchSize); leftToMint = leftToMint - maxBatchSize; } } function airdropToBulkAccounts(address[] calldata _recipients) external onlyOwner { require( totalSupply() + _recipients.length <= (maxSupply - ownerReserved), "Airdrop minting will exceed maximum supply" ); require(_recipients.length != 0, "Address not found for minting"); for (uint256 i = 0; i < _recipients.length; i++) { require(_recipients[i] != address(0), "Minting to Null address"); _safeMint(msg.sender, 1); } } function toggleMintLive() external onlyOwner { if (saleOpen) { saleOpen = false; return; } saleOpen = true; } function toggleReveal() external onlyOwner { if (revealed) { revealed = false; return; } revealed = true; } function setBaseURI(string memory _newURI) external onlyOwner { baseURI = _newURI; } function setUnrevealedURI(string memory _newUnrevealedURI) external onlyOwner { unrevealedURI = _newUnrevealedURI; } function withdraw() external onlyOwner { (bool success, ) = withdrawl_address.call{value: address(this).balance}(""); require(success, "Transfer failed"); } function setOwnersExplicit(uint256 quantity) external onlyOwner { _setOwnersExplicit(quantity); } function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { require(_exists(_tokenId), "URI query for nonexistent token"); if(revealed == false) { return unrevealedURI; } string memory baseTokenURI = _baseURI(); string memory json = ".json"; return bytes(baseTokenURI).length > 0 ? string(abi.encodePacked(baseTokenURI, _tokenId.toString(), json)) : ''; } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } fallback() external payable { } receive() external payable { } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"airdropByAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"}],"name":"airdropToBulkAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"claimReserved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"maxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintPerTransaction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"mintedByAddressCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextOwnerToExplicitlySet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"ownerReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","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":[],"name":"saleOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"_newURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_MerkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"setOwnersExplicit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier1_limit","type":"uint256"}],"name":"setTier1Limit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier1_price","type":"uint256"}],"name":"setTier1Price","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier2_price","type":"uint256"}],"name":"setTier2Price","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newUnrevealedURI","type":"string"}],"name":"setUnrevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_whitelistStatus","type":"bool"}],"name":"setWhitelistOnly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tier1_limit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tier1_price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tier2_price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleMintLive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unrevealedURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistOnly","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawl_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040526000808055600755600980546001600160a01b031916736896504e8a6cd20f49d25ff3c2c6f7352c42990a179055600260108190556011556013805462ffffff19166101011790553480156200005957600080fd5b506040518060400160405280601481526020017f546865204e6f727468204b6f7265616e204e465400000000000000000000000081525060405180604001604052806003815260200162544e4b60e81b81525060105460008111620001145760405162461bcd60e51b815260206004820152602760248201527f455243373231413a206d61782062617463682073697a65206d757374206265206044820152666e6f6e7a65726f60c81b606482015260840160405180910390fd5b825162000129906001906020860190620001c7565b5081516200013f906002906020850190620001c7565b50608052506200015190503362000175565b611a0a600f5561029a6012556107d0600c556703782dace9d90000600d55620002aa565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001d5906200026d565b90600052602060002090601f016020900481019282620001f9576000855562000244565b82601f106200021457805160ff191683800117855562000244565b8280016001018555821562000244579182015b828111156200024457825182559160200191906001019062000227565b506200025292915062000256565b5090565b5b8082111562000252576000815560010162000257565b600181811c908216806200028257607f821691505b60208210811415620002a457634e487b7160e01b600052602260045260246000fd5b50919050565b6080516131226200030c60003960008181610c4801528181610c8501528181610cba01528181610ce30152818161163a01528181611673015281816116a8015281816116d1015281816122c8015281816122f2015261272d01526131226000f3fe6080604052600436106102c75760003560e01c80636c0360eb1161017e578063b86ec2a6116100d3578063d4d9196e1161008f578063e985e9c51161006c578063e985e9c51461082d578063ea05a8c614610876578063f2fde38b14610896578063fe2c7fee146108b657005b8063d4d9196e146107e1578063d5abeb0114610801578063d7224ba01461081757005b8063b86ec2a614610743578063b88d4fde14610763578063bd3e19d414610783578063c28a346c14610798578063c87b56dd146107ae578063d2cab056146107ce57005b806395d89b411161013a578063a22cb46511610117578063a22cb465146106d7578063a9d894cc146106f7578063ad99cc8a1461070d578063b4269a161461072357005b806395d89b411461069557806399288dbb146106aa578063a0712d68146106c457005b80636c0360eb146105f85780637035bf181461060d57806370a0823114610622578063715018a6146106425780637cb64759146106575780638da5cb5b1461067757005b806337351b0f116102345780634f6ccce7116101f05780635b8ad429116101cd5780635b8ad4291461058d57806362137aeb146105a2578063632d76bd146105c25780636352211e146105d857005b80634f6ccce71461052e578063518302271461054e57806355f804b31461056d57005b806337351b0f146104635780633ccfd60b146104995780634018d346146104ae57806342842e0e146104ce5780634b4687b5146104ee5780634d22ff1b1461050e57005b806318160ddd1161028357806318160ddd146103b85780631b5757f2146103cd578063239c70ae146103ed57806323b872dd146104035780632d20fb60146104235780632f745c591461044357005b806301f56997146102d057806301ffc9a7146102f957806306fdde0314610329578063081812fc1461034b578063095ea7b314610383578063105739b8146103a357005b366102ce57005b005b3480156102dc57600080fd5b506102e660115481565b6040519081526020015b60405180910390f35b34801561030557600080fd5b50610319610314366004612d13565b6108d6565b60405190151581526020016102f0565b34801561033557600080fd5b5061033e610943565b6040516102f09190612e8c565b34801561035757600080fd5b5061036b610366366004612cfa565b6109d5565b6040516001600160a01b0390911681526020016102f0565b34801561038f57600080fd5b506102ce61039e366004612c74565b610a65565b3480156103af57600080fd5b506102ce610b7d565b3480156103c457600080fd5b506000546102e6565b3480156103d957600080fd5b506102ce6103e8366004612c74565b610bac565b3480156103f957600080fd5b506102e660105481565b34801561040f57600080fd5b506102ce61041e366004612b93565b610d24565b34801561042f57600080fd5b506102ce61043e366004612cfa565b610d2f565b34801561044f57600080fd5b506102e661045e366004612c74565b610d43565b34801561046f57600080fd5b506102e661047e366004612b45565b6001600160a01b031660009081526015602052604090205490565b3480156104a557600080fd5b506102ce610eb0565b3480156104ba57600080fd5b506102ce6104c9366004612cfa565b610f4d565b3480156104da57600080fd5b506102ce6104e9366004612b93565b610f5a565b3480156104fa57600080fd5b506013546103199062010000900460ff1681565b34801561051a57600080fd5b506102ce610529366004612c9e565b610f75565b34801561053a57600080fd5b506102e6610549366004612cfa565b6110f7565b34801561055a57600080fd5b5060135461031990610100900460ff1681565b34801561057957600080fd5b506102ce610588366004612d4d565b611159565b34801561059957600080fd5b506102ce611174565b3480156105ae57600080fd5b506102ce6105bd366004612cfa565b6111aa565b3480156105ce57600080fd5b506102e6600e5481565b3480156105e457600080fd5b5061036b6105f3366004612cfa565b6111b7565b34801561060457600080fd5b5061033e6111c9565b34801561061957600080fd5b5061033e611257565b34801561062e57600080fd5b506102e661063d366004612b45565b611264565b34801561064e57600080fd5b506102ce6112f5565b34801561066357600080fd5b506102ce610672366004612cfa565b611307565b34801561068357600080fd5b506008546001600160a01b031661036b565b3480156106a157600080fd5b5061033e611314565b3480156106b657600080fd5b506013546103199060ff1681565b6102ce6106d2366004612cfa565b611323565b3480156106e357600080fd5b506102ce6106f2366004612c4a565b611529565b34801561070357600080fd5b506102e660125481565b34801561071957600080fd5b506102e6600d5481565b34801561072f57600080fd5b506102ce61073e366004612cfa565b6115ee565b34801561074f57600080fd5b506102ce61075e366004612c74565b6115fb565b34801561076f57600080fd5b506102ce61077e366004612bcf565b6116fd565b34801561078f57600080fd5b506102e6611730565b3480156107a457600080fd5b506102e6600c5481565b3480156107ba57600080fd5b5061033e6107c9366004612cfa565b611751565b6102ce6107dc366004612d95565b6118c5565b3480156107ed57600080fd5b5060095461036b906001600160a01b031681565b34801561080d57600080fd5b506102e6600f5481565b34801561082357600080fd5b506102e660075481565b34801561083957600080fd5b50610319610848366004612b60565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b34801561088257600080fd5b506102ce610891366004612cdf565b611b8a565b3480156108a257600080fd5b506102ce6108b1366004612b45565b611bae565b3480156108c257600080fd5b506102ce6108d1366004612d4d565b611c24565b60006001600160e01b031982166380ac58cd60e01b148061090757506001600160e01b03198216635b5e139f60e01b145b8061092257506001600160e01b0319821663780e9d6360e01b145b8061093d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606001805461095290613014565b80601f016020809104026020016040519081016040528092919081815260200182805461097e90613014565b80156109cb5780601f106109a0576101008083540402835291602001916109cb565b820191906000526020600020905b8154815290600101906020018083116109ae57829003601f168201915b5050505050905090565b60006109e2826000541190565b610a495760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b60648201526084015b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b6000610a70826111b7565b9050806001600160a01b0316836001600160a01b03161415610adf5760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b6064820152608401610a40565b336001600160a01b0382161480610afb5750610afb8133610848565b610b6d5760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c000000000000006064820152608401610a40565b610b78838383611c3f565b505050565b610b85611c9b565b60135460ff1615610b9c576013805460ff19169055565b6013805460ff191660011790555b565b610bb4611c9b565b600081601254610bc49190612fba565b11610c115760405162461bcd60e51b815260206004820152601a60248201527f6f766572206f776e657220726573657276656420737570706c790000000000006044820152606401610a40565b600f5481610c1e60005490565b610c289190612f47565b1115610c465760405162461bcd60e51b8152600401610a4090612ef2565b7f00000000000000000000000000000000000000000000000000000000000000008111610c7b57610c778282611cf5565b5050565b805b8015610b78577f00000000000000000000000000000000000000000000000000000000000000008111610cb457610b788382611cf5565b610cde837f0000000000000000000000000000000000000000000000000000000000000000611cf5565b610d087f000000000000000000000000000000000000000000000000000000000000000082612fba565b601280549192506000610d1a83612ffd565b9190505550610c7d565b610b78838383611d0f565b610d37611c9b565b610d4081612095565b50565b6000610d4e83611264565b8210610da75760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610a40565b600080549080805b83811015610e50576000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215610e0157805192505b876001600160a01b0316836001600160a01b03161415610e3d5786841415610e2f5750935061093d92505050565b83610e398161304f565b9450505b5080610e488161304f565b915050610daf565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b6064820152608401610a40565b610eb8611c9b565b6009546040516000916001600160a01b03169047908381818185875af1925050503d8060008114610f05576040519150601f19603f3d011682016040523d82523d6000602084013e610f0a565b606091505b5050905080610d405760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610a40565b610f55611c9b565b600d55565b610b78838383604051806020016040528060008152506116fd565b610f7d611c9b565b601254600f54610f8d9190612fba565b81610f9760005490565b610fa19190612f47565b11156110025760405162461bcd60e51b815260206004820152602a60248201527f41697264726f70206d696e74696e672077696c6c20657863656564206d6178696044820152696d756d20737570706c7960b01b6064820152608401610a40565b8061104f5760405162461bcd60e51b815260206004820152601d60248201527f41646472657373206e6f7420666f756e6420666f72206d696e74696e670000006044820152606401610a40565b60005b81811015610b7857600083838381811061106e5761106e6130aa565b90506020020160208101906110839190612b45565b6001600160a01b031614156110da5760405162461bcd60e51b815260206004820152601760248201527f4d696e74696e6720746f204e756c6c20616464726573730000000000000000006044820152606401610a40565b6110e5336001611cf5565b806110ef8161304f565b915050611052565b6000805482106111555760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b6064820152608401610a40565b5090565b611161611c9b565b8051610c7790600a9060208401906129c9565b61117c611c9b565b601354610100900460ff1615611199576013805461ff0019169055565b6013805461ff001916610100179055565b6111b2611c9b565b600c55565b60006111c282612246565b5192915050565b600a80546111d690613014565b80601f016020809104026020016040519081016040528092919081815260200182805461120290613014565b801561124f5780601f106112245761010080835404028352916020019161124f565b820191906000526020600020905b81548152906001019060200180831161123257829003601f168201915b505050505081565b600b80546111d690613014565b60006001600160a01b0382166112d05760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b6064820152608401610a40565b506001600160a01b03166000908152600460205260409020546001600160801b031690565b6112fd611c9b565b610baa60006123ef565b61130f611c9b565b601455565b60606002805461095290613014565b60135460ff166113655760405162461bcd60e51b815260206004820152600d60248201526c6d696e74206e6f74206c69766560981b6044820152606401610a40565b60135462010000900460ff16156113b95760405162461bcd60e51b815260206004820152601860248201527715da1a5d195b1a5cdd1959081bdb9b1e48185b1b1bddd95960421b6044820152606401610a40565b336000818152601560205260409020546010546113d68483612f47565b11156114145760405162461bcd60e51b815260206004820152600d60248201526c0dad2dce840deeccae440dac2f609b1b6044820152606401610a40565b60115483111561145a5760405162461bcd60e51b81526020600482015260116024820152700c2dadeeadce840daeae6e8407840dac2f607b1b6044820152606401610a40565b601254600f5461146a9190612fba565b8361147460005490565b61147e9190612f47565b111561149c5760405162461bcd60e51b8152600401610a4090612ef2565b60006114a6611730565b90506114b28482612f73565b3410156114f65760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a40565b6115008483612f47565b6001600160a01b0384166000908152601560205260409020556115233385611cf5565b50505050565b6001600160a01b0382163314156115825760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c65720000000000006044820152606401610a40565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6115f6611c9b565b600e55565b611603611c9b565b600f548161161060005490565b61161a9190612f47565b11156116385760405162461bcd60e51b8152600401610a4090612ef2565b7f0000000000000000000000000000000000000000000000000000000000000000811161166957610c778282611cf5565b805b8015610b78577f000000000000000000000000000000000000000000000000000000000000000081116116a257610b788382611cf5565b6116cc837f0000000000000000000000000000000000000000000000000000000000000000611cf5565b6116f67f000000000000000000000000000000000000000000000000000000000000000082612fba565b905061166b565b611708848484611d0f565b61171484848484612441565b6115235760405162461bcd60e51b8152600401610a4090612e9f565b6000600c5461173e60005490565b1161174a5750600d5490565b50600e5490565b606061175e826000541190565b6117aa5760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e006044820152606401610a40565b601354610100900460ff1661184b57600b80546117c690613014565b80601f01602080910402602001604051908101604052809291908181526020018280546117f290613014565b801561183f5780601f106118145761010080835404028352916020019161183f565b820191906000526020600020905b81548152906001019060200180831161182257829003601f168201915b50505050509050919050565b600061185561254e565b604080518082019091526005815264173539b7b760d91b602082015281519192509061189057604051806020016040528060008152506118bd565b8161189a8561255d565b826040516020016118ad93929190612e0c565b6040516020818303038152906040525b949350505050565b60135460ff166119075760405162461bcd60e51b815260206004820152600d60248201526c6d696e74206e6f74206c69766560981b6044820152606401610a40565b60135462010000900460ff16151560011461195f5760405162461bcd60e51b815260206004820152601860248201527715da1a5d195b1a5cdd1959081bdb9b1e48185b1b1bddd95960421b6044820152606401610a40565b6040516bffffffffffffffffffffffff193360601b1660208201526000906034016040516020818303038152906040528051906020012090506119d983838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601454915084905061265a565b611a175760405162461bcd60e51b815260206004820152600f60248201526e24b731b7b93932b1ba10383937b7b360891b6044820152606401610a40565b33600081815260156020526040902054601054611a348783612f47565b1115611a725760405162461bcd60e51b815260206004820152600d60248201526c0dad2dce840deeccae440dac2f609b1b6044820152606401610a40565b601154861115611ab85760405162461bcd60e51b81526020600482015260116024820152700c2dadeeadce840daeae6e8407840dac2f607b1b6044820152606401610a40565b601254600f54611ac89190612fba565b86611ad260005490565b611adc9190612f47565b1115611afa5760405162461bcd60e51b8152600401610a4090612ef2565b6000611b04611730565b9050611b108782612f73565b341015611b545760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a40565b611b5e8783612f47565b6001600160a01b038416600090815260156020526040902055611b813388611cf5565b50505050505050565b611b92611c9b565b60138054911515620100000262ff000019909216919091179055565b611bb6611c9b565b6001600160a01b038116611c1b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a40565b610d40816123ef565b611c2c611c9b565b8051610c7790600b9060208401906129c9565b60008281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6008546001600160a01b03163314610baa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a40565b610c77828260405180602001604052806000815250612670565b6000611d1a82612246565b80519091506000906001600160a01b0316336001600160a01b03161480611d51575033611d46846109d5565b6001600160a01b0316145b80611d6357508151611d639033610848565b905080611dcd5760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610a40565b846001600160a01b031682600001516001600160a01b031614611e415760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b6064820152608401610a40565b6001600160a01b038416611ea55760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610a40565b611eb56000848460000151611c3f565b6001600160a01b0385166000908152600460205260408120805460019290611ee79084906001600160801b0316612f92565b82546101009290920a6001600160801b038181021990931691831602179091556001600160a01b03861660009081526004602052604081208054600194509092611f3391859116612f1c565b82546001600160801b039182166101009390930a9283029190920219909116179055506040805180820182526001600160a01b0380871682526001600160401b03428116602080850191825260008981526003909152948520935184549151909216600160a01b026001600160e01b03199091169190921617179055611fba846001612f47565b6000818152600360205260409020549091506001600160a01b031661204b57611fe4816000541190565b1561204b5760408051808201825284516001600160a01b0390811682526020808701516001600160401b039081168285019081526000878152600390935294909120925183549451909116600160a01b026001600160e01b03199094169116179190911790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b600754816120e55760405162461bcd60e51b815260206004820152601860248201527f7175616e74697479206d757374206265206e6f6e7a65726f00000000000000006044820152606401610a40565b600060016120f38484612f47565b6120fd9190612fba565b9050600160005461210e9190612fba565b8111156121275760016000546121249190612fba565b90505b612132816000541190565b61218d5760405162461bcd60e51b815260206004820152602660248201527f6e6f7420656e6f756768206d696e7465642079657420666f722074686973206360448201526506c65616e75760d41b6064820152608401610a40565b815b818111612232576000818152600360205260409020546001600160a01b03166122205760006121bd82612246565b60408051808201825282516001600160a01b0390811682526020938401516001600160401b039081168584019081526000888152600390965293909420915182549351909416600160a01b026001600160e01b0319909316931692909217179055505b8061222a8161304f565b91505061218f565b5061223e816001612f47565b600755505050565b6040805180820190915260008082526020820152612265826000541190565b6122c45760405162461bcd60e51b815260206004820152602a60248201527f455243373231413a206f776e657220717565727920666f72206e6f6e657869736044820152693a32b73a103a37b5b2b760b11b6064820152608401610a40565b60007f00000000000000000000000000000000000000000000000000000000000000008310612325576123177f000000000000000000000000000000000000000000000000000000000000000084612fba565b612322906001612f47565b90505b825b81811061238e576000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b0316918301919091521561237b57949350505050565b508061238681612ffd565b915050612327565b5060405162461bcd60e51b815260206004820152602f60248201527f455243373231413a20756e61626c6520746f2064657465726d696e652074686560448201526e1037bbb732b91037b3103a37b5b2b760891b6064820152608401610a40565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b1561254357604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612485903390899088908890600401612e4f565b602060405180830381600087803b15801561249f57600080fd5b505af19250505080156124cf575060408051601f3d908101601f191682019092526124cc91810190612d30565b60015b612529573d8080156124fd576040519150601f19603f3d011682016040523d82523d6000602084013e612502565b606091505b5080516125215760405162461bcd60e51b8152600401610a4090612e9f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506118bd565b506001949350505050565b6060600a805461095290613014565b6060816125815750506040805180820190915260018152600360fc1b602082015290565b8160005b81156125ab57806125958161304f565b91506125a49050600a83612f5f565b9150612585565b6000816001600160401b038111156125c5576125c56130c0565b6040519080825280601f01601f1916602001820160405280156125ef576020820181803683370190505b5090505b84156118bd57612604600183612fba565b9150612611600a8661306a565b61261c906030612f47565b60f81b818381518110612631576126316130aa565b60200101906001600160f81b031916908160001a905350612653600a86612f5f565b94506125f3565b600082612667858461294a565b14949350505050565b6000546001600160a01b0384166126d35760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610a40565b6126de816000541190565b1561272b5760405162461bcd60e51b815260206004820152601d60248201527f455243373231413a20746f6b656e20616c7265616479206d696e7465640000006044820152606401610a40565b7f00000000000000000000000000000000000000000000000000000000000000008311156127a65760405162461bcd60e51b815260206004820152602260248201527f455243373231413a207175616e7469747920746f206d696e7420746f6f2068696044820152610ced60f31b6064820152608401610a40565b6001600160a01b0384166000908152600460209081526040918290208251808401845290546001600160801b038082168352600160801b9091041691810191909152815180830190925280519091908190612802908790612f1c565b6001600160801b031681526020018583602001516128209190612f1c565b6001600160801b039081169091526001600160a01b0380881660008181526004602090815260408083208751978301518716600160801b029790961696909617909455845180860186529182526001600160401b034281168386019081528883526003909552948120915182549451909516600160a01b026001600160e01b031990941694909216939093179190911790915582905b8581101561293f5760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46129036000888488612441565b61291f5760405162461bcd60e51b8152600401610a4090612e9f565b816129298161304f565b92505080806129379061304f565b9150506128b6565b50600081905561208d565b600081815b845181101561298f5761297b8286838151811061296e5761296e6130aa565b6020026020010151612997565b9150806129878161304f565b91505061294f565b509392505050565b60008183106129b35760008281526020849052604090206129c2565b60008381526020839052604090205b9392505050565b8280546129d590613014565b90600052602060002090601f0160209004810192826129f75760008555612a3d565b82601f10612a1057805160ff1916838001178555612a3d565b82800160010185558215612a3d579182015b82811115612a3d578251825591602001919060010190612a22565b506111559291505b808211156111555760008155600101612a45565b60006001600160401b0380841115612a7357612a736130c0565b604051601f8501601f19908116603f01168101908282118183101715612a9b57612a9b6130c0565b81604052809350858152868686011115612ab457600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b0381168114612ae557600080fd5b919050565b60008083601f840112612afc57600080fd5b5081356001600160401b03811115612b1357600080fd5b6020830191508360208260051b8501011115612b2e57600080fd5b9250929050565b80358015158114612ae557600080fd5b600060208284031215612b5757600080fd5b6129c282612ace565b60008060408385031215612b7357600080fd5b612b7c83612ace565b9150612b8a60208401612ace565b90509250929050565b600080600060608486031215612ba857600080fd5b612bb184612ace565b9250612bbf60208501612ace565b9150604084013590509250925092565b60008060008060808587031215612be557600080fd5b612bee85612ace565b9350612bfc60208601612ace565b92506040850135915060608501356001600160401b03811115612c1e57600080fd5b8501601f81018713612c2f57600080fd5b612c3e87823560208401612a59565b91505092959194509250565b60008060408385031215612c5d57600080fd5b612c6683612ace565b9150612b8a60208401612b35565b60008060408385031215612c8757600080fd5b612c9083612ace565b946020939093013593505050565b60008060208385031215612cb157600080fd5b82356001600160401b03811115612cc757600080fd5b612cd385828601612aea565b90969095509350505050565b600060208284031215612cf157600080fd5b6129c282612b35565b600060208284031215612d0c57600080fd5b5035919050565b600060208284031215612d2557600080fd5b81356129c2816130d6565b600060208284031215612d4257600080fd5b81516129c2816130d6565b600060208284031215612d5f57600080fd5b81356001600160401b03811115612d7557600080fd5b8201601f81018413612d8657600080fd5b6118bd84823560208401612a59565b600080600060408486031215612daa57600080fd5b8335925060208401356001600160401b03811115612dc757600080fd5b612dd386828701612aea565b9497909650939450505050565b60008151808452612df8816020860160208601612fd1565b601f01601f19169290920160200192915050565b60008451612e1e818460208901612fd1565b845190830190612e32818360208901612fd1565b8451910190612e45818360208801612fd1565b0195945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612e8290830184612de0565b9695505050505050565b6020815260006129c26020830184612de0565b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b60208082526010908201526f6d696e74206f76657220737570706c7960801b604082015260600190565b60006001600160801b03808316818516808303821115612f3e57612f3e61307e565b01949350505050565b60008219821115612f5a57612f5a61307e565b500190565b600082612f6e57612f6e613094565b500490565b6000816000190483118215151615612f8d57612f8d61307e565b500290565b60006001600160801b0383811690831681811015612fb257612fb261307e565b039392505050565b600082821015612fcc57612fcc61307e565b500390565b60005b83811015612fec578181015183820152602001612fd4565b838111156115235750506000910152565b60008161300c5761300c61307e565b506000190190565b600181811c9082168061302857607f821691505b6020821081141561304957634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156130635761306361307e565b5060010190565b60008261307957613079613094565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610d4057600080fdfea26469706673582212203e41b2cd24d1853750011a7da6f1bbbd267c5679b68ce6795eb2cc26ab9b485564736f6c63430008070033
Deployed Bytecode
0x6080604052600436106102c75760003560e01c80636c0360eb1161017e578063b86ec2a6116100d3578063d4d9196e1161008f578063e985e9c51161006c578063e985e9c51461082d578063ea05a8c614610876578063f2fde38b14610896578063fe2c7fee146108b657005b8063d4d9196e146107e1578063d5abeb0114610801578063d7224ba01461081757005b8063b86ec2a614610743578063b88d4fde14610763578063bd3e19d414610783578063c28a346c14610798578063c87b56dd146107ae578063d2cab056146107ce57005b806395d89b411161013a578063a22cb46511610117578063a22cb465146106d7578063a9d894cc146106f7578063ad99cc8a1461070d578063b4269a161461072357005b806395d89b411461069557806399288dbb146106aa578063a0712d68146106c457005b80636c0360eb146105f85780637035bf181461060d57806370a0823114610622578063715018a6146106425780637cb64759146106575780638da5cb5b1461067757005b806337351b0f116102345780634f6ccce7116101f05780635b8ad429116101cd5780635b8ad4291461058d57806362137aeb146105a2578063632d76bd146105c25780636352211e146105d857005b80634f6ccce71461052e578063518302271461054e57806355f804b31461056d57005b806337351b0f146104635780633ccfd60b146104995780634018d346146104ae57806342842e0e146104ce5780634b4687b5146104ee5780634d22ff1b1461050e57005b806318160ddd1161028357806318160ddd146103b85780631b5757f2146103cd578063239c70ae146103ed57806323b872dd146104035780632d20fb60146104235780632f745c591461044357005b806301f56997146102d057806301ffc9a7146102f957806306fdde0314610329578063081812fc1461034b578063095ea7b314610383578063105739b8146103a357005b366102ce57005b005b3480156102dc57600080fd5b506102e660115481565b6040519081526020015b60405180910390f35b34801561030557600080fd5b50610319610314366004612d13565b6108d6565b60405190151581526020016102f0565b34801561033557600080fd5b5061033e610943565b6040516102f09190612e8c565b34801561035757600080fd5b5061036b610366366004612cfa565b6109d5565b6040516001600160a01b0390911681526020016102f0565b34801561038f57600080fd5b506102ce61039e366004612c74565b610a65565b3480156103af57600080fd5b506102ce610b7d565b3480156103c457600080fd5b506000546102e6565b3480156103d957600080fd5b506102ce6103e8366004612c74565b610bac565b3480156103f957600080fd5b506102e660105481565b34801561040f57600080fd5b506102ce61041e366004612b93565b610d24565b34801561042f57600080fd5b506102ce61043e366004612cfa565b610d2f565b34801561044f57600080fd5b506102e661045e366004612c74565b610d43565b34801561046f57600080fd5b506102e661047e366004612b45565b6001600160a01b031660009081526015602052604090205490565b3480156104a557600080fd5b506102ce610eb0565b3480156104ba57600080fd5b506102ce6104c9366004612cfa565b610f4d565b3480156104da57600080fd5b506102ce6104e9366004612b93565b610f5a565b3480156104fa57600080fd5b506013546103199062010000900460ff1681565b34801561051a57600080fd5b506102ce610529366004612c9e565b610f75565b34801561053a57600080fd5b506102e6610549366004612cfa565b6110f7565b34801561055a57600080fd5b5060135461031990610100900460ff1681565b34801561057957600080fd5b506102ce610588366004612d4d565b611159565b34801561059957600080fd5b506102ce611174565b3480156105ae57600080fd5b506102ce6105bd366004612cfa565b6111aa565b3480156105ce57600080fd5b506102e6600e5481565b3480156105e457600080fd5b5061036b6105f3366004612cfa565b6111b7565b34801561060457600080fd5b5061033e6111c9565b34801561061957600080fd5b5061033e611257565b34801561062e57600080fd5b506102e661063d366004612b45565b611264565b34801561064e57600080fd5b506102ce6112f5565b34801561066357600080fd5b506102ce610672366004612cfa565b611307565b34801561068357600080fd5b506008546001600160a01b031661036b565b3480156106a157600080fd5b5061033e611314565b3480156106b657600080fd5b506013546103199060ff1681565b6102ce6106d2366004612cfa565b611323565b3480156106e357600080fd5b506102ce6106f2366004612c4a565b611529565b34801561070357600080fd5b506102e660125481565b34801561071957600080fd5b506102e6600d5481565b34801561072f57600080fd5b506102ce61073e366004612cfa565b6115ee565b34801561074f57600080fd5b506102ce61075e366004612c74565b6115fb565b34801561076f57600080fd5b506102ce61077e366004612bcf565b6116fd565b34801561078f57600080fd5b506102e6611730565b3480156107a457600080fd5b506102e6600c5481565b3480156107ba57600080fd5b5061033e6107c9366004612cfa565b611751565b6102ce6107dc366004612d95565b6118c5565b3480156107ed57600080fd5b5060095461036b906001600160a01b031681565b34801561080d57600080fd5b506102e6600f5481565b34801561082357600080fd5b506102e660075481565b34801561083957600080fd5b50610319610848366004612b60565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b34801561088257600080fd5b506102ce610891366004612cdf565b611b8a565b3480156108a257600080fd5b506102ce6108b1366004612b45565b611bae565b3480156108c257600080fd5b506102ce6108d1366004612d4d565b611c24565b60006001600160e01b031982166380ac58cd60e01b148061090757506001600160e01b03198216635b5e139f60e01b145b8061092257506001600160e01b0319821663780e9d6360e01b145b8061093d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606001805461095290613014565b80601f016020809104026020016040519081016040528092919081815260200182805461097e90613014565b80156109cb5780601f106109a0576101008083540402835291602001916109cb565b820191906000526020600020905b8154815290600101906020018083116109ae57829003601f168201915b5050505050905090565b60006109e2826000541190565b610a495760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b60648201526084015b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b6000610a70826111b7565b9050806001600160a01b0316836001600160a01b03161415610adf5760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b6064820152608401610a40565b336001600160a01b0382161480610afb5750610afb8133610848565b610b6d5760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c000000000000006064820152608401610a40565b610b78838383611c3f565b505050565b610b85611c9b565b60135460ff1615610b9c576013805460ff19169055565b6013805460ff191660011790555b565b610bb4611c9b565b600081601254610bc49190612fba565b11610c115760405162461bcd60e51b815260206004820152601a60248201527f6f766572206f776e657220726573657276656420737570706c790000000000006044820152606401610a40565b600f5481610c1e60005490565b610c289190612f47565b1115610c465760405162461bcd60e51b8152600401610a4090612ef2565b7f00000000000000000000000000000000000000000000000000000000000000028111610c7b57610c778282611cf5565b5050565b805b8015610b78577f00000000000000000000000000000000000000000000000000000000000000028111610cb457610b788382611cf5565b610cde837f0000000000000000000000000000000000000000000000000000000000000002611cf5565b610d087f000000000000000000000000000000000000000000000000000000000000000282612fba565b601280549192506000610d1a83612ffd565b9190505550610c7d565b610b78838383611d0f565b610d37611c9b565b610d4081612095565b50565b6000610d4e83611264565b8210610da75760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610a40565b600080549080805b83811015610e50576000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215610e0157805192505b876001600160a01b0316836001600160a01b03161415610e3d5786841415610e2f5750935061093d92505050565b83610e398161304f565b9450505b5080610e488161304f565b915050610daf565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b6064820152608401610a40565b610eb8611c9b565b6009546040516000916001600160a01b03169047908381818185875af1925050503d8060008114610f05576040519150601f19603f3d011682016040523d82523d6000602084013e610f0a565b606091505b5050905080610d405760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610a40565b610f55611c9b565b600d55565b610b78838383604051806020016040528060008152506116fd565b610f7d611c9b565b601254600f54610f8d9190612fba565b81610f9760005490565b610fa19190612f47565b11156110025760405162461bcd60e51b815260206004820152602a60248201527f41697264726f70206d696e74696e672077696c6c20657863656564206d6178696044820152696d756d20737570706c7960b01b6064820152608401610a40565b8061104f5760405162461bcd60e51b815260206004820152601d60248201527f41646472657373206e6f7420666f756e6420666f72206d696e74696e670000006044820152606401610a40565b60005b81811015610b7857600083838381811061106e5761106e6130aa565b90506020020160208101906110839190612b45565b6001600160a01b031614156110da5760405162461bcd60e51b815260206004820152601760248201527f4d696e74696e6720746f204e756c6c20616464726573730000000000000000006044820152606401610a40565b6110e5336001611cf5565b806110ef8161304f565b915050611052565b6000805482106111555760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b6064820152608401610a40565b5090565b611161611c9b565b8051610c7790600a9060208401906129c9565b61117c611c9b565b601354610100900460ff1615611199576013805461ff0019169055565b6013805461ff001916610100179055565b6111b2611c9b565b600c55565b60006111c282612246565b5192915050565b600a80546111d690613014565b80601f016020809104026020016040519081016040528092919081815260200182805461120290613014565b801561124f5780601f106112245761010080835404028352916020019161124f565b820191906000526020600020905b81548152906001019060200180831161123257829003601f168201915b505050505081565b600b80546111d690613014565b60006001600160a01b0382166112d05760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b6064820152608401610a40565b506001600160a01b03166000908152600460205260409020546001600160801b031690565b6112fd611c9b565b610baa60006123ef565b61130f611c9b565b601455565b60606002805461095290613014565b60135460ff166113655760405162461bcd60e51b815260206004820152600d60248201526c6d696e74206e6f74206c69766560981b6044820152606401610a40565b60135462010000900460ff16156113b95760405162461bcd60e51b815260206004820152601860248201527715da1a5d195b1a5cdd1959081bdb9b1e48185b1b1bddd95960421b6044820152606401610a40565b336000818152601560205260409020546010546113d68483612f47565b11156114145760405162461bcd60e51b815260206004820152600d60248201526c0dad2dce840deeccae440dac2f609b1b6044820152606401610a40565b60115483111561145a5760405162461bcd60e51b81526020600482015260116024820152700c2dadeeadce840daeae6e8407840dac2f607b1b6044820152606401610a40565b601254600f5461146a9190612fba565b8361147460005490565b61147e9190612f47565b111561149c5760405162461bcd60e51b8152600401610a4090612ef2565b60006114a6611730565b90506114b28482612f73565b3410156114f65760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a40565b6115008483612f47565b6001600160a01b0384166000908152601560205260409020556115233385611cf5565b50505050565b6001600160a01b0382163314156115825760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c65720000000000006044820152606401610a40565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6115f6611c9b565b600e55565b611603611c9b565b600f548161161060005490565b61161a9190612f47565b11156116385760405162461bcd60e51b8152600401610a4090612ef2565b7f0000000000000000000000000000000000000000000000000000000000000002811161166957610c778282611cf5565b805b8015610b78577f000000000000000000000000000000000000000000000000000000000000000281116116a257610b788382611cf5565b6116cc837f0000000000000000000000000000000000000000000000000000000000000002611cf5565b6116f67f000000000000000000000000000000000000000000000000000000000000000282612fba565b905061166b565b611708848484611d0f565b61171484848484612441565b6115235760405162461bcd60e51b8152600401610a4090612e9f565b6000600c5461173e60005490565b1161174a5750600d5490565b50600e5490565b606061175e826000541190565b6117aa5760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e006044820152606401610a40565b601354610100900460ff1661184b57600b80546117c690613014565b80601f01602080910402602001604051908101604052809291908181526020018280546117f290613014565b801561183f5780601f106118145761010080835404028352916020019161183f565b820191906000526020600020905b81548152906001019060200180831161182257829003601f168201915b50505050509050919050565b600061185561254e565b604080518082019091526005815264173539b7b760d91b602082015281519192509061189057604051806020016040528060008152506118bd565b8161189a8561255d565b826040516020016118ad93929190612e0c565b6040516020818303038152906040525b949350505050565b60135460ff166119075760405162461bcd60e51b815260206004820152600d60248201526c6d696e74206e6f74206c69766560981b6044820152606401610a40565b60135462010000900460ff16151560011461195f5760405162461bcd60e51b815260206004820152601860248201527715da1a5d195b1a5cdd1959081bdb9b1e48185b1b1bddd95960421b6044820152606401610a40565b6040516bffffffffffffffffffffffff193360601b1660208201526000906034016040516020818303038152906040528051906020012090506119d983838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601454915084905061265a565b611a175760405162461bcd60e51b815260206004820152600f60248201526e24b731b7b93932b1ba10383937b7b360891b6044820152606401610a40565b33600081815260156020526040902054601054611a348783612f47565b1115611a725760405162461bcd60e51b815260206004820152600d60248201526c0dad2dce840deeccae440dac2f609b1b6044820152606401610a40565b601154861115611ab85760405162461bcd60e51b81526020600482015260116024820152700c2dadeeadce840daeae6e8407840dac2f607b1b6044820152606401610a40565b601254600f54611ac89190612fba565b86611ad260005490565b611adc9190612f47565b1115611afa5760405162461bcd60e51b8152600401610a4090612ef2565b6000611b04611730565b9050611b108782612f73565b341015611b545760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a40565b611b5e8783612f47565b6001600160a01b038416600090815260156020526040902055611b813388611cf5565b50505050505050565b611b92611c9b565b60138054911515620100000262ff000019909216919091179055565b611bb6611c9b565b6001600160a01b038116611c1b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a40565b610d40816123ef565b611c2c611c9b565b8051610c7790600b9060208401906129c9565b60008281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6008546001600160a01b03163314610baa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a40565b610c77828260405180602001604052806000815250612670565b6000611d1a82612246565b80519091506000906001600160a01b0316336001600160a01b03161480611d51575033611d46846109d5565b6001600160a01b0316145b80611d6357508151611d639033610848565b905080611dcd5760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610a40565b846001600160a01b031682600001516001600160a01b031614611e415760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b6064820152608401610a40565b6001600160a01b038416611ea55760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610a40565b611eb56000848460000151611c3f565b6001600160a01b0385166000908152600460205260408120805460019290611ee79084906001600160801b0316612f92565b82546101009290920a6001600160801b038181021990931691831602179091556001600160a01b03861660009081526004602052604081208054600194509092611f3391859116612f1c565b82546001600160801b039182166101009390930a9283029190920219909116179055506040805180820182526001600160a01b0380871682526001600160401b03428116602080850191825260008981526003909152948520935184549151909216600160a01b026001600160e01b03199091169190921617179055611fba846001612f47565b6000818152600360205260409020549091506001600160a01b031661204b57611fe4816000541190565b1561204b5760408051808201825284516001600160a01b0390811682526020808701516001600160401b039081168285019081526000878152600390935294909120925183549451909116600160a01b026001600160e01b03199094169116179190911790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b600754816120e55760405162461bcd60e51b815260206004820152601860248201527f7175616e74697479206d757374206265206e6f6e7a65726f00000000000000006044820152606401610a40565b600060016120f38484612f47565b6120fd9190612fba565b9050600160005461210e9190612fba565b8111156121275760016000546121249190612fba565b90505b612132816000541190565b61218d5760405162461bcd60e51b815260206004820152602660248201527f6e6f7420656e6f756768206d696e7465642079657420666f722074686973206360448201526506c65616e75760d41b6064820152608401610a40565b815b818111612232576000818152600360205260409020546001600160a01b03166122205760006121bd82612246565b60408051808201825282516001600160a01b0390811682526020938401516001600160401b039081168584019081526000888152600390965293909420915182549351909416600160a01b026001600160e01b0319909316931692909217179055505b8061222a8161304f565b91505061218f565b5061223e816001612f47565b600755505050565b6040805180820190915260008082526020820152612265826000541190565b6122c45760405162461bcd60e51b815260206004820152602a60248201527f455243373231413a206f776e657220717565727920666f72206e6f6e657869736044820152693a32b73a103a37b5b2b760b11b6064820152608401610a40565b60007f00000000000000000000000000000000000000000000000000000000000000028310612325576123177f000000000000000000000000000000000000000000000000000000000000000284612fba565b612322906001612f47565b90505b825b81811061238e576000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b0316918301919091521561237b57949350505050565b508061238681612ffd565b915050612327565b5060405162461bcd60e51b815260206004820152602f60248201527f455243373231413a20756e61626c6520746f2064657465726d696e652074686560448201526e1037bbb732b91037b3103a37b5b2b760891b6064820152608401610a40565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b1561254357604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612485903390899088908890600401612e4f565b602060405180830381600087803b15801561249f57600080fd5b505af19250505080156124cf575060408051601f3d908101601f191682019092526124cc91810190612d30565b60015b612529573d8080156124fd576040519150601f19603f3d011682016040523d82523d6000602084013e612502565b606091505b5080516125215760405162461bcd60e51b8152600401610a4090612e9f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506118bd565b506001949350505050565b6060600a805461095290613014565b6060816125815750506040805180820190915260018152600360fc1b602082015290565b8160005b81156125ab57806125958161304f565b91506125a49050600a83612f5f565b9150612585565b6000816001600160401b038111156125c5576125c56130c0565b6040519080825280601f01601f1916602001820160405280156125ef576020820181803683370190505b5090505b84156118bd57612604600183612fba565b9150612611600a8661306a565b61261c906030612f47565b60f81b818381518110612631576126316130aa565b60200101906001600160f81b031916908160001a905350612653600a86612f5f565b94506125f3565b600082612667858461294a565b14949350505050565b6000546001600160a01b0384166126d35760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610a40565b6126de816000541190565b1561272b5760405162461bcd60e51b815260206004820152601d60248201527f455243373231413a20746f6b656e20616c7265616479206d696e7465640000006044820152606401610a40565b7f00000000000000000000000000000000000000000000000000000000000000028311156127a65760405162461bcd60e51b815260206004820152602260248201527f455243373231413a207175616e7469747920746f206d696e7420746f6f2068696044820152610ced60f31b6064820152608401610a40565b6001600160a01b0384166000908152600460209081526040918290208251808401845290546001600160801b038082168352600160801b9091041691810191909152815180830190925280519091908190612802908790612f1c565b6001600160801b031681526020018583602001516128209190612f1c565b6001600160801b039081169091526001600160a01b0380881660008181526004602090815260408083208751978301518716600160801b029790961696909617909455845180860186529182526001600160401b034281168386019081528883526003909552948120915182549451909516600160a01b026001600160e01b031990941694909216939093179190911790915582905b8581101561293f5760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46129036000888488612441565b61291f5760405162461bcd60e51b8152600401610a4090612e9f565b816129298161304f565b92505080806129379061304f565b9150506128b6565b50600081905561208d565b600081815b845181101561298f5761297b8286838151811061296e5761296e6130aa565b6020026020010151612997565b9150806129878161304f565b91505061294f565b509392505050565b60008183106129b35760008281526020849052604090206129c2565b60008381526020839052604090205b9392505050565b8280546129d590613014565b90600052602060002090601f0160209004810192826129f75760008555612a3d565b82601f10612a1057805160ff1916838001178555612a3d565b82800160010185558215612a3d579182015b82811115612a3d578251825591602001919060010190612a22565b506111559291505b808211156111555760008155600101612a45565b60006001600160401b0380841115612a7357612a736130c0565b604051601f8501601f19908116603f01168101908282118183101715612a9b57612a9b6130c0565b81604052809350858152868686011115612ab457600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b0381168114612ae557600080fd5b919050565b60008083601f840112612afc57600080fd5b5081356001600160401b03811115612b1357600080fd5b6020830191508360208260051b8501011115612b2e57600080fd5b9250929050565b80358015158114612ae557600080fd5b600060208284031215612b5757600080fd5b6129c282612ace565b60008060408385031215612b7357600080fd5b612b7c83612ace565b9150612b8a60208401612ace565b90509250929050565b600080600060608486031215612ba857600080fd5b612bb184612ace565b9250612bbf60208501612ace565b9150604084013590509250925092565b60008060008060808587031215612be557600080fd5b612bee85612ace565b9350612bfc60208601612ace565b92506040850135915060608501356001600160401b03811115612c1e57600080fd5b8501601f81018713612c2f57600080fd5b612c3e87823560208401612a59565b91505092959194509250565b60008060408385031215612c5d57600080fd5b612c6683612ace565b9150612b8a60208401612b35565b60008060408385031215612c8757600080fd5b612c9083612ace565b946020939093013593505050565b60008060208385031215612cb157600080fd5b82356001600160401b03811115612cc757600080fd5b612cd385828601612aea565b90969095509350505050565b600060208284031215612cf157600080fd5b6129c282612b35565b600060208284031215612d0c57600080fd5b5035919050565b600060208284031215612d2557600080fd5b81356129c2816130d6565b600060208284031215612d4257600080fd5b81516129c2816130d6565b600060208284031215612d5f57600080fd5b81356001600160401b03811115612d7557600080fd5b8201601f81018413612d8657600080fd5b6118bd84823560208401612a59565b600080600060408486031215612daa57600080fd5b8335925060208401356001600160401b03811115612dc757600080fd5b612dd386828701612aea565b9497909650939450505050565b60008151808452612df8816020860160208601612fd1565b601f01601f19169290920160200192915050565b60008451612e1e818460208901612fd1565b845190830190612e32818360208901612fd1565b8451910190612e45818360208801612fd1565b0195945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612e8290830184612de0565b9695505050505050565b6020815260006129c26020830184612de0565b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b60208082526010908201526f6d696e74206f76657220737570706c7960801b604082015260600190565b60006001600160801b03808316818516808303821115612f3e57612f3e61307e565b01949350505050565b60008219821115612f5a57612f5a61307e565b500190565b600082612f6e57612f6e613094565b500490565b6000816000190483118215151615612f8d57612f8d61307e565b500290565b60006001600160801b0383811690831681811015612fb257612fb261307e565b039392505050565b600082821015612fcc57612fcc61307e565b500390565b60005b83811015612fec578181015183820152602001612fd4565b838111156115235750506000910152565b60008161300c5761300c61307e565b506000190190565b600181811c9082168061302857607f821691505b6020821081141561304957634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156130635761306361307e565b5060010190565b60008261307957613079613094565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610d4057600080fdfea26469706673582212203e41b2cd24d1853750011a7da6f1bbbd267c5679b68ce6795eb2cc26ab9b485564736f6c63430008070033
Deployed Bytecode Sourcemap
67819:7086:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68218:40;;;;;;;;;;;;;;;;;;;21448:25:1;;;21436:2;21421:18;68218:40:0;;;;;;;;54775:372;;;;;;;;;;-1:-1:-1;54775:372:0;;;;;:::i;:::-;;:::i;:::-;;;8050:14:1;;8043:22;8025:41;;8013:2;7998:18;54775:372:0;7885:187:1;56580:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;58141:214::-;;;;;;;;;;-1:-1:-1;58141:214:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7348:32:1;;;7330:51;;7318:2;7303:18;58141:214:0;7184:203:1;57662:413:0;;;;;;;;;;-1:-1:-1;57662:413:0;;;;;:::i;:::-;;:::i;73317:177::-;;;;;;;;;;;;;:::i;53216:100::-;;;;;;;;;;-1:-1:-1;53269:7:0;53296:12;53216:100;;71396:722;;;;;;;;;;-1:-1:-1;71396:722:0;;;;;:::i;:::-;;:::i;68179:32::-;;;;;;;;;;;;;;;;59017:162;;;;;;;;;;-1:-1:-1;59017:162:0;;;;;:::i;:::-;;:::i;74106:111::-;;;;;;;;;;-1:-1:-1;74106:111:0;;;;;:::i;:::-;;:::i;53880:823::-;;;;;;;;;;-1:-1:-1;53880:823:0;;;;;:::i;:::-;;:::i;68818:122::-;;;;;;;;;;-1:-1:-1;68818:122:0;;;;;:::i;:::-;-1:-1:-1;;;;;68913:19:0;68887:7;68913:19;;;:9;:19;;;;;;;68818:122;73919:179;;;;;;;;;;;;;:::i;69189:107::-;;;;;;;;;;-1:-1:-1;69189:107:0;;;;;:::i;:::-;;:::i;59250:177::-;;;;;;;;;;-1:-1:-1;59250:177:0;;;;;:::i;:::-;;:::i;68373:33::-;;;;;;;;;;-1:-1:-1;68373:33:0;;;;;;;;;;;72785:524;;;;;;;;;;-1:-1:-1;72785:524:0;;;;;:::i;:::-;;:::i;53393:187::-;;;;;;;;;;-1:-1:-1;53393:187:0;;;;;:::i;:::-;;:::i;68339:27::-;;;;;;;;;;-1:-1:-1;68339:27:0;;;;;;;;;;;73675:98;;;;;;;;;;-1:-1:-1;73675:98:0;;;;;:::i;:::-;;:::i;73502:165::-;;;;;;;;;;;;;:::i;69074:107::-;;;;;;;;;;-1:-1:-1;69074:107:0;;;;;:::i;:::-;;:::i;68115:26::-;;;;;;;;;;;;;;;;56389:124;;;;;;;;;;-1:-1:-1;56389:124:0;;;;;:::i;:::-;;:::i;67987:21::-;;;;;;;;;;;;;:::i;68015:27::-;;;;;;;;;;;;;:::i;55211:221::-;;;;;;;;;;-1:-1:-1;55211:221:0;;;;;:::i;:::-;;:::i;2809:103::-;;;;;;;;;;;;;:::i;71242:106::-;;;;;;;;;;-1:-1:-1;71242:106:0;;;;;:::i;:::-;;:::i;2161:87::-;;;;;;;;;;-1:-1:-1;2234:6:0;;-1:-1:-1;;;;;2234:6:0;2161:87;;56749:104;;;;;;;;;;;;;:::i;68305:27::-;;;;;;;;;;-1:-1:-1;68305:27:0;;;;;;;;69647:675;;;;;;:::i;:::-;;:::i;58427:288::-;;;;;;;;;;-1:-1:-1;58427:288:0;;;;;:::i;:::-;;:::i;68265:28::-;;;;;;;;;;;;;;;;68082:26;;;;;;;;;;;;;;;;69304:107;;;;;;;;;;-1:-1:-1;69304:107:0;;;;;:::i;:::-;;:::i;72166:611::-;;;;;;;;;;-1:-1:-1;72166:611:0;;;;;:::i;:::-;;:::i;59498:355::-;;;;;;;;;;-1:-1:-1;59498:355:0;;;;;:::i;:::-;;:::i;69419:194::-;;;;;;;;;;;;;:::i;68049:26::-;;;;;;;;;;;;;;;;74225:484;;;;;;;;;;-1:-1:-1;74225:484:0;;;;;:::i;:::-;;:::i;70356:874::-;;;;;;:::i;:::-;;:::i;67903:77::-;;;;;;;;;;-1:-1:-1;67903:77:0;;;;-1:-1:-1;;;;;67903:77:0;;;68148:24;;;;;;;;;;;;;;;;64158:43;;;;;;;;;;;;;;;;58786:164;;;;;;;;;;-1:-1:-1;58786:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;58907:25:0;;;58883:4;58907:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;58786:164;68948:118;;;;;;;;;;-1:-1:-1;68948:118:0;;;;;:::i;:::-;;:::i;3067:201::-;;;;;;;;;;-1:-1:-1;3067:201:0;;;;;:::i;:::-;;:::i;73781:130::-;;;;;;;;;;-1:-1:-1;73781:130:0;;;;;:::i;:::-;;:::i;54775:372::-;54877:4;-1:-1:-1;;;;;;54914:40:0;;-1:-1:-1;;;54914:40:0;;:105;;-1:-1:-1;;;;;;;54971:48:0;;-1:-1:-1;;;54971:48:0;54914:105;:172;;;-1:-1:-1;;;;;;;55036:50:0;;-1:-1:-1;;;55036:50:0;54914:172;:225;;;-1:-1:-1;;;;;;;;;;29704:40:0;;;55103:36;54894:245;54775:372;-1:-1:-1;;54775:372:0:o;56580:100::-;56634:13;56667:5;56660:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56580:100;:::o;58141:214::-;58209:7;58237:16;58245:7;60165:4;60199:12;-1:-1:-1;60189:22:0;60108:111;58237:16;58229:74;;;;-1:-1:-1;;;58229:74:0;;20687:2:1;58229:74:0;;;20669:21:1;20726:2;20706:18;;;20699:30;20765:34;20745:18;;;20738:62;-1:-1:-1;;;20816:18:1;;;20809:43;20869:19;;58229:74:0;;;;;;;;;-1:-1:-1;58323:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;58323:24:0;;58141:214::o;57662:413::-;57735:13;57751:24;57767:7;57751:15;:24::i;:::-;57735:40;;57800:5;-1:-1:-1;;;;;57794:11:0;:2;-1:-1:-1;;;;;57794:11:0;;;57786:58;;;;-1:-1:-1;;;57786:58:0;;17174:2:1;57786:58:0;;;17156:21:1;17213:2;17193:18;;;17186:30;17252:34;17232:18;;;17225:62;-1:-1:-1;;;17303:18:1;;;17296:32;17345:19;;57786:58:0;16972:398:1;57786:58:0;792:10;-1:-1:-1;;;;;57879:21:0;;;;:62;;-1:-1:-1;57904:37:0;57921:5;792:10;58786:164;:::i;57904:37::-;57857:169;;;;-1:-1:-1;;;57857:169:0;;13409:2:1;57857:169:0;;;13391:21:1;13448:2;13428:18;;;13421:30;13487:34;13467:18;;;13460:62;13558:27;13538:18;;;13531:55;13603:19;;57857:169:0;13207:421:1;57857:169:0;58039:28;58048:2;58052:7;58061:5;58039:8;:28::i;:::-;57724:351;57662:413;;:::o;73317:177::-;2047:13;:11;:13::i;:::-;73377:8:::1;::::0;::::1;;73373:78;;;73402:8;:16:::0;;-1:-1:-1;;73402:16:0::1;::::0;;73317:177::o;73373:78::-:1;73471:8;:15:::0;;-1:-1:-1;;73471:15:0::1;73482:4;73471:15;::::0;;2071:1:::1;73317:177::o:0;71396:722::-;2047:13;:11;:13::i;:::-;71523:1:::1;71508:11;71492:13;;:27;;;;:::i;:::-;71491:33;71483:72;;;::::0;-1:-1:-1;;;71483:72:0;;12301:2:1;71483:72:0::1;::::0;::::1;12283:21:1::0;12340:2;12320:18;;;12313:30;12379:28;12359:18;;;12352:56;12425:18;;71483:72:0::1;12099:350:1::0;71483:72:0::1;71605:9;;71590:11;71574:13;53269:7:::0;53296:12;;53216:100;71574:13:::1;:27;;;;:::i;:::-;:40;;71566:69;;;;-1:-1:-1::0;;;71566:69:0::1;;;;;;;:::i;:::-;71665:12;71650:11;:27;71646:108;;71694:27;71704:3;71709:11;71694:9;:27::i;:::-;71396:722:::0;;:::o;71646:108::-:1;71795:11:::0;71817:294:::1;71824:14:::0;;71817:294:::1;;71873:12;71859:10;:26;71855:118;;71906:26;71916:3;71921:10;71906:9;:26::i;71855:118::-;71987:28;71997:3;72002:12;71987:9;:28::i;:::-;72043:25;72056:12;72043:10:::0;:25:::1;:::i;:::-;72083:13;:15:::0;;72030:38;;-1:-1:-1;72083:13:0::1;:15;::::0;::::1;:::i;:::-;;;;;;71817:294;;59017:162:::0;59143:28;59153:4;59159:2;59163:7;59143:9;:28::i;74106:111::-;2047:13;:11;:13::i;:::-;74181:28:::1;74200:8;74181:18;:28::i;:::-;74106:111:::0;:::o;53880:823::-;53969:7;54005:16;54015:5;54005:9;:16::i;:::-;53997:5;:24;53989:71;;;;-1:-1:-1;;;53989:71:0;;8503:2:1;53989:71:0;;;8485:21:1;8542:2;8522:18;;;8515:30;8581:34;8561:18;;;8554:62;-1:-1:-1;;;8632:18:1;;;8625:32;8674:19;;53989:71:0;8301:398:1;53989:71:0;54071:22;53296:12;;;54071:22;;54203:426;54227:14;54223:1;:18;54203:426;;;54263:31;54297:14;;;:11;:14;;;;;;;;;54263:48;;;;;;;;;-1:-1:-1;;;;;54263:48:0;;;;;-1:-1:-1;;;54263:48:0;;;-1:-1:-1;;;;;54263:48:0;;;;;;;;54330:28;54326:103;;54399:14;;;-1:-1:-1;54326:103:0;54468:5;-1:-1:-1;;;;;54447:26:0;:17;-1:-1:-1;;;;;54447:26:0;;54443:175;;;54513:5;54498:11;:20;54494:77;;;-1:-1:-1;54550:1:0;-1:-1:-1;54543:8:0;;-1:-1:-1;;;54543:8:0;54494:77;54589:13;;;;:::i;:::-;;;;54443:175;-1:-1:-1;54243:3:0;;;;:::i;:::-;;;;54203:426;;;-1:-1:-1;54639:56:0;;-1:-1:-1;;;54639:56:0;;19449:2:1;54639:56:0;;;19431:21:1;19488:2;19468:18;;;19461:30;19527:34;19507:18;;;19500:62;-1:-1:-1;;;19578:18:1;;;19571:44;19632:19;;54639:56:0;19247:410:1;73919:179:0;2047:13;:11;:13::i;:::-;73988:17:::1;::::0;:56:::1;::::0;73970:12:::1;::::0;-1:-1:-1;;;;;73988:17:0::1;::::0;74018:21:::1;::::0;73970:12;73988:56;73970:12;73988:56;74018:21;73988:17;:56:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73969:75;;;74063:7;74055:35;;;::::0;-1:-1:-1;;;74055:35:0;;10736:2:1;74055:35:0::1;::::0;::::1;10718:21:1::0;10775:2;10755:18;;;10748:30;-1:-1:-1;;;10794:18:1;;;10787:45;10849:18;;74055:35:0::1;10534:339:1::0;69189:107:0;2047:13;:11;:13::i;:::-;69262:11:::1;:26:::0;69189:107::o;59250:177::-;59380:39;59397:4;59403:2;59407:7;59380:39;;;;;;;;;;;;:16;:39::i;72785:524::-;2047:13;:11;:13::i;:::-;72951::::1;;72939:9;;:25;;;;:::i;:::-;72916:11:::0;72900:13:::1;53269:7:::0;53296:12;;53216:100;72900:13:::1;:34;;;;:::i;:::-;:65;;72878:157;;;::::0;-1:-1:-1;;;72878:157:0;;12998:2:1;72878:157:0::1;::::0;::::1;12980:21:1::0;13037:2;13017:18;;;13010:30;13076:34;13056:18;;;13049:62;-1:-1:-1;;;13127:18:1;;;13120:40;13177:19;;72878:157:0::1;12796:406:1::0;72878:157:0::1;73054:23:::0;73046:65:::1;;;::::0;-1:-1:-1;;;73046:65:0;;8906:2:1;73046:65:0::1;::::0;::::1;8888:21:1::0;8945:2;8925:18;;;8918:30;8984:31;8964:18;;;8957:59;9033:18;;73046:65:0::1;8704:353:1::0;73046:65:0::1;73127:9;73122:180;73142:22:::0;;::::1;73122:180;;;73220:1;73194:11:::0;;73206:1;73194:14;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;73194:28:0::1;;;73186:64;;;::::0;-1:-1:-1;;;73186:64:0;;9624:2:1;73186:64:0::1;::::0;::::1;9606:21:1::0;9663:2;9643:18;;;9636:30;9702:25;9682:18;;;9675:53;9745:18;;73186:64:0::1;9422:347:1::0;73186:64:0::1;73266:24;73276:10;73288:1;73266:9;:24::i;:::-;73166:3:::0;::::1;::::0;::::1;:::i;:::-;;;;73122:180;;53393:187:::0;53460:7;53296:12;;53488:5;:21;53480:69;;;;-1:-1:-1;;;53480:69:0;;11491:2:1;53480:69:0;;;11473:21:1;11530:2;11510:18;;;11503:30;11569:34;11549:18;;;11542:62;-1:-1:-1;;;11620:18:1;;;11613:33;11663:19;;53480:69:0;11289:399:1;53480:69:0;-1:-1:-1;53567:5:0;53393:187::o;73675:98::-;2047:13;:11;:13::i;:::-;73748:17;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;73502:165::-:0;2047:13;:11;:13::i;:::-;73560:8:::1;::::0;::::1;::::0;::::1;;;73556:78;;;73585:8;:16:::0;;-1:-1:-1;;73585:16:0::1;::::0;;73317:177::o;73556:78::-:1;73644:8;:15:::0;;-1:-1:-1;;73644:15:0::1;;;::::0;;73502:165::o;69074:107::-;2047:13;:11;:13::i;:::-;69147:11:::1;:26:::0;69074:107::o;56389:124::-;56453:7;56480:20;56492:7;56480:11;:20::i;:::-;:25;;56389:124;-1:-1:-1;;56389:124:0:o;67987:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;68015:27::-;;;;;;;:::i;55211:221::-;55275:7;-1:-1:-1;;;;;55303:19:0;;55295:75;;;;-1:-1:-1;;;55295:75:0;;14188:2:1;55295:75:0;;;14170:21:1;14227:2;14207:18;;;14200:30;14266:34;14246:18;;;14239:62;-1:-1:-1;;;14317:18:1;;;14310:41;14368:19;;55295:75:0;13986:407:1;55295:75:0;-1:-1:-1;;;;;;55396:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;55396:27:0;;55211:221::o;2809:103::-;2047:13;:11;:13::i;:::-;2874:30:::1;2901:1;2874:18;:30::i;71242:106::-:0;2047:13;:11;:13::i;:::-;71316:10:::1;:24:::0;71242:106::o;56749:104::-;56805:13;56838:7;56831:14;;;;;:::i;69647:675::-;68537:8;;;;68529:34;;;;-1:-1:-1;;;68529:34:0;;12656:2:1;68529:34:0;;;12638:21:1;12695:2;12675:18;;;12668:30;-1:-1:-1;;;12714:18:1;;;12707:43;12767:18;;68529:34:0;12454:337:1;68529:34:0;69729:13:::1;::::0;;;::::1;;;:22;69721:58;;;::::0;-1:-1:-1;;;69721:58:0;;9976:2:1;69721:58:0::1;::::0;::::1;9958:21:1::0;10015:2;9995:18;;;9988:30;-1:-1:-1;;;10034:18:1;;;10027:54;10098:18;;69721:58:0::1;9774:348:1::0;69721:58:0::1;69804:10;69790:11;69842:14:::0;;;:9:::1;:14;::::0;;;;;69899:13:::1;::::0;69875:20:::1;69884:11:::0;69842:14;69875:20:::1;:::i;:::-;:37;;69867:63;;;::::0;-1:-1:-1;;;69867:63:0;;16832:2:1;69867:63:0::1;::::0;::::1;16814:21:1::0;16871:2;16851:18;;;16844:30;-1:-1:-1;;;16890:18:1;;;16883:43;16943:18;;69867:63:0::1;16630:337:1::0;69867:63:0::1;69964:21;;69949:11;:36;;69941:66;;;::::0;-1:-1:-1;;;69941:66:0;;15007:2:1;69941:66:0::1;::::0;::::1;14989:21:1::0;15046:2;15026:18;;;15019:30;-1:-1:-1;;;15065:18:1;;;15058:47;15122:18;;69941:66:0::1;14805:341:1::0;69941:66:0::1;70070:13;;70058:9;;:25;;;;:::i;:::-;70042:11;70026:13;53269:7:::0;53296:12;;53216:100;70026:13:::1;:27;;;;:::i;:::-;:58;;70018:87;;;;-1:-1:-1::0;;;70018:87:0::1;;;;;;;:::i;:::-;70118:13;70134:9;:7;:9::i;:::-;70118:25:::0;-1:-1:-1;70177:19:0::1;70185:11:::0;70118:25;70177:19:::1;:::i;:::-;70164:9;:32;;70156:63;;;::::0;-1:-1:-1;;;70156:63:0;;17577:2:1;70156:63:0::1;::::0;::::1;17559:21:1::0;17616:2;17596:18;;;17589:30;-1:-1:-1;;;17635:18:1;;;17628:48;17693:18;;70156:63:0::1;17375:342:1::0;70156:63:0::1;70249:20;70258:11:::0;70249:6;:20:::1;:::i;:::-;-1:-1:-1::0;;;;;70232:14:0;::::1;;::::0;;;:9:::1;:14;::::0;;;;:37;70280:34:::1;70290:10;70302:11:::0;70280:9:::1;:34::i;:::-;69710:612;;;69647:675:::0;:::o;58427:288::-;-1:-1:-1;;;;;58522:24:0;;792:10;58522:24;;58514:63;;;;-1:-1:-1;;;58514:63:0;;15714:2:1;58514:63:0;;;15696:21:1;15753:2;15733:18;;;15726:30;15792:28;15772:18;;;15765:56;15838:18;;58514:63:0;15512:350:1;58514:63:0;792:10;58590:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;58590:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;58590:53:0;;;;;;;;;;58659:48;;8025:41:1;;;58590:42:0;;792:10;58659:48;;7998:18:1;58659:48:0;;;;;;;58427:288;;:::o;69304:107::-;2047:13;:11;:13::i;:::-;69377:11:::1;:26:::0;69304:107::o;72166:611::-;2047:13;:11;:13::i;:::-;72295:9:::1;;72280:11;72264:13;53269:7:::0;53296:12;;53216:100;72264:13:::1;:27;;;;:::i;:::-;:40;;72256:69;;;;-1:-1:-1::0;;;72256:69:0::1;;;;;;;:::i;:::-;72355:12;72340:11;:27;72336:108;;72384:27;72394:3;72399:11;72384:9;:27::i;72336:108::-;72485:11:::0;72507:263:::1;72514:14:::0;;72507:263:::1;;72563:12;72549:10;:26;72545:118;;72596:26;72606:3;72611:10;72596:9;:26::i;72545:118::-;72677:28;72687:3;72692:12;72677:9;:28::i;:::-;72733:25;72746:12;72733:10:::0;:25:::1;:::i;:::-;72720:38;;72507:263;;59498:355:::0;59657:28;59667:4;59673:2;59677:7;59657:9;:28::i;:::-;59718:48;59741:4;59747:2;59751:7;59760:5;59718:22;:48::i;:::-;59696:149;;;;-1:-1:-1;;;59696:149:0;;;;;;;:::i;69419:194::-;69458:7;69498:11;;69481:13;53269:7;53296:12;;53216:100;69481:13;:28;69478:128;;-1:-1:-1;69532:11:0;;;69419:194::o;69478:128::-;-1:-1:-1;69583:11:0;;;69419:194::o;74225:484::-;74299:13;74333:17;74341:8;60165:4;60199:12;-1:-1:-1;60189:22:0;60108:111;74333:17;74325:61;;;;-1:-1:-1;;;74325:61:0;;9264:2:1;74325:61:0;;;9246:21:1;9303:2;9283:18;;;9276:30;9342:33;9322:18;;;9315:61;9393:18;;74325:61:0;9062:355:1;74325:61:0;74400:8;;;;;;;74397:69;;74441:13;74434:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74225:484;;;:::o;74397:69::-;74476:26;74505:10;:8;:10::i;:::-;74526:28;;;;;;;;;;;;-1:-1:-1;;;74526:28:0;;;;74572:26;;74476:39;;-1:-1:-1;74526:28:0;74572:129;;;;;;;;;;;;;;;;;74642:12;74656:19;:8;:17;:19::i;:::-;74677:4;74625:57;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;74572:129;74565:136;74225:484;-1:-1:-1;;;;74225:484:0:o;70356:874::-;68537:8;;;;68529:34;;;;-1:-1:-1;;;68529:34:0;;12656:2:1;68529:34:0;;;12638:21:1;12695:2;12675:18;;;12668:30;-1:-1:-1;;;12714:18:1;;;12707:43;12767:18;;68529:34:0;12454:337:1;68529:34:0;70480:13:::1;::::0;;;::::1;;;:21;;70497:4;70480:21;70472:57;;;::::0;-1:-1:-1;;;70472:57:0;;9976:2:1;70472:57:0::1;::::0;::::1;9958:21:1::0;10015:2;9995:18;;;9988:30;-1:-1:-1;;;10034:18:1;;;10027:54;10098:18;;70472:57:0::1;9774:348:1::0;70472:57:0::1;70567:28;::::0;-1:-1:-1;;70584:10:0::1;6220:2:1::0;6216:15;6212:53;70567:28:0::1;::::0;::::1;6200:66:1::0;70542:12:0::1;::::0;6282::1;;70567:28:0::1;;;;;;;;;;;;70557:39;;;;;;70542:54;;70615:50;70634:12;;70615:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;70648:10:0::1;::::0;;-1:-1:-1;70660:4:0;;-1:-1:-1;70615:18:0::1;:50::i;:::-;70607:78;;;::::0;-1:-1:-1;;;70607:78:0;;16488:2:1;70607:78:0::1;::::0;::::1;16470:21:1::0;16527:2;16507:18;;;16500:30;-1:-1:-1;;;16546:18:1;;;16539:45;16601:18;;70607:78:0::1;16286:339:1::0;70607:78:0::1;70712:10;70698:11;70750:14:::0;;;:9:::1;:14;::::0;;;;;70807:13:::1;::::0;70783:20:::1;70792:11:::0;70750:14;70783:20:::1;:::i;:::-;:37;;70775:63;;;::::0;-1:-1:-1;;;70775:63:0;;16832:2:1;70775:63:0::1;::::0;::::1;16814:21:1::0;16871:2;16851:18;;;16844:30;-1:-1:-1;;;16890:18:1;;;16883:43;16943:18;;70775:63:0::1;16630:337:1::0;70775:63:0::1;70872:21;;70857:11;:36;;70849:66;;;::::0;-1:-1:-1;;;70849:66:0;;15007:2:1;70849:66:0::1;::::0;::::1;14989:21:1::0;15046:2;15026:18;;;15019:30;-1:-1:-1;;;15065:18:1;;;15058:47;15122:18;;70849:66:0::1;14805:341:1::0;70849:66:0::1;70978:13;;70966:9;;:25;;;;:::i;:::-;70950:11;70934:13;53269:7:::0;53296:12;;53216:100;70934:13:::1;:27;;;;:::i;:::-;:58;;70926:87;;;;-1:-1:-1::0;;;70926:87:0::1;;;;;;;:::i;:::-;71026:13;71042:9;:7;:9::i;:::-;71026:25:::0;-1:-1:-1;71085:19:0::1;71093:11:::0;71026:25;71085:19:::1;:::i;:::-;71072:9;:32;;71064:63;;;::::0;-1:-1:-1;;;71064:63:0;;17577:2:1;71064:63:0::1;::::0;::::1;17559:21:1::0;17616:2;17596:18;;;17589:30;-1:-1:-1;;;17635:18:1;;;17628:48;17693:18;;71064:63:0::1;17375:342:1::0;71064:63:0::1;71157:20;71166:11:::0;71157:6;:20:::1;:::i;:::-;-1:-1:-1::0;;;;;71140:14:0;::::1;;::::0;;;:9:::1;:14;::::0;;;;:37;71188:34:::1;71198:10;71210:11:::0;71188:9:::1;:34::i;:::-;70461:769;;;;70356:874:::0;;;:::o;68948:118::-;2047:13;:11;:13::i;:::-;69026::::1;:32:::0;;;::::1;;::::0;::::1;-1:-1:-1::0;;69026:32:0;;::::1;::::0;;;::::1;::::0;;68948:118::o;3067:201::-;2047:13;:11;:13::i;:::-;-1:-1:-1;;;;;3156:22:0;::::1;3148:73;;;::::0;-1:-1:-1;;;3148:73:0;;10329:2:1;3148:73:0::1;::::0;::::1;10311:21:1::0;10368:2;10348:18;;;10341:30;10407:34;10387:18;;;10380:62;-1:-1:-1;;;10458:18:1;;;10451:36;10504:19;;3148:73:0::1;10127:402:1::0;3148:73:0::1;3232:28;3251:8;3232:18;:28::i;73781:130::-:0;2047:13;:11;:13::i;:::-;73870:33;;::::1;::::0;:13:::1;::::0;:33:::1;::::0;::::1;::::0;::::1;:::i;63954:196::-:0;64069:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;64069:29:0;-1:-1:-1;;;;;64069:29:0;;;;;;;;;64114:28;;64069:24;;64114:28;;;;;;;63954:196;;;:::o;2326:132::-;2234:6;;-1:-1:-1;;;;;2234:6:0;792:10;2390:23;2382:68;;;;-1:-1:-1;;;2382:68:0;;15353:2:1;2382:68:0;;;15335:21:1;;;15372:18;;;15365:30;15431:34;15411:18;;;15404:62;15483:18;;2382:68:0;15151:356:1;60227:104:0;60296:27;60306:2;60310:8;60296:27;;;;;;;;;;;;:9;:27::i;62262:1574::-;62377:35;62415:20;62427:7;62415:11;:20::i;:::-;62490:18;;62377:58;;-1:-1:-1;62448:22:0;;-1:-1:-1;;;;;62474:34:0;792:10;-1:-1:-1;;;;;62474:34:0;;:87;;;-1:-1:-1;792:10:0;62525:20;62537:7;62525:11;:20::i;:::-;-1:-1:-1;;;;;62525:36:0;;62474:87;:154;;;-1:-1:-1;62595:18:0;;62578:50;;792:10;58786:164;:::i;62578:50::-;62448:181;;62650:17;62642:80;;;;-1:-1:-1;;;62642:80:0;;16069:2:1;62642:80:0;;;16051:21:1;16108:2;16088:18;;;16081:30;16147:34;16127:18;;;16120:62;-1:-1:-1;;;16198:18:1;;;16191:48;16256:19;;62642:80:0;15867:414:1;62642:80:0;62765:4;-1:-1:-1;;;;;62743:26:0;:13;:18;;;-1:-1:-1;;;;;62743:26:0;;62735:77;;;;-1:-1:-1;;;62735:77:0;;14600:2:1;62735:77:0;;;14582:21:1;14639:2;14619:18;;;14612:30;14678:34;14658:18;;;14651:62;-1:-1:-1;;;14729:18:1;;;14722:36;14775:19;;62735:77:0;14398:402:1;62735:77:0;-1:-1:-1;;;;;62831:16:0;;62823:66;;;;-1:-1:-1;;;62823:66:0;;11895:2:1;62823:66:0;;;11877:21:1;11934:2;11914:18;;;11907:30;11973:34;11953:18;;;11946:62;-1:-1:-1;;;12024:18:1;;;12017:35;12069:19;;62823:66:0;11693:401:1;62823:66:0;63010:49;63027:1;63031:7;63040:13;:18;;;63010:8;:49::i;:::-;-1:-1:-1;;;;;63072:18:0;;;;;;:12;:18;;;;;:31;;63102:1;;63072:18;:31;;63102:1;;-1:-1:-1;;;;;63072:31:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;63072:31:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;63114:16:0;;-1:-1:-1;63114:16:0;;;:12;:16;;;;;:29;;-1:-1:-1;;;63114:16:0;;:29;;-1:-1:-1;;63114:29:0;;:::i;:::-;;;-1:-1:-1;;;;;63114:29:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63177:43:0;;;;;;;;-1:-1:-1;;;;;63177:43:0;;;;;-1:-1:-1;;;;;63203:15:0;63177:43;;;;;;;;;-1:-1:-1;63154:20:0;;;:11;:20;;;;;;:66;;;;;;;;;-1:-1:-1;;;63154:66:0;-1:-1:-1;;;;;;63154:66:0;;;;;;;;;;;63482:11;63166:7;-1:-1:-1;63482:11:0;:::i;:::-;63549:1;63508:24;;;:11;:24;;;;;:29;63460:33;;-1:-1:-1;;;;;;63508:29:0;63504:227;;63572:20;63580:11;60165:4;60199:12;-1:-1:-1;60189:22:0;60108:111;63572:20;63568:152;;;63640:64;;;;;;;;63655:18;;-1:-1:-1;;;;;63640:64:0;;;;;;63675:28;;;;-1:-1:-1;;;;;63640:64:0;;;;;;;;;-1:-1:-1;63613:24:0;;;:11;:24;;;;;;;:91;;;;;;;;;-1:-1:-1;;;63613:91:0;-1:-1:-1;;;;;;63613:91:0;;;;;;;;;;;;63568:152;63767:7;63763:2;-1:-1:-1;;;;;63748:27:0;63757:4;-1:-1:-1;;;;;63748:27:0;;;;;;;;;;;63786:42;62366:1470;;;62262:1574;;;:::o;64314:885::-;64408:24;;64451:12;64443:49;;;;-1:-1:-1;;;64443:49:0;;13835:2:1;64443:49:0;;;13817:21:1;13874:2;13854:18;;;13847:30;13913:26;13893:18;;;13886:54;13957:18;;64443:49:0;13633:348:1;64443:49:0;64503:16;64553:1;64522:28;64542:8;64522:17;:28;:::i;:::-;:32;;;;:::i;:::-;64503:51;;64595:1;64580:12;;:16;;;;:::i;:::-;64569:8;:27;64565:87;;;64639:1;64624:12;;:16;;;;:::i;:::-;64613:27;;64565:87;64775:17;64783:8;60165:4;60199:12;-1:-1:-1;60189:22:0;60108:111;64775:17;64767:68;;;;-1:-1:-1;;;64767:68:0;;19864:2:1;64767:68:0;;;19846:21:1;19903:2;19883:18;;;19876:30;19942:34;19922:18;;;19915:62;-1:-1:-1;;;19993:18:1;;;19986:36;20039:19;;64767:68:0;19662:402:1;64767:68:0;64863:17;64846:296;64887:8;64882:1;:13;64846:296;;64952:1;64921:14;;;:11;:14;;;;;:19;-1:-1:-1;;;;;64921:19:0;64917:214;;64975:31;65009:14;65021:1;65009:11;:14::i;:::-;65059:56;;;;;;;;65074:14;;-1:-1:-1;;;;;65059:56:0;;;;;;65090:24;;;;-1:-1:-1;;;;;65059:56:0;;;;;;;;;-1:-1:-1;65042:14:0;;;:11;:14;;;;;;;:73;;;;;;;;;-1:-1:-1;;;65042:73:0;-1:-1:-1;;;;;;65042:73:0;;;;;;;;;;;;-1:-1:-1;64917:214:0;64897:3;;;;:::i;:::-;;;;64846:296;;;-1:-1:-1;65179:12:0;:8;65190:1;65179:12;:::i;:::-;65152:24;:39;-1:-1:-1;;;64314:885:0:o;55677:650::-;-1:-1:-1;;;;;;;;;;;;;;;;;55780:16:0;55788:7;60165:4;60199:12;-1:-1:-1;60189:22:0;60108:111;55780:16;55772:71;;;;-1:-1:-1;;;55772:71:0;;11080:2:1;55772:71:0;;;11062:21:1;11119:2;11099:18;;;11092:30;11158:34;11138:18;;;11131:62;-1:-1:-1;;;11209:18:1;;;11202:40;11259:19;;55772:71:0;10878:406:1;55772:71:0;55856:26;55908:12;55897:7;:23;55893:103;;55958:22;55968:12;55958:7;:22;:::i;:::-;:26;;55983:1;55958:26;:::i;:::-;55937:47;;55893:103;56028:7;56008:242;56045:18;56037:4;:26;56008:242;;56088:31;56122:17;;;:11;:17;;;;;;;;;56088:51;;;;;;;;;-1:-1:-1;;;;;56088:51:0;;;;;-1:-1:-1;;;56088:51:0;;;-1:-1:-1;;;;;56088:51:0;;;;;;;;56158:28;56154:85;;56214:9;55677:650;-1:-1:-1;;;;55677:650:0:o;56154:85::-;-1:-1:-1;56065:6:0;;;;:::i;:::-;;;;56008:242;;;-1:-1:-1;56262:57:0;;-1:-1:-1;;;56262:57:0;;20271:2:1;56262:57:0;;;20253:21:1;20310:2;20290:18;;;20283:30;20349:34;20329:18;;;20322:62;-1:-1:-1;;;20400:18:1;;;20393:45;20455:19;;56262:57:0;20069:411:1;3428:191:0;3521:6;;;-1:-1:-1;;;;;3538:17:0;;;-1:-1:-1;;;;;;3538:17:0;;;;;;;3571:40;;3521:6;;;3538:17;3521:6;;3571:40;;3502:16;;3571:40;3491:128;3428:191;:::o;65764:804::-;65919:4;-1:-1:-1;;;;;65940:13:0;;12643:20;12691:8;65936:625;;65976:72;;-1:-1:-1;;;65976:72:0;;-1:-1:-1;;;;;65976:36:0;;;;;:72;;792:10;;66027:4;;66033:7;;66042:5;;65976:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65976:72:0;;;;;;;;-1:-1:-1;;65976:72:0;;;;;;;;;;;;:::i;:::-;;;65972:534;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66222:13:0;;66218:273;;66265:61;;-1:-1:-1;;;66265:61:0;;;;;;;:::i;66218:273::-;66441:6;66435:13;66426:6;66422:2;66418:15;66411:38;65972:534;-1:-1:-1;;;;;;66099:55:0;-1:-1:-1;;;66099:55:0;;-1:-1:-1;66092:62:0;;65936:625;-1:-1:-1;66545:4:0;65764:804;;;;;;:::o;74717:108::-;74777:13;74810:7;74803:14;;;;;:::i;18281:723::-;18337:13;18558:10;18554:53;;-1:-1:-1;;18585:10:0;;;;;;;;;;;;-1:-1:-1;;;18585:10:0;;;;;18281:723::o;18554:53::-;18632:5;18617:12;18673:78;18680:9;;18673:78;;18706:8;;;;:::i;:::-;;-1:-1:-1;18729:10:0;;-1:-1:-1;18737:2:0;18729:10;;:::i;:::-;;;18673:78;;;18761:19;18793:6;-1:-1:-1;;;;;18783:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18783:17:0;;18761:39;;18811:154;18818:10;;18811:154;;18845:11;18855:1;18845:11;;:::i;:::-;;-1:-1:-1;18914:10:0;18922:2;18914:5;:10;:::i;:::-;18901:24;;:2;:24;:::i;:::-;18888:39;;18871:6;18878;18871:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;18871:56:0;;;;;;;;-1:-1:-1;18942:11:0;18951:2;18942:11;;:::i;:::-;;;18811:154;;4845:190;4970:4;5023;4994:25;5007:5;5014:4;4994:12;:25::i;:::-;:33;;4845:190;-1:-1:-1;;;;4845:190:0:o;60608:1400::-;60731:20;60754:12;-1:-1:-1;;;;;60785:16:0;;60777:62;;;;-1:-1:-1;;;60777:62:0;;19047:2:1;60777:62:0;;;19029:21:1;19086:2;19066:18;;;19059:30;19125:34;19105:18;;;19098:62;-1:-1:-1;;;19176:18:1;;;19169:31;19217:19;;60777:62:0;18845:397:1;60777:62:0;60984:21;60992:12;60165:4;60199:12;-1:-1:-1;60189:22:0;60108:111;60984:21;60983:22;60975:64;;;;-1:-1:-1;;;60975:64:0;;18344:2:1;60975:64:0;;;18326:21:1;18383:2;18363:18;;;18356:30;18422:31;18402:18;;;18395:59;18471:18;;60975:64:0;18142:353:1;60975:64:0;61070:12;61058:8;:24;;61050:71;;;;-1:-1:-1;;;61050:71:0;;21101:2:1;61050:71:0;;;21083:21:1;21140:2;21120:18;;;21113:30;21179:34;21159:18;;;21152:62;-1:-1:-1;;;21230:18:1;;;21223:32;21272:19;;61050:71:0;20899:398:1;61050:71:0;-1:-1:-1;;;;;61241:16:0;;61208:30;61241:16;;;:12;:16;;;;;;;;;61208:49;;;;;;;;;-1:-1:-1;;;;;61208:49:0;;;;;-1:-1:-1;;;61208:49:0;;;;;;;;;;;61287:135;;;;;;;;61313:19;;61208:49;;61287:135;;;61313:39;;61343:8;;61313:39;:::i;:::-;-1:-1:-1;;;;;61287:135:0;;;;;61402:8;61367:11;:24;;;:44;;;;:::i;:::-;-1:-1:-1;;;;;61287:135:0;;;;;;-1:-1:-1;;;;;61268:16:0;;;;;;;:12;:16;;;;;;;;:154;;;;;;;;-1:-1:-1;;;61268:154:0;;;;;;;;;;;;61461:43;;;;;;;;;;-1:-1:-1;;;;;61487:15:0;61461:43;;;;;;;;61433:25;;;:11;:25;;;;;;:71;;;;;;;;;-1:-1:-1;;;61433:71:0;-1:-1:-1;;;;;;61433:71:0;;;;;;;;;;;;;;;;;;61445:12;;61565:325;61589:8;61585:1;:12;61565:325;;;61624:38;;61649:12;;-1:-1:-1;;;;;61624:38:0;;;61641:1;;61624:38;;61641:1;;61624:38;61703:59;61734:1;61738:2;61742:12;61756:5;61703:22;:59::i;:::-;61677:172;;;;-1:-1:-1;;;61677:172:0;;;;;;;:::i;:::-;61864:14;;;;:::i;:::-;;;;61599:3;;;;;:::i;:::-;;;;61565:325;;;-1:-1:-1;61902:12:0;:27;;;61940:60;69647:675;5712:296;5795:7;5838:4;5795:7;5853:118;5877:5;:12;5873:1;:16;5853:118;;;5926:33;5936:12;5950:5;5956:1;5950:8;;;;;;;;:::i;:::-;;;;;;;5926:9;:33::i;:::-;5911:48;-1:-1:-1;5891:3:0;;;;:::i;:::-;;;;5853:118;;;-1:-1:-1;5988:12:0;5712:296;-1:-1:-1;;;5712:296:0:o;11919:149::-;11982:7;12013:1;12009;:5;:51;;12144:13;12238:15;;;12274:4;12267:15;;;12321:4;12305:21;;12009:51;;;12144:13;12238:15;;;12274:4;12267:15;;;12321:4;12305:21;;12017:20;12002:58;11919:149;-1:-1:-1;;;11919:149:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:631:1;78:5;-1:-1:-1;;;;;149:2:1;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:173::-;718:20;;-1:-1:-1;;;;;767:31:1;;757:42;;747:70;;813:1;810;803:12;747:70;650:173;;;:::o;828:367::-;891:8;901:6;955:3;948:4;940:6;936:17;932:27;922:55;;973:1;970;963:12;922:55;-1:-1:-1;996:20:1;;-1:-1:-1;;;;;1028:30:1;;1025:50;;;1071:1;1068;1061:12;1025:50;1108:4;1100:6;1096:17;1084:29;;1168:3;1161:4;1151:6;1148:1;1144:14;1136:6;1132:27;1128:38;1125:47;1122:67;;;1185:1;1182;1175:12;1122:67;828:367;;;;;:::o;1200:160::-;1265:20;;1321:13;;1314:21;1304:32;;1294:60;;1350:1;1347;1340:12;1365:186;1424:6;1477:2;1465:9;1456:7;1452:23;1448:32;1445:52;;;1493:1;1490;1483:12;1445:52;1516:29;1535:9;1516:29;:::i;1556:260::-;1624:6;1632;1685:2;1673:9;1664:7;1660:23;1656:32;1653:52;;;1701:1;1698;1691:12;1653:52;1724:29;1743:9;1724:29;:::i;:::-;1714:39;;1772:38;1806:2;1795:9;1791:18;1772:38;:::i;:::-;1762:48;;1556:260;;;;;:::o;1821:328::-;1898:6;1906;1914;1967:2;1955:9;1946:7;1942:23;1938:32;1935:52;;;1983:1;1980;1973:12;1935:52;2006:29;2025:9;2006:29;:::i;:::-;1996:39;;2054:38;2088:2;2077:9;2073:18;2054:38;:::i;:::-;2044:48;;2139:2;2128:9;2124:18;2111:32;2101:42;;1821:328;;;;;:::o;2154:666::-;2249:6;2257;2265;2273;2326:3;2314:9;2305:7;2301:23;2297:33;2294:53;;;2343:1;2340;2333:12;2294:53;2366:29;2385:9;2366:29;:::i;:::-;2356:39;;2414:38;2448:2;2437:9;2433:18;2414:38;:::i;:::-;2404:48;;2499:2;2488:9;2484:18;2471:32;2461:42;;2554:2;2543:9;2539:18;2526:32;-1:-1:-1;;;;;2573:6:1;2570:30;2567:50;;;2613:1;2610;2603:12;2567:50;2636:22;;2689:4;2681:13;;2677:27;-1:-1:-1;2667:55:1;;2718:1;2715;2708:12;2667:55;2741:73;2806:7;2801:2;2788:16;2783:2;2779;2775:11;2741:73;:::i;:::-;2731:83;;;2154:666;;;;;;;:::o;2825:254::-;2890:6;2898;2951:2;2939:9;2930:7;2926:23;2922:32;2919:52;;;2967:1;2964;2957:12;2919:52;2990:29;3009:9;2990:29;:::i;:::-;2980:39;;3038:35;3069:2;3058:9;3054:18;3038:35;:::i;3084:254::-;3152:6;3160;3213:2;3201:9;3192:7;3188:23;3184:32;3181:52;;;3229:1;3226;3219:12;3181:52;3252:29;3271:9;3252:29;:::i;:::-;3242:39;3328:2;3313:18;;;;3300:32;;-1:-1:-1;;;3084:254:1:o;3343:437::-;3429:6;3437;3490:2;3478:9;3469:7;3465:23;3461:32;3458:52;;;3506:1;3503;3496:12;3458:52;3546:9;3533:23;-1:-1:-1;;;;;3571:6:1;3568:30;3565:50;;;3611:1;3608;3601:12;3565:50;3650:70;3712:7;3703:6;3692:9;3688:22;3650:70;:::i;:::-;3739:8;;3624:96;;-1:-1:-1;3343:437:1;-1:-1:-1;;;;3343:437:1:o;3785:180::-;3841:6;3894:2;3882:9;3873:7;3869:23;3865:32;3862:52;;;3910:1;3907;3900:12;3862:52;3933:26;3949:9;3933:26;:::i;3970:180::-;4029:6;4082:2;4070:9;4061:7;4057:23;4053:32;4050:52;;;4098:1;4095;4088:12;4050:52;-1:-1:-1;4121:23:1;;3970:180;-1:-1:-1;3970:180:1:o;4155:245::-;4213:6;4266:2;4254:9;4245:7;4241:23;4237:32;4234:52;;;4282:1;4279;4272:12;4234:52;4321:9;4308:23;4340:30;4364:5;4340:30;:::i;4405:249::-;4474:6;4527:2;4515:9;4506:7;4502:23;4498:32;4495:52;;;4543:1;4540;4533:12;4495:52;4575:9;4569:16;4594:30;4618:5;4594:30;:::i;4659:450::-;4728:6;4781:2;4769:9;4760:7;4756:23;4752:32;4749:52;;;4797:1;4794;4787:12;4749:52;4837:9;4824:23;-1:-1:-1;;;;;4862:6:1;4859:30;4856:50;;;4902:1;4899;4892:12;4856:50;4925:22;;4978:4;4970:13;;4966:27;-1:-1:-1;4956:55:1;;5007:1;5004;4997:12;4956:55;5030:73;5095:7;5090:2;5077:16;5072:2;5068;5064:11;5030:73;:::i;5299:505::-;5394:6;5402;5410;5463:2;5451:9;5442:7;5438:23;5434:32;5431:52;;;5479:1;5476;5469:12;5431:52;5515:9;5502:23;5492:33;;5576:2;5565:9;5561:18;5548:32;-1:-1:-1;;;;;5595:6:1;5592:30;5589:50;;;5635:1;5632;5625:12;5589:50;5674:70;5736:7;5727:6;5716:9;5712:22;5674:70;:::i;:::-;5299:505;;5763:8;;-1:-1:-1;5648:96:1;;-1:-1:-1;;;;5299:505:1:o;5809:257::-;5850:3;5888:5;5882:12;5915:6;5910:3;5903:19;5931:63;5987:6;5980:4;5975:3;5971:14;5964:4;5957:5;5953:16;5931:63;:::i;:::-;6048:2;6027:15;-1:-1:-1;;6023:29:1;6014:39;;;;6055:4;6010:50;;5809:257;-1:-1:-1;;5809:257:1:o;6305:664::-;6532:3;6570:6;6564:13;6586:53;6632:6;6627:3;6620:4;6612:6;6608:17;6586:53;:::i;:::-;6702:13;;6661:16;;;;6724:57;6702:13;6661:16;6758:4;6746:17;;6724:57;:::i;:::-;6848:13;;6803:20;;;6870:57;6848:13;6803:20;6904:4;6892:17;;6870:57;:::i;:::-;6943:20;;6305:664;-1:-1:-1;;;;;6305:664:1:o;7392:488::-;-1:-1:-1;;;;;7661:15:1;;;7643:34;;7713:15;;7708:2;7693:18;;7686:43;7760:2;7745:18;;7738:34;;;7808:3;7803:2;7788:18;;7781:31;;;7586:4;;7829:45;;7854:19;;7846:6;7829:45;:::i;:::-;7821:53;7392:488;-1:-1:-1;;;;;;7392:488:1:o;8077:219::-;8226:2;8215:9;8208:21;8189:4;8246:44;8286:2;8275:9;8271:18;8263:6;8246:44;:::i;17722:415::-;17924:2;17906:21;;;17963:2;17943:18;;;17936:30;18002:34;17997:2;17982:18;;17975:62;-1:-1:-1;;;18068:2:1;18053:18;;18046:49;18127:3;18112:19;;17722:415::o;18500:340::-;18702:2;18684:21;;;18741:2;18721:18;;;18714:30;-1:-1:-1;;;18775:2:1;18760:18;;18753:46;18831:2;18816:18;;18500:340::o;21484:253::-;21524:3;-1:-1:-1;;;;;21613:2:1;21610:1;21606:10;21643:2;21640:1;21636:10;21674:3;21670:2;21666:12;21661:3;21658:21;21655:47;;;21682:18;;:::i;:::-;21718:13;;21484:253;-1:-1:-1;;;;21484:253:1:o;21742:128::-;21782:3;21813:1;21809:6;21806:1;21803:13;21800:39;;;21819:18;;:::i;:::-;-1:-1:-1;21855:9:1;;21742:128::o;21875:120::-;21915:1;21941;21931:35;;21946:18;;:::i;:::-;-1:-1:-1;21980:9:1;;21875:120::o;22000:168::-;22040:7;22106:1;22102;22098:6;22094:14;22091:1;22088:21;22083:1;22076:9;22069:17;22065:45;22062:71;;;22113:18;;:::i;:::-;-1:-1:-1;22153:9:1;;22000:168::o;22173:246::-;22213:4;-1:-1:-1;;;;;22326:10:1;;;;22296;;22348:12;;;22345:38;;;22363:18;;:::i;:::-;22400:13;;22173:246;-1:-1:-1;;;22173:246:1:o;22424:125::-;22464:4;22492:1;22489;22486:8;22483:34;;;22497:18;;:::i;:::-;-1:-1:-1;22534:9:1;;22424:125::o;22554:258::-;22626:1;22636:113;22650:6;22647:1;22644:13;22636:113;;;22726:11;;;22720:18;22707:11;;;22700:39;22672:2;22665:10;22636:113;;;22767:6;22764:1;22761:13;22758:48;;;-1:-1:-1;;22802:1:1;22784:16;;22777:27;22554:258::o;22817:136::-;22856:3;22884:5;22874:39;;22893:18;;:::i;:::-;-1:-1:-1;;;22929:18:1;;22817:136::o;22958:380::-;23037:1;23033:12;;;;23080;;;23101:61;;23155:4;23147:6;23143:17;23133:27;;23101:61;23208:2;23200:6;23197:14;23177:18;23174:38;23171:161;;;23254:10;23249:3;23245:20;23242:1;23235:31;23289:4;23286:1;23279:15;23317:4;23314:1;23307:15;23171:161;;22958:380;;;:::o;23343:135::-;23382:3;-1:-1:-1;;23403:17:1;;23400:43;;;23423:18;;:::i;:::-;-1:-1:-1;23470:1:1;23459:13;;23343:135::o;23483:112::-;23515:1;23541;23531:35;;23546:18;;:::i;:::-;-1:-1:-1;23580:9:1;;23483:112::o;23600:127::-;23661:10;23656:3;23652:20;23649:1;23642:31;23692:4;23689:1;23682:15;23716:4;23713:1;23706:15;23732:127;23793:10;23788:3;23784:20;23781:1;23774:31;23824:4;23821:1;23814:15;23848:4;23845:1;23838:15;23864:127;23925:10;23920:3;23916:20;23913:1;23906:31;23956:4;23953:1;23946:15;23980:4;23977:1;23970:15;23996:127;24057:10;24052:3;24048:20;24045:1;24038:31;24088:4;24085:1;24078:15;24112:4;24109:1;24102:15;24128:131;-1:-1:-1;;;;;;24202:32:1;;24192:43;;24182:71;;24249:1;24246;24239:12
Swarm Source
ipfs://3e41b2cd24d1853750011a7da6f1bbbd267c5679b68ce6795eb2cc26ab9b4855
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.