ETH Price: $3,103.61 (-3.28%)
Gas: 6 Gwei

Token

3GMAIPFP (3GMAIPFP)
 

Overview

Max Total Supply

3,198 3GMAIPFP

Holders

929

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3 3GMAIPFP
0x535cb66298184f0297fcb18d7633ec0065e679ee
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
ThreeGMAIPFP

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-06-28
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/**

      /$$$$$$   /$$$$$$  /$$      /$$
     /$$__  $$ /$$__  $$| $$$    /$$$
    |__/  \ $$| $$  \__/| $$$$  /$$$$
       /$$$$$/| $$ /$$$$| $$ $$/$$ $$
      |___  $$| $$|_  $$| $$  $$$| $$
     /$$  \ $$| $$  \ $$| $$\  $ | $$
    |  $$$$$$/|  $$$$$$/| $$ \/  | $$
    \______/  \______/ |__/     |__/


    ** Website
       https://3gm.dev/

    ** Twitter
       https://twitter.com/3gmdev

**/


// OpenZeppelin Contracts (last updated v4.6.0) (utils/cryptography/MerkleProof.sol)



/**
 * @dev These functions deal with verification of Merkle Trees 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 a `leafs` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, `proofs` for each leaf must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Then
     * 'proofFlag' designates the nodes needed for the multi proof.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32 root,
        bytes32[] calldata leaves,
        bytes32[] calldata proofs,
        bool[] calldata proofFlag
    ) internal pure returns (bool) {
        return processMultiProof(leaves, proofs, proofFlag) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using the multi proof as `proofFlag`. A multi proof is
     * valid if the final hash matches the root of the tree.
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] calldata leaves,
        bytes32[] calldata proofs,
        bool[] calldata proofFlag
    ) 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 = proofFlag.length;

        // Check proof validity.
        require(leavesLen + proofs.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
        //   `proofs` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlag[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proofs[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proofs[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)
        }
    }
}


// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)



/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)




// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)



/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


/**
 * @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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        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);
    }
}


// ERC721A Contracts v4.1.0
// Creator: Chiru Labs




// ERC721A Contracts v4.1.0
// Creator: Chiru Labs



/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set through `_extraData`.
        uint24 extraData;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

    // ==============================
    //            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);

    // ==============================
    //            IERC721
    // ==============================

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must 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 Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    // ==============================
    //        IERC721Metadata
    // ==============================

    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);

    // ==============================
    //            IERC2309
    // ==============================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId` (inclusive) is transferred from `from` to `to`,
     * as defined in the ERC2309 standard. See `_mintERC2309` for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}


/**
 * @dev ERC721 token receiver interface.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard,
 * including the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at `_startTokenId()`
 * (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Mask of an entry in packed address data.
    uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with `_mintERC2309`.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to `_mintERC2309`
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The tokenId of the next token to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See `_packedOwnershipOf` implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

    // Mapping from token ID to approved address.
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see `_totalMinted`.
     */
    function totalSupply() public view override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to `_startTokenId()`
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view returns (uint256) {
        return _burnCounter;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes of the XOR of
        // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165
        // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            //if (_startTokenId() <= curr)
                //if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                //}
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
        ownership.burned = packed & BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> BITPOS_EXTRA_DATA);
    }

    /**
     * Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, BITMASK_ADDRESS)
            // `owner | (block.timestamp << BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @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) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << BITPOS_NEXT_INITIALIZED`.
            result := shl(BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = ownerOf(tokenId);

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), 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-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 {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @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) {
        if(_packedOwnerships[tokenId] != 0){
            return _packedOwnerships[tokenId] & BITMASK_BURNED == 0;
        }
        return false;
        /* return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned. */
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 tokenId = startTokenId;
            uint256 end = startTokenId + quantity;
            do {
                emit Transfer(address(0), to, tokenId++);
            } while (tokenId < end);

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `tokenIds` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenIds` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mintSpecifics(address to, uint256[] memory tokenIds) internal {
        uint256 quantity = tokenIds.length;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        // Updates:
        // - `balance += quantity`.
        // - `numberMinted += quantity`.
        //
        // We can directly add to the `balance` and `numberMinted`.
        _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

        for (uint256 i; i < tokenIds.length; i++) {
            // Overflows are incredibly unrealistic.
            // `balance` and `numberMinted` have a maximum limit of 2**64.
            // `tokenId` has a maximum limit of 2**256.
            unchecked {
                _beforeTokenTransfers(address(0), to, tokenIds[i], 1);
                // Updates:
                // - `address` to the owner.
                // - `startTimestamp` to the timestamp of minting.
                // - `burned` to `false`.
                // - `nextInitialized` to `quantity == 1`.
                _packedOwnerships[tokenIds[i]] = _packOwnershipData(
                    to,
                    _nextInitializedFlag(1) | _nextExtraData(address(0), to, 0)
                );

                emit Transfer(address(0), to, tokenIds[i]);
                _afterTokenTransfers(address(0), to, tokenIds[i], 1);
            }

        }
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals;
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`.
        assembly {
            // Compute the slot.
            mstore(0x00, tokenId)
            mstore(0x20, tokenApprovalsPtr.slot)
            approvedAddressSlot := keccak256(0x00, 0x40)
            // Load the slot's value from storage.
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    /**
     * @dev Returns whether the `approvedAddress` is equals to `from` or `msgSender`.
     */
    function _isOwnerOrApproved(
        address approvedAddress,
        address from,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
            from := and(from, BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, BITMASK_ADDRESS)
            // `msgSender == from || msgSender == approvedAddress`.
            result := or(eq(msgSender, from), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @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 transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (BITMASK_BURNED | BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << BITPOS_EXTRA_DATA;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred.
     * This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred.
     * This includes minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function _toString(uint256 value) internal pure returns (string memory ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

            // Cache the end of the memory to calculate the length later.
            let end := ptr

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for {
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp {
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } {
                // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }

            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}


contract ThreeGMAIPFP is ERC721A, Ownable {

    string public baseURI = "";
    string public contractURI = "";
    uint256 constant public MAX_SUPPLY = 5000;
    uint256 public PUBLIC_SUPPLY = 2000;
    bytes32 public whitelistMerkle = 0xd6b7ab9c29363efd9448bb78e592fe0d6d77aa10a2034690bbe3a26af23007d2;

    uint256 public txLimit = 5;
    uint256 public walletLimit = 10;
    uint256 public price = 0.02 ether;

    bool public claimPaused = true;
    bool public whitelistPaused = true;
    bool public publicPaused = true;

    IERC721A threeGMGenesisPass = IERC721A(0xbB52d85C8dE311A031770b48dC9F91083E6D12B1);

    mapping(address => uint256) public claimedWhitelist;
    mapping(address => uint256) public walletMint;

    constructor() ERC721A("3GMAIPFP", "3GMAIPFP") {}

    function claimFromGenesis(uint256[] calldata _tokenIds) external {
      address _caller = _msgSender();
      require(!claimPaused || owner() == _caller, "Claim paused");
      require(tx.origin == _caller, "No contracts");

      for (uint256 i; i < _tokenIds.length; i++) {
          require(threeGMGenesisPass.ownerOf(_tokenIds[i]) == _caller, "Not owner of the token");
          require(!_exists(_tokenIds[i]), "Token already claimed.");

          uint256[] memory tokens = new uint256[](3);
          tokens[0] = _tokenIds[i];
          tokens[1] = _tokenIds[i] + 333;
          tokens[2] = _tokenIds[i] + 666;

          _mintSpecifics(_caller, tokens);
      }
    }

    function whitelist(uint256 _amountToMint, uint256 _maxAmount, bytes32[] calldata _merkleProof) external payable {
        require(!whitelistPaused, "Whitelist paused");
        require(MAX_SUPPLY >= totalSupply() + _amountToMint, "Exceeds max supply");
        require(_amountToMint > 0, "Not 0 mints");

        address _caller = _msgSender();
        require(tx.origin == _caller, "No contracts");
        require(claimedWhitelist[_caller] + _amountToMint <= _maxAmount, "Not allow to mint more");

        bytes32 leaf = keccak256(abi.encodePacked(_caller, _maxAmount));
        require(MerkleProof.verify(_merkleProof, whitelistMerkle, leaf), "Invalid proof");

        unchecked { claimedWhitelist[_caller] += _amountToMint; }
        _safeMint(_caller, _amountToMint);
    }

    function mint(uint256 _amountToMint) external payable {
        require(!publicPaused, "Public paused");
        require(MAX_SUPPLY >= totalSupply() + _amountToMint, "Exceeds max supply");
        require(PUBLIC_SUPPLY - _amountToMint >= 0, "Max public mints reached");
        require(_amountToMint > 0, "Not 0 mints");
        require(_amountToMint <= txLimit, "Tx limit");
        require(_amountToMint * price == msg.value, "Invalid funds provided");

        address _caller = _msgSender();
        require(tx.origin == _caller, "No contracts");
        require(walletMint[_caller] + _amountToMint <= walletLimit, "Not allow to mint more");

        unchecked {
          PUBLIC_SUPPLY -= _amountToMint;
          walletMint[_caller] += _amountToMint;
        }
        _safeMint(_caller, _amountToMint);
    }

    function _startTokenId() internal override view virtual returns (uint256) {
        return 1000;
    }

    function exists(uint256 _tokenId) public view returns (bool) {
        return _exists(_tokenId);
    }

    function minted(address _owner) public view returns (uint256) {
        return _numberMinted(_owner);
    }

    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        (bool success, ) = _msgSender().call{value: balance}("");
        require(success, "Failed to send");
    }

    function teamMint(address _to, uint256 _amount) external onlyOwner {
        _safeMint(_to, _amount);
    }

    function teamMintSpecific(address _to, uint256[] calldata _tokenIds) external onlyOwner {
      for (uint256 i; i < _tokenIds.length; i++) {
          require(!_exists(_tokenIds[i]), "Token already exist.");

          uint256[] memory tokens = new uint256[](3);
          tokens[0] = _tokenIds[i];
          tokens[1] = _tokenIds[i] + 333;
          tokens[2] = _tokenIds[i] + 666;

          _mintSpecifics(_to, tokens);
      }
    }

    function toggleClaim() external onlyOwner {
        claimPaused = !claimPaused;
    }

    function toggleWhitelist() external onlyOwner {
        whitelistPaused = !whitelistPaused;
    }

    function togglePublic() external onlyOwner {
        publicPaused = !publicPaused;
    }

    function setPublicSupply(uint256 _supply) external onlyOwner {
        PUBLIC_SUPPLY = _supply;
    }

    function setPrice(uint256 _price) external onlyOwner {
        price = _price;
    }

    function setTxLimit(uint256 _limit) external onlyOwner {
        txLimit = _limit;
    }

    function setWalletLimit(uint256 _limit) external onlyOwner {
        walletLimit = _limit;
    }

    function setWhitelistMerkle(bytes32 _merkle) external onlyOwner {
        whitelistMerkle = _merkle;
    }

    function setBaseURI(string memory baseURI_) external onlyOwner {
        baseURI = baseURI_;
    }

    function setContractURI(string memory _contractURI) external onlyOwner {
        contractURI = _contractURI;
    }

    function tokenURI(uint256 _tokenId) public view override returns (string memory) {
        require(_exists(_tokenId), "Token does not exist.");
        return bytes(baseURI).length > 0 ? string(
            abi.encodePacked(
              baseURI,
              Strings.toString(_tokenId),
              ".json"
            )
        ) : "";
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"claimFromGenesis","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimedWhitelist","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountToMint","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"minted","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":"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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_contractURI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"name":"setPublicSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setTxLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkle","type":"bytes32"}],"name":"setWhitelistMerkle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"teamMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"teamMintSpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleWhitelist","outputs":[],"stateMutability":"nonpayable","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":"txLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"walletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountToMint","type":"uint256"},{"internalType":"uint256","name":"_maxAmount","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"whitelist","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistMerkle","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040819052600060808190526200001b9160099162000178565b506040805160208101918290526000908190526200003c91600a9162000178565b506107d0600b557fd6b7ab9c29363efd9448bb78e592fe0d6d77aa10a2034690bbe3a26af23007d2600c556005600d55600a600e5566470de4df820000600f55601080546001600160b81b03191676bb52d85c8de311a031770b48dc9f91083e6d12b1010101179055348015620000b257600080fd5b50604080518082018252600880825267033474d41495046560c41b602080840182815285518087019096529285528401528151919291620000f69160029162000178565b5080516200010c90600390602084019062000178565b50506103e860005550620001203362000126565b6200025a565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805462000186906200021e565b90600052602060002090601f016020900481019282620001aa5760008555620001f5565b82601f10620001c557805160ff1916838001178555620001f5565b82800160010185558215620001f5579182015b82811115620001f5578251825591602001919060010190620001d8565b506200020392915062000207565b5090565b5b8082111562000203576000815560010162000208565b600181811c908216806200023357607f821691505b6020821081036200025457634e487b7160e01b600052602260045260246000fd5b50919050565b612a4a806200026a6000396000f3fe6080604052600436106102935760003560e01c8063715018a61161015a578063a91789e7116100c1578063cd8805531161007a578063cd88055314610798578063d1129745146107ae578063e8a3d485146107c3578063e985e9c5146107d8578063f1d5f51714610821578063f2fde38b1461084157600080fd5b8063a91789e7146106de578063ab5e124a146106fe578063add5a4fa14610718578063b88d4fde14610738578063c5b1501a14610758578063c87b56dd1461077857600080fd5b806394db17db1161011357806394db17db1461064b57806395d89b411461066b578063981d877114610680578063a035b1fe14610695578063a0712d68146106ab578063a22cb465146106be57600080fd5b8063715018a6146105ad5780637e15144b146105c25780638342083a146105d75780638da5cb5b146105ed57806391b7f5ed1461060b578063938e3d7b1461062b57600080fd5b80633c8463a1116101fe5780635efec59a116101b75780635efec59a146104f657806361e61a25146105235780636352211e146105425780636c0360eb146105625780636caae8321461057757806370a082311461058d57600080fd5b80633c8463a11461044b5780633ccfd60b1461046157806342842e0e146104765780634f558e791461049657806355f804b3146104b65780635c85974f146104d657600080fd5b80631181d7ac116102505780631181d7ac146103a457806318160ddd146103b75780631e7269c5146103d557806323b872dd146103f557806326aa420a1461041557806332cb6b0c1461043557600080fd5b806301ffc9a71461029857806306fdde03146102cd578063081812fc146102ef578063095ea7b3146103275780630bb12bb8146103495780631056ae3114610369575b600080fd5b3480156102a457600080fd5b506102b86102b336600461232a565b610861565b60405190151581526020015b60405180910390f35b3480156102d957600080fd5b506102e26108b3565b6040516102c4919061239f565b3480156102fb57600080fd5b5061030f61030a3660046123b2565b610945565b6040516001600160a01b0390911681526020016102c4565b34801561033357600080fd5b506103476103423660046123e0565b610989565b005b34801561035557600080fd5b506010546102b89062010000900460ff1681565b34801561037557600080fd5b5061039661038436600461240c565b60126020526000908152604090205481565b6040519081526020016102c4565b6103476103b2366004612475565b610a29565b3480156103c357600080fd5b50600154600054036103e71901610396565b3480156103e157600080fd5b506103966103f036600461240c565b610c91565b34801561040157600080fd5b506103476104103660046124c8565b610cbc565b34801561042157600080fd5b506103476104303660046123b2565b610e67565b34801561044157600080fd5b5061039661138881565b34801561045757600080fd5b50610396600e5481565b34801561046d57600080fd5b50610347610e96565b34801561048257600080fd5b506103476104913660046124c8565b610f4f565b3480156104a257600080fd5b506102b86104b13660046123b2565b610f6f565b3480156104c257600080fd5b506103476104d1366004612595565b610f7a565b3480156104e257600080fd5b506103476104f13660046123b2565b610fb7565b34801561050257600080fd5b5061039661051136600461240c565b60116020526000908152604090205481565b34801561052f57600080fd5b506010546102b890610100900460ff1681565b34801561054e57600080fd5b5061030f61055d3660046123b2565b610fe6565b34801561056e57600080fd5b506102e2610ff1565b34801561058357600080fd5b50610396600d5481565b34801561059957600080fd5b506103966105a836600461240c565b61107f565b3480156105b957600080fd5b506103476110ce565b3480156105ce57600080fd5b50610347611104565b3480156105e357600080fd5b50610396600b5481565b3480156105f957600080fd5b506008546001600160a01b031661030f565b34801561061757600080fd5b506103476106263660046123b2565b61114b565b34801561063757600080fd5b50610347610646366004612595565b61117a565b34801561065757600080fd5b506103476106663660046125de565b6111b7565b34801561067757600080fd5b506102e26114ad565b34801561068c57600080fd5b506103476114bc565b3480156106a157600080fd5b50610396600f5481565b6103476106b93660046123b2565b611505565b3480156106ca57600080fd5b506103476106d9366004612620565b61179a565b3480156106ea57600080fd5b506103476106f93660046123b2565b61182f565b34801561070a57600080fd5b506010546102b89060ff1681565b34801561072457600080fd5b506103476107333660046123e0565b61185e565b34801561074457600080fd5b5061034761075336600461265e565b611892565b34801561076457600080fd5b506103476107733660046126de565b6118d6565b34801561078457600080fd5b506102e26107933660046123b2565b611a66565b3480156107a457600080fd5b50610396600c5481565b3480156107ba57600080fd5b50610347611b11565b3480156107cf57600080fd5b506102e2611b4f565b3480156107e457600080fd5b506102b86107f3366004612733565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561082d57600080fd5b5061034761083c3660046123b2565b611b5c565b34801561084d57600080fd5b5061034761085c36600461240c565b611b8b565b60006301ffc9a760e01b6001600160e01b03198316148061089257506380ac58cd60e01b6001600160e01b03198316145b806108ad5750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600280546108c290612761565b80601f01602080910402602001604051908101604052809291908181526020018280546108ee90612761565b801561093b5780601f106109105761010080835404028352916020019161093b565b820191906000526020600020905b81548152906001019060200180831161091e57829003601f168201915b5050505050905090565b600061095082611c26565b61096d576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061099482610fe6565b9050336001600160a01b038216146109cd576109b081336107f3565b6109cd576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b601054610100900460ff1615610a795760405162461bcd60e51b815260206004820152601060248201526f15da1a5d195b1a5cdd081c185d5cd95960821b60448201526064015b60405180910390fd5b600154600054859190036103e71901610a9291906127b1565b6113881015610ad85760405162461bcd60e51b815260206004820152601260248201527145786365656473206d617820737570706c7960701b6044820152606401610a70565b60008411610b165760405162461bcd60e51b815260206004820152600b60248201526a4e6f742030206d696e747360a81b6044820152606401610a70565b33328114610b365760405162461bcd60e51b8152600401610a70906127c9565b6001600160a01b0381166000908152601160205260409020548490610b5c9087906127b1565b1115610ba35760405162461bcd60e51b81526020600482015260166024820152754e6f7420616c6c6f7720746f206d696e74206d6f726560501b6044820152606401610a70565b6040516bffffffffffffffffffffffff19606083901b16602082015260348101859052600090605401604051602081830303815290604052805190602001209050610c2584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c549150849050611c5c565b610c615760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610a70565b6001600160a01b0382166000908152601160205260409020805487019055610c898287611c72565b505050505050565b6001600160a01b0381166000908152600560205260408082205467ffffffffffffffff911c166108ad565b6000610cc782611c8c565b9050836001600160a01b0316816001600160a01b031614610cfa5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610d4757610d2a86336107f3565b610d4757604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610d6e57604051633a954ecd60e21b815260040160405180910390fd5b8015610d7957600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716815290812080546001019055610dcc9086905b600160e11b174260a01b176001600160a01b03919091161790565b600085815260046020526040812091909155600160e11b84169003610e2157600184016000818152600460205260408120549003610e1f576000548114610e1f5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610c89565b6008546001600160a01b03163314610e915760405162461bcd60e51b8152600401610a70906127ef565b600b55565b6008546001600160a01b03163314610ec05760405162461bcd60e51b8152600401610a70906127ef565b6040514790600090339083908381818185875af1925050503d8060008114610f04576040519150601f19603f3d011682016040523d82523d6000602084013e610f09565b606091505b5050905080610f4b5760405162461bcd60e51b815260206004820152600e60248201526d11985a5b1959081d1bc81cd95b9960921b6044820152606401610a70565b5050565b610f6a83838360405180602001604052806000815250611892565b505050565b60006108ad82611c26565b6008546001600160a01b03163314610fa45760405162461bcd60e51b8152600401610a70906127ef565b8051610f4b90600990602084019061227b565b6008546001600160a01b03163314610fe15760405162461bcd60e51b8152600401610a70906127ef565b600d55565b60006108ad82611c8c565b60098054610ffe90612761565b80601f016020809104026020016040519081016040528092919081815260200182805461102a90612761565b80156110775780601f1061104c57610100808354040283529160200191611077565b820191906000526020600020905b81548152906001019060200180831161105a57829003601f168201915b505050505081565b60006001600160a01b0382166110a8576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b6008546001600160a01b031633146110f85760405162461bcd60e51b8152600401610a70906127ef565b6111026000611ced565b565b6008546001600160a01b0316331461112e5760405162461bcd60e51b8152600401610a70906127ef565b6010805461ff001981166101009182900460ff1615909102179055565b6008546001600160a01b031633146111755760405162461bcd60e51b8152600401610a70906127ef565b600f55565b6008546001600160a01b031633146111a45760405162461bcd60e51b8152600401610a70906127ef565b8051610f4b90600a90602084019061227b565b601054339060ff1615806111ed5750806001600160a01b03166111e26008546001600160a01b031690565b6001600160a01b0316145b6112285760405162461bcd60e51b815260206004820152600c60248201526b10db185a5b481c185d5cd95960a21b6044820152606401610a70565b326001600160a01b038216146112505760405162461bcd60e51b8152600401610a70906127c9565b60005b828110156114a7576010546001600160a01b03808416916301000000900416636352211e86868581811061128957611289612824565b905060200201356040518263ffffffff1660e01b81526004016112ae91815260200190565b602060405180830381865afa1580156112cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ef919061283a565b6001600160a01b03161461133e5760405162461bcd60e51b81526020600482015260166024820152752737ba1037bbb732b91037b3103a3432903a37b5b2b760511b6044820152606401610a70565b61135f84848381811061135357611353612824565b90506020020135611c26565b156113a55760405162461bcd60e51b81526020600482015260166024820152752a37b5b2b71030b63932b0b23c9031b630b4b6b2b21760511b6044820152606401610a70565b60408051600380825260808201909252600091602082016060803683370190505090508484838181106113da576113da612824565b90506020020135816000815181106113f4576113f4612824565b60200260200101818152505084848381811061141257611412612824565b9050602002013561014d61142691906127b1565b8160018151811061143957611439612824565b60200260200101818152505084848381811061145757611457612824565b9050602002013561029a61146b91906127b1565b8160028151811061147e5761147e612824565b6020026020010181815250506114948382611d3f565b508061149f81612857565b915050611253565b50505050565b6060600380546108c290612761565b6008546001600160a01b031633146114e65760405162461bcd60e51b8152600401610a70906127ef565b6010805462ff0000198116620100009182900460ff1615909102179055565b60105462010000900460ff161561154e5760405162461bcd60e51b815260206004820152600d60248201526c141d589b1a58c81c185d5cd959609a1b6044820152606401610a70565b600154600054829190036103e7190161156791906127b1565b61138810156115ad5760405162461bcd60e51b815260206004820152601260248201527145786365656473206d617820737570706c7960701b6044820152606401610a70565b600081600b546115bd9190612870565b101561160b5760405162461bcd60e51b815260206004820152601860248201527f4d6178207075626c6963206d696e7473207265616368656400000000000000006044820152606401610a70565b600081116116495760405162461bcd60e51b815260206004820152600b60248201526a4e6f742030206d696e747360a81b6044820152606401610a70565b600d548111156116865760405162461bcd60e51b8152602060048201526008602482015267151e081b1a5b5a5d60c21b6044820152606401610a70565b34600f54826116959190612887565b146116db5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a5908199d5b991cc81c1c9bdd9a59195960521b6044820152606401610a70565b333281146116fb5760405162461bcd60e51b8152600401610a70906127c9565b600e546001600160a01b0382166000908152601260205260409020546117229084906127b1565b11156117695760405162461bcd60e51b81526020600482015260166024820152754e6f7420616c6c6f7720746f206d696e74206d6f726560501b6044820152606401610a70565b600b805483900390556001600160a01b0381166000908152601260205260409020805483019055610f4b8183611c72565b336001600160a01b038316036117c35760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6008546001600160a01b031633146118595760405162461bcd60e51b8152600401610a70906127ef565b600c55565b6008546001600160a01b031633146118885760405162461bcd60e51b8152600401610a70906127ef565b610f4b8282611c72565b61189d848484610cbc565b6001600160a01b0383163b156114a7576118b984848484611ec3565b6114a7576040516368d2bf6b60e11b815260040160405180910390fd5b6008546001600160a01b031633146119005760405162461bcd60e51b8152600401610a70906127ef565b60005b818110156114a75761192083838381811061135357611353612824565b156119645760405162461bcd60e51b81526020600482015260146024820152732a37b5b2b71030b63932b0b23c9032bc34b9ba1760611b6044820152606401610a70565b604080516003808252608082019092526000916020820160608036833701905050905083838381811061199957611999612824565b90506020020135816000815181106119b3576119b3612824565b6020026020010181815250508383838181106119d1576119d1612824565b9050602002013561014d6119e591906127b1565b816001815181106119f8576119f8612824565b602002602001018181525050838383818110611a1657611a16612824565b9050602002013561029a611a2a91906127b1565b81600281518110611a3d57611a3d612824565b602002602001018181525050611a538582611d3f565b5080611a5e81612857565b915050611903565b6060611a7182611c26565b611ab55760405162461bcd60e51b81526020600482015260156024820152742a37b5b2b7103237b2b9903737ba1032bc34b9ba1760591b6044820152606401610a70565b600060098054611ac490612761565b905011611ae057604051806020016040528060008152506108ad565b6009611aeb83611faf565b604051602001611afc9291906128c2565b60405160208183030381529060405292915050565b6008546001600160a01b03163314611b3b5760405162461bcd60e51b8152600401610a70906127ef565b6010805460ff19811660ff90911615179055565b600a8054610ffe90612761565b6008546001600160a01b03163314611b865760405162461bcd60e51b8152600401610a70906127ef565b600e55565b6008546001600160a01b03163314611bb55760405162461bcd60e51b8152600401610a70906127ef565b6001600160a01b038116611c1a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a70565b611c2381611ced565b50565b60008181526004602052604081205415611c545750600090815260046020526040902054600160e01b161590565b506000919050565b600082611c6985846120b0565b14949350505050565b610f4b8282604051806020016040528060008152506120fd565b6000818152600460205260408120548290600160e01b81168303611cd3575b80600003611ccc575060001901600081815260046020526040902054611cab565b9392505050565b50604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b038316611d6757604051622e076360e81b815260040160405180910390fd5b80600003611d885760405163b562e8dd60e01b815260040160405180910390fd5b611d9b6801000000000000000182612887565b6001600160a01b03841660009081526005602052604081208054909190611dc39084906127b1565b90915550600090505b82518110156114a757611ded6000858584815181106114a7576114a7612824565b611e0e846000610db1565b174260a01b176001600160a01b03919091161790565b60046000858481518110611e2457611e24612824565b6020026020010151815260200190815260200160002081905550828181518110611e5057611e50612824565b6020026020010151846001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611eb16000858584815181106114a7576114a7612824565b80611ebb81612857565b915050611dcc565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611ef890339089908890889060040161297c565b6020604051808303816000875af1925050508015611f33575060408051601f3d908101601f19168201909252611f30918101906129b9565b60015b611f91573d808015611f61576040519150601f19603f3d011682016040523d82523d6000602084013e611f66565b606091505b508051600003611f89576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b606081600003611fd65750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120005780611fea81612857565b9150611ff99050600a836129ec565b9150611fda565b60008167ffffffffffffffff81111561201b5761201b612509565b6040519080825280601f01601f191660200182016040528015612045576020820181803683370190505b5090505b8415611fa75761205a600183612870565b9150612067600a86612a00565b6120729060306127b1565b60f81b81838151811061208757612087612824565b60200101906001600160f81b031916908160001a9053506120a9600a866129ec565b9450612049565b600081815b84518110156120f5576120e1828683815181106120d4576120d4612824565b602002602001015161216a565b9150806120ed81612857565b9150506120b5565b509392505050565b6121078383612196565b6001600160a01b0383163b15610f6a576000548281035b6121316000868380600101945086611ec3565b61214e576040516368d2bf6b60e11b815260040160405180910390fd5b81811061211e57816000541461216357600080fd5b5050505050565b6000818310612186576000828152602084905260409020611ccc565b5060009182526020526040902090565b6000546001600160a01b0383166121bf57604051622e076360e81b815260040160405180910390fd5b816000036121e05760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600560205260408120805468010000000000000001850201905561221b9084906001851460e11b611df8565b600082815260046020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480821061222f5760005550505050565b82805461228790612761565b90600052602060002090601f0160209004810192826122a957600085556122ef565b82601f106122c257805160ff19168380011785556122ef565b828001600101855582156122ef579182015b828111156122ef5782518255916020019190600101906122d4565b506122fb9291506122ff565b5090565b5b808211156122fb5760008155600101612300565b6001600160e01b031981168114611c2357600080fd5b60006020828403121561233c57600080fd5b8135611ccc81612314565b60005b8381101561236257818101518382015260200161234a565b838111156114a75750506000910152565b6000815180845261238b816020860160208601612347565b601f01601f19169290920160200192915050565b602081526000611ccc6020830184612373565b6000602082840312156123c457600080fd5b5035919050565b6001600160a01b0381168114611c2357600080fd5b600080604083850312156123f357600080fd5b82356123fe816123cb565b946020939093013593505050565b60006020828403121561241e57600080fd5b8135611ccc816123cb565b60008083601f84011261243b57600080fd5b50813567ffffffffffffffff81111561245357600080fd5b6020830191508360208260051b850101111561246e57600080fd5b9250929050565b6000806000806060858703121561248b57600080fd5b8435935060208501359250604085013567ffffffffffffffff8111156124b057600080fd5b6124bc87828801612429565b95989497509550505050565b6000806000606084860312156124dd57600080fd5b83356124e8816123cb565b925060208401356124f8816123cb565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561253a5761253a612509565b604051601f8501601f19908116603f0116810190828211818310171561256257612562612509565b8160405280935085815286868601111561257b57600080fd5b858560208301376000602087830101525050509392505050565b6000602082840312156125a757600080fd5b813567ffffffffffffffff8111156125be57600080fd5b8201601f810184136125cf57600080fd5b611fa78482356020840161251f565b600080602083850312156125f157600080fd5b823567ffffffffffffffff81111561260857600080fd5b61261485828601612429565b90969095509350505050565b6000806040838503121561263357600080fd5b823561263e816123cb565b91506020830135801515811461265357600080fd5b809150509250929050565b6000806000806080858703121561267457600080fd5b843561267f816123cb565b9350602085013561268f816123cb565b925060408501359150606085013567ffffffffffffffff8111156126b257600080fd5b8501601f810187136126c357600080fd5b6126d28782356020840161251f565b91505092959194509250565b6000806000604084860312156126f357600080fd5b83356126fe816123cb565b9250602084013567ffffffffffffffff81111561271a57600080fd5b61272686828701612429565b9497909650939450505050565b6000806040838503121561274657600080fd5b8235612751816123cb565b91506020830135612653816123cb565b600181811c9082168061277557607f821691505b60208210810361279557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082198211156127c4576127c461279b565b500190565b6020808252600c908201526b4e6f20636f6e74726163747360a01b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561284c57600080fd5b8151611ccc816123cb565b6000600182016128695761286961279b565b5060010190565b6000828210156128825761288261279b565b500390565b60008160001904831182151516156128a1576128a161279b565b500290565b600081516128b8818560208601612347565b9290920192915050565b600080845481600182811c9150808316806128de57607f831692505b602080841082036128fd57634e487b7160e01b86526022600452602486fd5b81801561291157600181146129225761294f565b60ff1986168952848901965061294f565b60008b81526020902060005b868110156129475781548b82015290850190830161292e565b505084890196505b50505050505061297361296282866128a6565b64173539b7b760d91b815260050190565b95945050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906129af90830184612373565b9695505050505050565b6000602082840312156129cb57600080fd5b8151611ccc81612314565b634e487b7160e01b600052601260045260246000fd5b6000826129fb576129fb6129d6565b500490565b600082612a0f57612a0f6129d6565b50069056fea2646970667358221220aeb86cd0030cafb3cd2fa96f89ecf5bbcb38ccc3a423ba422f356e035571f19f64736f6c634300080d0033

Deployed Bytecode

0x6080604052600436106102935760003560e01c8063715018a61161015a578063a91789e7116100c1578063cd8805531161007a578063cd88055314610798578063d1129745146107ae578063e8a3d485146107c3578063e985e9c5146107d8578063f1d5f51714610821578063f2fde38b1461084157600080fd5b8063a91789e7146106de578063ab5e124a146106fe578063add5a4fa14610718578063b88d4fde14610738578063c5b1501a14610758578063c87b56dd1461077857600080fd5b806394db17db1161011357806394db17db1461064b57806395d89b411461066b578063981d877114610680578063a035b1fe14610695578063a0712d68146106ab578063a22cb465146106be57600080fd5b8063715018a6146105ad5780637e15144b146105c25780638342083a146105d75780638da5cb5b146105ed57806391b7f5ed1461060b578063938e3d7b1461062b57600080fd5b80633c8463a1116101fe5780635efec59a116101b75780635efec59a146104f657806361e61a25146105235780636352211e146105425780636c0360eb146105625780636caae8321461057757806370a082311461058d57600080fd5b80633c8463a11461044b5780633ccfd60b1461046157806342842e0e146104765780634f558e791461049657806355f804b3146104b65780635c85974f146104d657600080fd5b80631181d7ac116102505780631181d7ac146103a457806318160ddd146103b75780631e7269c5146103d557806323b872dd146103f557806326aa420a1461041557806332cb6b0c1461043557600080fd5b806301ffc9a71461029857806306fdde03146102cd578063081812fc146102ef578063095ea7b3146103275780630bb12bb8146103495780631056ae3114610369575b600080fd5b3480156102a457600080fd5b506102b86102b336600461232a565b610861565b60405190151581526020015b60405180910390f35b3480156102d957600080fd5b506102e26108b3565b6040516102c4919061239f565b3480156102fb57600080fd5b5061030f61030a3660046123b2565b610945565b6040516001600160a01b0390911681526020016102c4565b34801561033357600080fd5b506103476103423660046123e0565b610989565b005b34801561035557600080fd5b506010546102b89062010000900460ff1681565b34801561037557600080fd5b5061039661038436600461240c565b60126020526000908152604090205481565b6040519081526020016102c4565b6103476103b2366004612475565b610a29565b3480156103c357600080fd5b50600154600054036103e71901610396565b3480156103e157600080fd5b506103966103f036600461240c565b610c91565b34801561040157600080fd5b506103476104103660046124c8565b610cbc565b34801561042157600080fd5b506103476104303660046123b2565b610e67565b34801561044157600080fd5b5061039661138881565b34801561045757600080fd5b50610396600e5481565b34801561046d57600080fd5b50610347610e96565b34801561048257600080fd5b506103476104913660046124c8565b610f4f565b3480156104a257600080fd5b506102b86104b13660046123b2565b610f6f565b3480156104c257600080fd5b506103476104d1366004612595565b610f7a565b3480156104e257600080fd5b506103476104f13660046123b2565b610fb7565b34801561050257600080fd5b5061039661051136600461240c565b60116020526000908152604090205481565b34801561052f57600080fd5b506010546102b890610100900460ff1681565b34801561054e57600080fd5b5061030f61055d3660046123b2565b610fe6565b34801561056e57600080fd5b506102e2610ff1565b34801561058357600080fd5b50610396600d5481565b34801561059957600080fd5b506103966105a836600461240c565b61107f565b3480156105b957600080fd5b506103476110ce565b3480156105ce57600080fd5b50610347611104565b3480156105e357600080fd5b50610396600b5481565b3480156105f957600080fd5b506008546001600160a01b031661030f565b34801561061757600080fd5b506103476106263660046123b2565b61114b565b34801561063757600080fd5b50610347610646366004612595565b61117a565b34801561065757600080fd5b506103476106663660046125de565b6111b7565b34801561067757600080fd5b506102e26114ad565b34801561068c57600080fd5b506103476114bc565b3480156106a157600080fd5b50610396600f5481565b6103476106b93660046123b2565b611505565b3480156106ca57600080fd5b506103476106d9366004612620565b61179a565b3480156106ea57600080fd5b506103476106f93660046123b2565b61182f565b34801561070a57600080fd5b506010546102b89060ff1681565b34801561072457600080fd5b506103476107333660046123e0565b61185e565b34801561074457600080fd5b5061034761075336600461265e565b611892565b34801561076457600080fd5b506103476107733660046126de565b6118d6565b34801561078457600080fd5b506102e26107933660046123b2565b611a66565b3480156107a457600080fd5b50610396600c5481565b3480156107ba57600080fd5b50610347611b11565b3480156107cf57600080fd5b506102e2611b4f565b3480156107e457600080fd5b506102b86107f3366004612733565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561082d57600080fd5b5061034761083c3660046123b2565b611b5c565b34801561084d57600080fd5b5061034761085c36600461240c565b611b8b565b60006301ffc9a760e01b6001600160e01b03198316148061089257506380ac58cd60e01b6001600160e01b03198316145b806108ad5750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600280546108c290612761565b80601f01602080910402602001604051908101604052809291908181526020018280546108ee90612761565b801561093b5780601f106109105761010080835404028352916020019161093b565b820191906000526020600020905b81548152906001019060200180831161091e57829003601f168201915b5050505050905090565b600061095082611c26565b61096d576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061099482610fe6565b9050336001600160a01b038216146109cd576109b081336107f3565b6109cd576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b601054610100900460ff1615610a795760405162461bcd60e51b815260206004820152601060248201526f15da1a5d195b1a5cdd081c185d5cd95960821b60448201526064015b60405180910390fd5b600154600054859190036103e71901610a9291906127b1565b6113881015610ad85760405162461bcd60e51b815260206004820152601260248201527145786365656473206d617820737570706c7960701b6044820152606401610a70565b60008411610b165760405162461bcd60e51b815260206004820152600b60248201526a4e6f742030206d696e747360a81b6044820152606401610a70565b33328114610b365760405162461bcd60e51b8152600401610a70906127c9565b6001600160a01b0381166000908152601160205260409020548490610b5c9087906127b1565b1115610ba35760405162461bcd60e51b81526020600482015260166024820152754e6f7420616c6c6f7720746f206d696e74206d6f726560501b6044820152606401610a70565b6040516bffffffffffffffffffffffff19606083901b16602082015260348101859052600090605401604051602081830303815290604052805190602001209050610c2584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c549150849050611c5c565b610c615760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610a70565b6001600160a01b0382166000908152601160205260409020805487019055610c898287611c72565b505050505050565b6001600160a01b0381166000908152600560205260408082205467ffffffffffffffff911c166108ad565b6000610cc782611c8c565b9050836001600160a01b0316816001600160a01b031614610cfa5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610d4757610d2a86336107f3565b610d4757604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610d6e57604051633a954ecd60e21b815260040160405180910390fd5b8015610d7957600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716815290812080546001019055610dcc9086905b600160e11b174260a01b176001600160a01b03919091161790565b600085815260046020526040812091909155600160e11b84169003610e2157600184016000818152600460205260408120549003610e1f576000548114610e1f5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610c89565b6008546001600160a01b03163314610e915760405162461bcd60e51b8152600401610a70906127ef565b600b55565b6008546001600160a01b03163314610ec05760405162461bcd60e51b8152600401610a70906127ef565b6040514790600090339083908381818185875af1925050503d8060008114610f04576040519150601f19603f3d011682016040523d82523d6000602084013e610f09565b606091505b5050905080610f4b5760405162461bcd60e51b815260206004820152600e60248201526d11985a5b1959081d1bc81cd95b9960921b6044820152606401610a70565b5050565b610f6a83838360405180602001604052806000815250611892565b505050565b60006108ad82611c26565b6008546001600160a01b03163314610fa45760405162461bcd60e51b8152600401610a70906127ef565b8051610f4b90600990602084019061227b565b6008546001600160a01b03163314610fe15760405162461bcd60e51b8152600401610a70906127ef565b600d55565b60006108ad82611c8c565b60098054610ffe90612761565b80601f016020809104026020016040519081016040528092919081815260200182805461102a90612761565b80156110775780601f1061104c57610100808354040283529160200191611077565b820191906000526020600020905b81548152906001019060200180831161105a57829003601f168201915b505050505081565b60006001600160a01b0382166110a8576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b6008546001600160a01b031633146110f85760405162461bcd60e51b8152600401610a70906127ef565b6111026000611ced565b565b6008546001600160a01b0316331461112e5760405162461bcd60e51b8152600401610a70906127ef565b6010805461ff001981166101009182900460ff1615909102179055565b6008546001600160a01b031633146111755760405162461bcd60e51b8152600401610a70906127ef565b600f55565b6008546001600160a01b031633146111a45760405162461bcd60e51b8152600401610a70906127ef565b8051610f4b90600a90602084019061227b565b601054339060ff1615806111ed5750806001600160a01b03166111e26008546001600160a01b031690565b6001600160a01b0316145b6112285760405162461bcd60e51b815260206004820152600c60248201526b10db185a5b481c185d5cd95960a21b6044820152606401610a70565b326001600160a01b038216146112505760405162461bcd60e51b8152600401610a70906127c9565b60005b828110156114a7576010546001600160a01b03808416916301000000900416636352211e86868581811061128957611289612824565b905060200201356040518263ffffffff1660e01b81526004016112ae91815260200190565b602060405180830381865afa1580156112cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ef919061283a565b6001600160a01b03161461133e5760405162461bcd60e51b81526020600482015260166024820152752737ba1037bbb732b91037b3103a3432903a37b5b2b760511b6044820152606401610a70565b61135f84848381811061135357611353612824565b90506020020135611c26565b156113a55760405162461bcd60e51b81526020600482015260166024820152752a37b5b2b71030b63932b0b23c9031b630b4b6b2b21760511b6044820152606401610a70565b60408051600380825260808201909252600091602082016060803683370190505090508484838181106113da576113da612824565b90506020020135816000815181106113f4576113f4612824565b60200260200101818152505084848381811061141257611412612824565b9050602002013561014d61142691906127b1565b8160018151811061143957611439612824565b60200260200101818152505084848381811061145757611457612824565b9050602002013561029a61146b91906127b1565b8160028151811061147e5761147e612824565b6020026020010181815250506114948382611d3f565b508061149f81612857565b915050611253565b50505050565b6060600380546108c290612761565b6008546001600160a01b031633146114e65760405162461bcd60e51b8152600401610a70906127ef565b6010805462ff0000198116620100009182900460ff1615909102179055565b60105462010000900460ff161561154e5760405162461bcd60e51b815260206004820152600d60248201526c141d589b1a58c81c185d5cd959609a1b6044820152606401610a70565b600154600054829190036103e7190161156791906127b1565b61138810156115ad5760405162461bcd60e51b815260206004820152601260248201527145786365656473206d617820737570706c7960701b6044820152606401610a70565b600081600b546115bd9190612870565b101561160b5760405162461bcd60e51b815260206004820152601860248201527f4d6178207075626c6963206d696e7473207265616368656400000000000000006044820152606401610a70565b600081116116495760405162461bcd60e51b815260206004820152600b60248201526a4e6f742030206d696e747360a81b6044820152606401610a70565b600d548111156116865760405162461bcd60e51b8152602060048201526008602482015267151e081b1a5b5a5d60c21b6044820152606401610a70565b34600f54826116959190612887565b146116db5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a5908199d5b991cc81c1c9bdd9a59195960521b6044820152606401610a70565b333281146116fb5760405162461bcd60e51b8152600401610a70906127c9565b600e546001600160a01b0382166000908152601260205260409020546117229084906127b1565b11156117695760405162461bcd60e51b81526020600482015260166024820152754e6f7420616c6c6f7720746f206d696e74206d6f726560501b6044820152606401610a70565b600b805483900390556001600160a01b0381166000908152601260205260409020805483019055610f4b8183611c72565b336001600160a01b038316036117c35760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6008546001600160a01b031633146118595760405162461bcd60e51b8152600401610a70906127ef565b600c55565b6008546001600160a01b031633146118885760405162461bcd60e51b8152600401610a70906127ef565b610f4b8282611c72565b61189d848484610cbc565b6001600160a01b0383163b156114a7576118b984848484611ec3565b6114a7576040516368d2bf6b60e11b815260040160405180910390fd5b6008546001600160a01b031633146119005760405162461bcd60e51b8152600401610a70906127ef565b60005b818110156114a75761192083838381811061135357611353612824565b156119645760405162461bcd60e51b81526020600482015260146024820152732a37b5b2b71030b63932b0b23c9032bc34b9ba1760611b6044820152606401610a70565b604080516003808252608082019092526000916020820160608036833701905050905083838381811061199957611999612824565b90506020020135816000815181106119b3576119b3612824565b6020026020010181815250508383838181106119d1576119d1612824565b9050602002013561014d6119e591906127b1565b816001815181106119f8576119f8612824565b602002602001018181525050838383818110611a1657611a16612824565b9050602002013561029a611a2a91906127b1565b81600281518110611a3d57611a3d612824565b602002602001018181525050611a538582611d3f565b5080611a5e81612857565b915050611903565b6060611a7182611c26565b611ab55760405162461bcd60e51b81526020600482015260156024820152742a37b5b2b7103237b2b9903737ba1032bc34b9ba1760591b6044820152606401610a70565b600060098054611ac490612761565b905011611ae057604051806020016040528060008152506108ad565b6009611aeb83611faf565b604051602001611afc9291906128c2565b60405160208183030381529060405292915050565b6008546001600160a01b03163314611b3b5760405162461bcd60e51b8152600401610a70906127ef565b6010805460ff19811660ff90911615179055565b600a8054610ffe90612761565b6008546001600160a01b03163314611b865760405162461bcd60e51b8152600401610a70906127ef565b600e55565b6008546001600160a01b03163314611bb55760405162461bcd60e51b8152600401610a70906127ef565b6001600160a01b038116611c1a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a70565b611c2381611ced565b50565b60008181526004602052604081205415611c545750600090815260046020526040902054600160e01b161590565b506000919050565b600082611c6985846120b0565b14949350505050565b610f4b8282604051806020016040528060008152506120fd565b6000818152600460205260408120548290600160e01b81168303611cd3575b80600003611ccc575060001901600081815260046020526040902054611cab565b9392505050565b50604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b038316611d6757604051622e076360e81b815260040160405180910390fd5b80600003611d885760405163b562e8dd60e01b815260040160405180910390fd5b611d9b6801000000000000000182612887565b6001600160a01b03841660009081526005602052604081208054909190611dc39084906127b1565b90915550600090505b82518110156114a757611ded6000858584815181106114a7576114a7612824565b611e0e846000610db1565b174260a01b176001600160a01b03919091161790565b60046000858481518110611e2457611e24612824565b6020026020010151815260200190815260200160002081905550828181518110611e5057611e50612824565b6020026020010151846001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611eb16000858584815181106114a7576114a7612824565b80611ebb81612857565b915050611dcc565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611ef890339089908890889060040161297c565b6020604051808303816000875af1925050508015611f33575060408051601f3d908101601f19168201909252611f30918101906129b9565b60015b611f91573d808015611f61576040519150601f19603f3d011682016040523d82523d6000602084013e611f66565b606091505b508051600003611f89576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b606081600003611fd65750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120005780611fea81612857565b9150611ff99050600a836129ec565b9150611fda565b60008167ffffffffffffffff81111561201b5761201b612509565b6040519080825280601f01601f191660200182016040528015612045576020820181803683370190505b5090505b8415611fa75761205a600183612870565b9150612067600a86612a00565b6120729060306127b1565b60f81b81838151811061208757612087612824565b60200101906001600160f81b031916908160001a9053506120a9600a866129ec565b9450612049565b600081815b84518110156120f5576120e1828683815181106120d4576120d4612824565b602002602001015161216a565b9150806120ed81612857565b9150506120b5565b509392505050565b6121078383612196565b6001600160a01b0383163b15610f6a576000548281035b6121316000868380600101945086611ec3565b61214e576040516368d2bf6b60e11b815260040160405180910390fd5b81811061211e57816000541461216357600080fd5b5050505050565b6000818310612186576000828152602084905260409020611ccc565b5060009182526020526040902090565b6000546001600160a01b0383166121bf57604051622e076360e81b815260040160405180910390fd5b816000036121e05760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600560205260408120805468010000000000000001850201905561221b9084906001851460e11b611df8565b600082815260046020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480821061222f5760005550505050565b82805461228790612761565b90600052602060002090601f0160209004810192826122a957600085556122ef565b82601f106122c257805160ff19168380011785556122ef565b828001600101855582156122ef579182015b828111156122ef5782518255916020019190600101906122d4565b506122fb9291506122ff565b5090565b5b808211156122fb5760008155600101612300565b6001600160e01b031981168114611c2357600080fd5b60006020828403121561233c57600080fd5b8135611ccc81612314565b60005b8381101561236257818101518382015260200161234a565b838111156114a75750506000910152565b6000815180845261238b816020860160208601612347565b601f01601f19169290920160200192915050565b602081526000611ccc6020830184612373565b6000602082840312156123c457600080fd5b5035919050565b6001600160a01b0381168114611c2357600080fd5b600080604083850312156123f357600080fd5b82356123fe816123cb565b946020939093013593505050565b60006020828403121561241e57600080fd5b8135611ccc816123cb565b60008083601f84011261243b57600080fd5b50813567ffffffffffffffff81111561245357600080fd5b6020830191508360208260051b850101111561246e57600080fd5b9250929050565b6000806000806060858703121561248b57600080fd5b8435935060208501359250604085013567ffffffffffffffff8111156124b057600080fd5b6124bc87828801612429565b95989497509550505050565b6000806000606084860312156124dd57600080fd5b83356124e8816123cb565b925060208401356124f8816123cb565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561253a5761253a612509565b604051601f8501601f19908116603f0116810190828211818310171561256257612562612509565b8160405280935085815286868601111561257b57600080fd5b858560208301376000602087830101525050509392505050565b6000602082840312156125a757600080fd5b813567ffffffffffffffff8111156125be57600080fd5b8201601f810184136125cf57600080fd5b611fa78482356020840161251f565b600080602083850312156125f157600080fd5b823567ffffffffffffffff81111561260857600080fd5b61261485828601612429565b90969095509350505050565b6000806040838503121561263357600080fd5b823561263e816123cb565b91506020830135801515811461265357600080fd5b809150509250929050565b6000806000806080858703121561267457600080fd5b843561267f816123cb565b9350602085013561268f816123cb565b925060408501359150606085013567ffffffffffffffff8111156126b257600080fd5b8501601f810187136126c357600080fd5b6126d28782356020840161251f565b91505092959194509250565b6000806000604084860312156126f357600080fd5b83356126fe816123cb565b9250602084013567ffffffffffffffff81111561271a57600080fd5b61272686828701612429565b9497909650939450505050565b6000806040838503121561274657600080fd5b8235612751816123cb565b91506020830135612653816123cb565b600181811c9082168061277557607f821691505b60208210810361279557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082198211156127c4576127c461279b565b500190565b6020808252600c908201526b4e6f20636f6e74726163747360a01b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561284c57600080fd5b8151611ccc816123cb565b6000600182016128695761286961279b565b5060010190565b6000828210156128825761288261279b565b500390565b60008160001904831182151516156128a1576128a161279b565b500290565b600081516128b8818560208601612347565b9290920192915050565b600080845481600182811c9150808316806128de57607f831692505b602080841082036128fd57634e487b7160e01b86526022600452602486fd5b81801561291157600181146129225761294f565b60ff1986168952848901965061294f565b60008b81526020902060005b868110156129475781548b82015290850190830161292e565b505084890196505b50505050505061297361296282866128a6565b64173539b7b760d91b815260050190565b95945050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906129af90830184612373565b9695505050505050565b6000602082840312156129cb57600080fd5b8151611ccc81612314565b634e487b7160e01b600052601260045260246000fd5b6000826129fb576129fb6129d6565b500490565b600082612a0f57612a0f6129d6565b50069056fea2646970667358221220aeb86cd0030cafb3cd2fa96f89ecf5bbcb38ccc3a423ba422f356e035571f19f64736f6c634300080d0033

Deployed Bytecode Sourcemap

58806:5697:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26791:615;;;;;;;;;;-1:-1:-1;26791:615:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;26791:615:0;;;;;;;;32444:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;34390:204::-;;;;;;;;;;-1:-1:-1;34390:204:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1714:32:1;;;1696:51;;1684:2;1669:18;34390:204:0;1550:203:1;33938:386:0;;;;;;;;;;-1:-1:-1;33938:386:0;;;;;:::i;:::-;;:::i;:::-;;59316:31;;;;;;;;;;-1:-1:-1;59316:31:0;;;;;;;;;;;59505:45;;;;;;;;;;-1:-1:-1;59505:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2612:25:1;;;2600:2;2585:18;59505:45:0;2466:177:1;60315:794:0;;;;;;:::i;:::-;;:::i;25845:315::-;;;;;;;;;;-1:-1:-1;26111:12:0;;25898:7;26095:13;:28;-1:-1:-1;;26095:46:0;25845:315;;62181:109;;;;;;;;;;-1:-1:-1;62181:109:0;;;;;:::i;:::-;;:::i;45530:2800::-;;;;;;;;;;-1:-1:-1;45530:2800:0;;;;;:::i;:::-;;:::i;63387:103::-;;;;;;;;;;-1:-1:-1;63387:103:0;;;;;:::i;:::-;;:::i;58927:41::-;;;;;;;;;;;;58964:4;58927:41;;59158:31;;;;;;;;;;;;;;;;62298:209;;;;;;;;;;;;;:::i;35280:185::-;;;;;;;;;;-1:-1:-1;35280:185:0;;;;;:::i;:::-;;:::i;62069:104::-;;;;;;;;;;-1:-1:-1;62069:104:0;;;;;:::i;:::-;;:::i;63912:100::-;;;;;;;;;;-1:-1:-1;63912:100:0;;;;;:::i;:::-;;:::i;63592:90::-;;;;;;;;;;-1:-1:-1;63592:90:0;;;;;:::i;:::-;;:::i;59447:51::-;;;;;;;;;;-1:-1:-1;59447:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;59275:34;;;;;;;;;;-1:-1:-1;59275:34:0;;;;;;;;;;;32233:144;;;;;;;;;;-1:-1:-1;32233:144:0;;;;;:::i;:::-;;:::i;58857:26::-;;;;;;;;;;;;;:::i;59125:::-;;;;;;;;;;;;;;;;27470:224;;;;;;;;;;-1:-1:-1;27470:224:0;;;;;:::i;:::-;;:::i;11513:103::-;;;;;;;;;;;;;:::i;63182:99::-;;;;;;;;;;;;;:::i;58975:35::-;;;;;;;;;;;;;;;;10862:87;;;;;;;;;;-1:-1:-1;10935:6:0;;-1:-1:-1;;;;;10935:6:0;10862:87;;63498:86;;;;;;;;;;-1:-1:-1;63498:86:0;;;;;:::i;:::-;;:::i;64020:116::-;;;;;;;;;;-1:-1:-1;64020:116:0;;;;;:::i;:::-;;:::i;59615:692::-;;;;;;;;;;-1:-1:-1;59615:692:0;;;;;:::i;:::-;;:::i;32613:104::-;;;;;;;;;;;;;:::i;63289:90::-;;;;;;;;;;;;;:::i;59196:33::-;;;;;;;;;;;;;;;;61117:832;;;;;;:::i;:::-;;:::i;34666:308::-;;;;;;;;;;-1:-1:-1;34666:308:0;;;;;:::i;:::-;;:::i;63796:108::-;;;;;;;;;;-1:-1:-1;63796:108:0;;;;;:::i;:::-;;:::i;59238:30::-;;;;;;;;;;-1:-1:-1;59238:30:0;;;;;;;;62515:109;;;;;;;;;;-1:-1:-1;62515:109:0;;;;;:::i;:::-;;:::i;35536:399::-;;;;;;;;;;-1:-1:-1;35536:399:0;;;;;:::i;:::-;;:::i;62632:447::-;;;;;;;;;;-1:-1:-1;62632:447:0;;;;;:::i;:::-;;:::i;64144:356::-;;;;;;;;;;-1:-1:-1;64144:356:0;;;;;:::i;:::-;;:::i;59017:99::-;;;;;;;;;;;;;;;;63087:87;;;;;;;;;;;;;:::i;58890:30::-;;;;;;;;;;;;;:::i;35045:164::-;;;;;;;;;;-1:-1:-1;35045:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;35166:25:0;;;35142:4;35166:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;35045:164;63690:98;;;;;;;;;;-1:-1:-1;63690:98:0;;;;;:::i;:::-;;:::i;11771:201::-;;;;;;;;;;-1:-1:-1;11771:201:0;;;;;:::i;:::-;;:::i;26791:615::-;26876:4;-1:-1:-1;;;;;;;;;27176:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;27253:25:0;;;27176:102;:179;;;-1:-1:-1;;;;;;;;;;27330:25:0;;;27176:179;27156:199;26791:615;-1:-1:-1;;26791:615:0:o;32444:100::-;32498:13;32531:5;32524:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32444:100;:::o;34390:204::-;34458:7;34483:16;34491:7;34483;:16::i;:::-;34478:64;;34508:34;;-1:-1:-1;;;34508:34:0;;;;;;;;;;;34478:64;-1:-1:-1;34562:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;34562:24:0;;34390:204::o;33938:386::-;34011:13;34027:16;34035:7;34027;:16::i;:::-;34011:32;-1:-1:-1;56713:10:0;-1:-1:-1;;;;;34060:28:0;;;34056:175;;34108:44;34125:5;56713:10;35045:164;:::i;34108:44::-;34103:128;;34180:35;;-1:-1:-1;;;34180:35:0;;;;;;;;;;;34103:128;34243:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;34243:29:0;-1:-1:-1;;;;;34243:29:0;;;;;;;;;34288:28;;34243:24;;34288:28;;;;;;;34000:324;33938:386;;:::o;60315:794::-;60447:15;;;;;;;60446:16;60438:45;;;;-1:-1:-1;;;60438:45:0;;8871:2:1;60438:45:0;;;8853:21:1;8910:2;8890:18;;;8883:30;-1:-1:-1;;;8929:18:1;;;8922:46;8985:18;;60438:45:0;;;;;;;;;26111:12;;25898:7;26095:13;60532;;26095:28;;-1:-1:-1;;26095:46:0;60516:29;;;;:::i;:::-;58964:4;60502:43;;60494:74;;;;-1:-1:-1;;;60494:74:0;;9481:2:1;60494:74:0;;;9463:21:1;9520:2;9500:18;;;9493:30;-1:-1:-1;;;9539:18:1;;;9532:48;9597:18;;60494:74:0;9279:342:1;60494:74:0;60603:1;60587:13;:17;60579:41;;;;-1:-1:-1;;;60579:41:0;;9828:2:1;60579:41:0;;;9810:21:1;9867:2;9847:18;;;9840:30;-1:-1:-1;;;9886:18:1;;;9879:41;9937:18;;60579:41:0;9626:335:1;60579:41:0;56713:10;60682:9;:20;;60674:45;;;;-1:-1:-1;;;60674:45:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;60738:25:0;;;;;;:16;:25;;;;;;60783:10;;60738:41;;60766:13;;60738:41;:::i;:::-;:55;;60730:90;;;;-1:-1:-1;;;60730:90:0;;10509:2:1;60730:90:0;;;10491:21:1;10548:2;10528:18;;;10521:30;-1:-1:-1;;;10567:18:1;;;10560:52;10629:18;;60730:90:0;10307:346:1;60730:90:0;60858:37;;-1:-1:-1;;10835:2:1;10831:15;;;10827:53;60858:37:0;;;10815:66:1;10897:12;;;10890:28;;;60833:12:0;;10934::1;;60858:37:0;;;;;;;;;;;;60848:48;;;;;;60833:63;;60915:55;60934:12;;60915:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;60948:15:0;;;-1:-1:-1;60965:4:0;;-1:-1:-1;60915:18:0;:55::i;:::-;60907:81;;;;-1:-1:-1;;;60907:81:0;;11159:2:1;60907:81:0;;;11141:21:1;11198:2;11178:18;;;11171:30;-1:-1:-1;;;11217:18:1;;;11210:43;11270:18;;60907:81:0;10957:337:1;60907:81:0;-1:-1:-1;;;;;61013:25:0;;;;;;:16;:25;;;;;:42;;;;;;61068:33;61030:7;61042:13;61068:9;:33::i;:::-;60427:682;;60315:794;;;;:::o;62181:109::-;-1:-1:-1;;;;;27865:25:0;;62234:7;27865:25;;;:18;:25;;22162:2;27865:25;;;;22025:13;27865:49;;27864:80;62261:21;27776:176;45530:2800;45664:27;45694;45713:7;45694:18;:27::i;:::-;45664:57;;45779:4;-1:-1:-1;;;;;45738:45:0;45754:19;-1:-1:-1;;;;;45738:45:0;;45734:86;;45792:28;;-1:-1:-1;;;45792:28:0;;;;;;;;;;;45734:86;45834:27;44260:21;;;44087:15;44302:4;44295:36;44384:4;44368:21;;44474:26;;56713:10;45227:30;;;-1:-1:-1;;;;;44925:26:0;;45206:19;;;45203:55;46013:174;;46100:43;46117:4;56713:10;35045:164;:::i;46100:43::-;46095:92;;46152:35;;-1:-1:-1;;;46152:35:0;;;;;;;;;;;46095:92;-1:-1:-1;;;;;46204:16:0;;46200:52;;46229:23;;-1:-1:-1;;;46229:23:0;;;;;;;;;;;46200:52;46401:15;46398:160;;;46541:1;46520:19;46513:30;46398:160;-1:-1:-1;;;;;46936:24:0;;;;;;;:18;:24;;;;;;46934:26;;-1:-1:-1;;46934:26:0;;;47005:22;;;;;;;;47003:24;;-1:-1:-1;47003:24:0;;;47327:145;;47005:22;;47412:45;-1:-1:-1;;;47385:72:0;32132:11;32108:22;32104:40;32101:51;-1:-1:-1;;;;;31961:27:0;;;;32091:62;;31724:447;47327:145;47298:26;;;;:17;:26;;;;;:174;;;;-1:-1:-1;;;47592:46:0;;:51;;47588:626;;47696:1;47686:11;;47664:19;47819:30;;;:17;:30;;;;;;:35;;47815:384;;47957:13;;47942:11;:28;47938:242;;48104:30;;;;:17;:30;;;;;:52;;;47938:242;47645:569;47588:626;48261:7;48257:2;-1:-1:-1;;;;;48242:27:0;48251:4;-1:-1:-1;;;;;48242:27:0;;;;;;;;;;;48280:42;59615:692;63387:103;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63459:13:::1;:23:::0;63387:103::o;62298:209::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;62417:37:::1;::::0;62366:21:::1;::::0;62348:15:::1;::::0;56713:10;;62366:21;;62348:15;62417:37;62348:15;62417:37;62366:21;56713:10;62417:37:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62398:56;;;62473:7;62465:34;;;::::0;-1:-1:-1;;;62465:34:0;;12072:2:1;62465:34:0::1;::::0;::::1;12054:21:1::0;12111:2;12091:18;;;12084:30;-1:-1:-1;;;12130:18:1;;;12123:44;12184:18;;62465:34:0::1;11870:338:1::0;62465:34:0::1;62337:170;;62298:209::o:0;35280:185::-;35418:39;35435:4;35441:2;35445:7;35418:39;;;;;;;;;;;;:16;:39::i;:::-;35280:185;;;:::o;62069:104::-;62124:4;62148:17;62156:8;62148:7;:17::i;63912:100::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63986:18;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;63592:90::-:0;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63658:7:::1;:16:::0;63592:90::o;32233:144::-;32297:7;32340:27;32359:7;32340:18;:27::i;58857:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;27470:224::-;27534:7;-1:-1:-1;;;;;27558:19:0;;27554:60;;27586:28;;-1:-1:-1;;;27586:28:0;;;;;;;;;;;27554:60;-1:-1:-1;;;;;;27632:25:0;;;;;:18;:25;;;;;;22025:13;27632:54;;27470:224::o;11513:103::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;11578:30:::1;11605:1;11578:18;:30::i;:::-;11513:103::o:0;63182:99::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63258:15:::1;::::0;;-1:-1:-1;;63239:34:0;::::1;63258:15;::::0;;;::::1;;;63257:16;63239:34:::0;;::::1;;::::0;;63182:99::o;63498:86::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63562:5:::1;:14:::0;63498:86::o;64020:116::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;64102:26;;::::1;::::0;:11:::1;::::0;:26:::1;::::0;::::1;::::0;::::1;:::i;59615:692::-:0;59737:11;;56713:10;;59737:11;;59736:12;;:34;;;59763:7;-1:-1:-1;;;;;59752:18:0;:7;10935:6;;-1:-1:-1;;;;;10935:6:0;;10862:87;59752:7;-1:-1:-1;;;;;59752:18:0;;59736:34;59728:59;;;;-1:-1:-1;;;59728:59:0;;12415:2:1;59728:59:0;;;12397:21:1;12454:2;12434:18;;;12427:30;-1:-1:-1;;;12473:18:1;;;12466:42;12525:18;;59728:59:0;12213:336:1;59728:59:0;59804:9;-1:-1:-1;;;;;59804:20:0;;;59796:45;;;;-1:-1:-1;;;59796:45:0;;;;;;;:::i;:::-;59857:9;59852:448;59868:20;;;59852:448;;;59916:18;;-1:-1:-1;;;;;59916:51:0;;;;:18;;;;:26;59943:9;;59953:1;59943:12;;;;;;;:::i;:::-;;;;;;;59916:40;;;;;;;;;;;;;2612:25:1;;2600:2;2585:18;;2466:177;59916:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;59916:51:0;;59908:86;;;;-1:-1:-1;;;59908:86:0;;13144:2:1;59908:86:0;;;13126:21:1;13183:2;13163:18;;;13156:30;-1:-1:-1;;;13202:18:1;;;13195:52;13264:18;;59908:86:0;12942:346:1;59908:86:0;60016:21;60024:9;;60034:1;60024:12;;;;;;;:::i;:::-;;;;;;;60016:7;:21::i;:::-;60015:22;60007:57;;;;-1:-1:-1;;;60007:57:0;;13495:2:1;60007:57:0;;;13477:21:1;13534:2;13514:18;;;13507:30;-1:-1:-1;;;13553:18:1;;;13546:52;13615:18;;60007:57:0;13293:346:1;60007:57:0;60105:16;;;60119:1;60105:16;;;;;;;;;60079:23;;60105:16;;;;;;;;;;-1:-1:-1;60105:16:0;60079:42;;60146:9;;60156:1;60146:12;;;;;;;:::i;:::-;;;;;;;60134:6;60141:1;60134:9;;;;;;;;:::i;:::-;;;;;;:24;;;;;60183:9;;60193:1;60183:12;;;;;;;:::i;:::-;;;;;;;60198:3;60183:18;;;;:::i;:::-;60171:6;60178:1;60171:9;;;;;;;;:::i;:::-;;;;;;:30;;;;;60226:9;;60236:1;60226:12;;;;;;;:::i;:::-;;;;;;;60241:3;60226:18;;;;:::i;:::-;60214:6;60221:1;60214:9;;;;;;;;:::i;:::-;;;;;;:30;;;;;60259:31;60274:7;60283:6;60259:14;:31::i;:::-;-1:-1:-1;59890:3:0;;;;:::i;:::-;;;;59852:448;;;;59680:627;59615:692;;:::o;32613:104::-;32669:13;32702:7;32695:14;;;;;:::i;63289:90::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63359:12:::1;::::0;;-1:-1:-1;;63343:28:0;::::1;63359:12:::0;;;;::::1;;;63358:13;63343:28:::0;;::::1;;::::0;;63289:90::o;61117:832::-;61191:12;;;;;;;61190:13;61182:39;;;;-1:-1:-1;;;61182:39:0;;13986:2:1;61182:39:0;;;13968:21:1;14025:2;14005:18;;;13998:30;-1:-1:-1;;;14044:18:1;;;14037:43;14097:18;;61182:39:0;13784:337:1;61182:39:0;26111:12;;25898:7;26095:13;61270;;26095:28;;-1:-1:-1;;26095:46:0;61254:29;;;;:::i;:::-;58964:4;61240:43;;61232:74;;;;-1:-1:-1;;;61232:74:0;;9481:2:1;61232:74:0;;;9463:21:1;9520:2;9500:18;;;9493:30;-1:-1:-1;;;9539:18:1;;;9532:48;9597:18;;61232:74:0;9279:342:1;61232:74:0;61358:1;61341:13;61325;;:29;;;;:::i;:::-;:34;;61317:71;;;;-1:-1:-1;;;61317:71:0;;14458:2:1;61317:71:0;;;14440:21:1;14497:2;14477:18;;;14470:30;14536:26;14516:18;;;14509:54;14580:18;;61317:71:0;14256:348:1;61317:71:0;61423:1;61407:13;:17;61399:41;;;;-1:-1:-1;;;61399:41:0;;9828:2:1;61399:41:0;;;9810:21:1;9867:2;9847:18;;;9840:30;-1:-1:-1;;;9886:18:1;;;9879:41;9937:18;;61399:41:0;9626:335:1;61399:41:0;61476:7;;61459:13;:24;;61451:45;;;;-1:-1:-1;;;61451:45:0;;14811:2:1;61451:45:0;;;14793:21:1;14850:1;14830:18;;;14823:29;-1:-1:-1;;;14868:18:1;;;14861:38;14916:18;;61451:45:0;14609:331:1;61451:45:0;61540:9;61531:5;;61515:13;:21;;;;:::i;:::-;:34;61507:69;;;;-1:-1:-1;;;61507:69:0;;15320:2:1;61507:69:0;;;15302:21:1;15359:2;15339:18;;;15332:30;-1:-1:-1;;;15378:18:1;;;15371:52;15440:18;;61507:69:0;15118:346:1;61507:69:0;56713:10;61638:9;:20;;61630:45;;;;-1:-1:-1;;;61630:45:0;;;;;;;:::i;:::-;61733:11;;-1:-1:-1;;;;;61694:19:0;;;;;;:10;:19;;;;;;:35;;61716:13;;61694:35;:::i;:::-;:50;;61686:85;;;;-1:-1:-1;;;61686:85:0;;10509:2:1;61686:85:0;;;10491:21:1;10548:2;10528:18;;;10521:30;-1:-1:-1;;;10567:18:1;;;10560:52;10629:18;;61686:85:0;10307:346:1;61686:85:0;61807:13;:30;;;;;;;-1:-1:-1;;;;;61850:19:0;;61807:13;61850:19;;;:10;:19;;;;;:36;;;;;;61908:33;61861:7;61824:13;61908:9;:33::i;34666:308::-;56713:10;-1:-1:-1;;;;;34765:31:0;;;34761:61;;34805:17;;-1:-1:-1;;;34805:17:0;;;;;;;;;;;34761:61;56713:10;34835:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;34835:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;34835:60:0;;;;;;;;;;34911:55;;540:41:1;;;34835:49:0;;56713:10;34911:55;;513:18:1;34911:55:0;;;;;;;34666:308;;:::o;63796:108::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63871:15:::1;:25:::0;63796:108::o;62515:109::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;62593:23:::1;62603:3;62608:7;62593:9;:23::i;35536:399::-:0;35703:31;35716:4;35722:2;35726:7;35703:12;:31::i;:::-;-1:-1:-1;;;;;35749:14:0;;;:19;35745:183;;35788:56;35819:4;35825:2;35829:7;35838:5;35788:30;:56::i;:::-;35783:145;;35872:40;;-1:-1:-1;;;35872:40:0;;;;;;;;;;;62632:447;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;62734:9:::1;62729:343;62745:20:::0;;::::1;62729:343;;;62794:21;62802:9;;62812:1;62802:12;;;;;;;:::i;62794:21::-;62793:22;62785:55;;;::::0;-1:-1:-1;;;62785:55:0;;15671:2:1;62785:55:0::1;::::0;::::1;15653:21:1::0;15710:2;15690:18;;;15683:30;-1:-1:-1;;;15729:18:1;;;15722:50;15789:18;;62785:55:0::1;15469:344:1::0;62785:55:0::1;62881:16;::::0;;62895:1:::1;62881:16:::0;;;;;::::1;::::0;;;62855:23:::1;::::0;62881:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;62881:16:0::1;62855:42;;62922:9;;62932:1;62922:12;;;;;;;:::i;:::-;;;;;;;62910:6;62917:1;62910:9;;;;;;;;:::i;:::-;;;;;;:24;;;::::0;::::1;62959:9;;62969:1;62959:12;;;;;;;:::i;:::-;;;;;;;62974:3;62959:18;;;;:::i;:::-;62947:6;62954:1;62947:9;;;;;;;;:::i;:::-;;;;;;:30;;;::::0;::::1;63002:9;;63012:1;63002:12;;;;;;;:::i;:::-;;;;;;;63017:3;63002:18;;;;:::i;:::-;62990:6;62997:1;62990:9;;;;;;;;:::i;:::-;;;;;;:30;;;::::0;::::1;63035:27;63050:3;63055:6;63035:14;:27::i;:::-;-1:-1:-1::0;62767:3:0;::::1;::::0;::::1;:::i;:::-;;;;62729:343;;64144:356:::0;64210:13;64244:17;64252:8;64244:7;:17::i;:::-;64236:51;;;;-1:-1:-1;;;64236:51:0;;16020:2:1;64236:51:0;;;16002:21:1;16059:2;16039:18;;;16032:30;-1:-1:-1;;;16078:18:1;;;16071:51;16139:18;;64236:51:0;15818:345:1;64236:51:0;64329:1;64311:7;64305:21;;;;;:::i;:::-;;;:25;:187;;;;;;;;;;;;;;;;;64387:7;64411:26;64428:8;64411:16;:26::i;:::-;64354:122;;;;;;;;;:::i;:::-;;;;;;;;;;;;;64298:194;64144:356;-1:-1:-1;;64144:356:0:o;63087:87::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63155:11:::1;::::0;;-1:-1:-1;;63140:26:0;::::1;63155:11;::::0;;::::1;63154:12;63140:26;::::0;;63087:87::o;58890:30::-;;;;;;;:::i;63690:98::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;63760:11:::1;:20:::0;63690:98::o;11771:201::-;10935:6;;-1:-1:-1;;;;;10935:6:0;56713:10;11082:23;11074:68;;;;-1:-1:-1;;;11074:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;11860:22:0;::::1;11852:73;;;::::0;-1:-1:-1;;;11852:73:0;;18110:2:1;11852:73:0::1;::::0;::::1;18092:21:1::0;18149:2;18129:18;;;18122:30;18188:34;18168:18;;;18161:62;-1:-1:-1;;;18239:18:1;;;18232:36;18285:19;;11852:73:0::1;17908:402:1::0;11852:73:0::1;11936:28;11955:8;11936:18;:28::i;:::-;11771:201:::0;:::o;36190:429::-;36247:4;36267:26;;;:17;:26;;;;;;:31;36264:117;;-1:-1:-1;36321:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;36321:43:0;:48;;36190:429::o;36264:117::-;-1:-1:-1;36398:5:0;;36190:429;-1:-1:-1;36190:429:0:o;1612:190::-;1737:4;1790;1761:25;1774:5;1781:4;1761:12;:25::i;:::-;:33;;1612:190;-1:-1:-1;;;;1612:190:0:o;36703:104::-;36772:27;36782:2;36786:8;36772:27;;;;;;;;;;;;:9;:27::i;29144:1135::-;29211:7;29407:23;;;:17;:23;;;;;;29246:7;;-1:-1:-1;;;29496:23:0;;:28;;29492:699;;30015:113;30022:6;30032:1;30022:11;30015:113;;-1:-1:-1;;;30093:6:0;30075:25;;;;:17;:25;;;;;;30015:113;;;30161:6;29144:1135;-1:-1:-1;;;29144:1135:0:o;29492:699::-;29266:957;30240:31;;-1:-1:-1;;;30240:31:0;;;;;;;;;;;12132:191;12225:6;;;-1:-1:-1;;;;;12242:17:0;;;-1:-1:-1;;;;;;12242:17:0;;;;;;;12275:40;;12225:6;;;12242:17;12225:6;;12275:40;;12206:16;;12275:40;12195:128;12132:191;:::o;39979:1446::-;40081:15;;-1:-1:-1;;;;;40111:16:0;;40107:48;;40136:19;;-1:-1:-1;;;40136:19:0;;;;;;;;;;;40107:48;40170:8;40182:1;40170:13;40166:44;;40192:18;;-1:-1:-1;;;40192:18:0;;;;;;;;;;;40166:44;40430;40442:31;40430:8;:44;:::i;:::-;-1:-1:-1;;;;;40404:22:0;;;;;;:18;:22;;;;;:70;;:22;;;:70;;;;;:::i;:::-;;;;-1:-1:-1;40492:9:0;;-1:-1:-1;40487:931:0;40507:8;:15;40503:1;:19;40487:931;;;40760:53;40790:1;40794:2;40798:8;40807:1;40798:11;;;;;;;;:::i;40760:53::-;41111:144;41152:2;41226:1;41203:33;53771:309;41177:23;:59;32132:11;32108:22;32104:40;32101:51;-1:-1:-1;;;;;31961:27:0;;;;32091:62;;31724:447;41111:144;41078:17;:30;41096:8;41105:1;41096:11;;;;;;;;:::i;:::-;;;;;;;41078:30;;;;;;;;;;;:177;;;;41306:8;41315:1;41306:11;;;;;;;;:::i;:::-;;;;;;;41302:2;-1:-1:-1;;;;;41281:37:0;41298:1;-1:-1:-1;;;;;41281:37:0;;;;;;;;;;;41337:52;41366:1;41370:2;41374:8;41383:1;41374:11;;;;;;;;:::i;41337:52::-;40524:3;;;;:::i;:::-;;;;40487:931;;52281:716;52465:88;;-1:-1:-1;;;52465:88:0;;52444:4;;-1:-1:-1;;;;;52465:45:0;;;;;:88;;56713:10;;52532:4;;52538:7;;52547:5;;52465:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52465:88:0;;;;;;;;-1:-1:-1;;52465:88:0;;;;;;;;;;;;:::i;:::-;;;52461:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52748:6;:13;52765:1;52748:18;52744:235;;52794:40;;-1:-1:-1;;;52794:40:0;;;;;;;;;;;52744:235;52937:6;52931:13;52922:6;52918:2;52914:15;52907:38;52461:529;-1:-1:-1;;;;;;52624:64:0;-1:-1:-1;;;52624:64:0;;-1:-1:-1;52461:529:0;52281:716;;;;;;:::o;6995:723::-;7051:13;7272:5;7281:1;7272:10;7268:53;;-1:-1:-1;;7299:10:0;;;;;;;;;;;;-1:-1:-1;;;7299:10:0;;;;;6995:723::o;7268:53::-;7346:5;7331:12;7387:78;7394:9;;7387:78;;7420:8;;;;:::i;:::-;;-1:-1:-1;7443:10:0;;-1:-1:-1;7451:2:0;7443:10;;:::i;:::-;;;7387:78;;;7475:19;7507:6;7497:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7497:17:0;;7475:39;;7525:154;7532:10;;7525:154;;7559:11;7569:1;7559:11;;:::i;:::-;;-1:-1:-1;7628:10:0;7636:2;7628:5;:10;:::i;:::-;7615:24;;:2;:24;:::i;:::-;7602:39;;7585:6;7592;7585:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;7585:56:0;;;;;;;;-1:-1:-1;7656:11:0;7665:2;7656:11;;:::i;:::-;;;7525:154;;2479:296;2562:7;2605:4;2562:7;2620:118;2644:5;:12;2640:1;:16;2620:118;;;2693:33;2703:12;2717:5;2723:1;2717:8;;;;;;;;:::i;:::-;;;;;;;2693:9;:33::i;:::-;2678:48;-1:-1:-1;2658:3:0;;;;:::i;:::-;;;;2620:118;;;-1:-1:-1;2755:12:0;2479:296;-1:-1:-1;;;2479:296:0:o;37223:681::-;37346:19;37352:2;37356:8;37346:5;:19::i;:::-;-1:-1:-1;;;;;37407:14:0;;;:19;37403:483;;37447:11;37461:13;37509:14;;;37542:233;37573:62;37612:1;37616:2;37620:7;;;;;;37629:5;37573:30;:62::i;:::-;37568:167;;37671:40;;-1:-1:-1;;;37671:40:0;;;;;;;;;;;37568:167;37770:3;37762:5;:11;37542:233;;37857:3;37840:13;;:20;37836:34;;37862:8;;;37836:34;37428:458;;37223:681;;;:::o;6225:149::-;6288:7;6319:1;6315;:5;:51;;6450:13;6544:15;;;6580:4;6573:15;;;6627:4;6611:21;;6315:51;;;-1:-1:-1;6450:13:0;6544:15;;;6580:4;6573:15;6627:4;6611:21;;;6225:149::o;38177:1529::-;38242:20;38265:13;-1:-1:-1;;;;;38293:16:0;;38289:48;;38318:19;;-1:-1:-1;;;38318:19:0;;;;;;;;;;;38289:48;38352:8;38364:1;38352:13;38348:44;;38374:18;;-1:-1:-1;;;38374:18:0;;;;;;;;;;;38348:44;-1:-1:-1;;;;;38880:22:0;;;;;;:18;:22;;22162:2;38880:22;;:70;;38918:31;38906:44;;38880:70;;;39227:139;;38880:22;;33855:1;33842:15;;33817:23;33813:45;39285:30;33554:322;39227:139;39193:31;;;;:17;:31;;;;;:173;39211:12;39442:23;;;39480:101;39507:35;;39532:9;;;;;-1:-1:-1;;;;;39507:35:0;;;39524:1;;39507:35;;39524:1;;39507:35;39576:3;39566:7;:13;39480:101;;39597:13;:19;-1:-1:-1;35280:185:0;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:269::-;908:3;946:5;940:12;973:6;968:3;961:19;989:63;1045:6;1038:4;1033:3;1029:14;1022:4;1015:5;1011:16;989:63;:::i;:::-;1106:2;1085:15;-1:-1:-1;;1081:29:1;1072:39;;;;1113:4;1068:50;;855:269;-1:-1:-1;;855:269:1:o;1129:231::-;1278:2;1267:9;1260:21;1241:4;1298:56;1350:2;1339:9;1335:18;1327:6;1298:56;:::i;1365:180::-;1424:6;1477:2;1465:9;1456:7;1452:23;1448:32;1445:52;;;1493:1;1490;1483:12;1445:52;-1:-1:-1;1516:23:1;;1365:180;-1:-1:-1;1365:180:1:o;1758:131::-;-1:-1:-1;;;;;1833:31:1;;1823:42;;1813:70;;1879:1;1876;1869:12;1894:315;1962:6;1970;2023:2;2011:9;2002:7;1998:23;1994:32;1991:52;;;2039:1;2036;2029:12;1991:52;2078:9;2065:23;2097:31;2122:5;2097:31;:::i;:::-;2147:5;2199:2;2184:18;;;;2171:32;;-1:-1:-1;;;1894:315:1:o;2214:247::-;2273:6;2326:2;2314:9;2305:7;2301:23;2297:32;2294:52;;;2342:1;2339;2332:12;2294:52;2381:9;2368:23;2400:31;2425:5;2400:31;:::i;2648:367::-;2711:8;2721:6;2775:3;2768:4;2760:6;2756:17;2752:27;2742:55;;2793:1;2790;2783:12;2742:55;-1:-1:-1;2816:20:1;;2859:18;2848:30;;2845:50;;;2891:1;2888;2881:12;2845:50;2928:4;2920:6;2916:17;2904:29;;2988:3;2981:4;2971:6;2968:1;2964:14;2956:6;2952:27;2948:38;2945:47;2942:67;;;3005:1;3002;2995:12;2942:67;2648:367;;;;;:::o;3020:573::-;3124:6;3132;3140;3148;3201:2;3189:9;3180:7;3176:23;3172:32;3169:52;;;3217:1;3214;3207:12;3169:52;3253:9;3240:23;3230:33;;3310:2;3299:9;3295:18;3282:32;3272:42;;3365:2;3354:9;3350:18;3337:32;3392:18;3384:6;3381:30;3378:50;;;3424:1;3421;3414:12;3378:50;3463:70;3525:7;3516:6;3505:9;3501:22;3463:70;:::i;:::-;3020:573;;;;-1:-1:-1;3552:8:1;-1:-1:-1;;;;3020:573:1:o;3598:456::-;3675:6;3683;3691;3744:2;3732:9;3723:7;3719:23;3715:32;3712:52;;;3760:1;3757;3750:12;3712:52;3799:9;3786:23;3818:31;3843:5;3818:31;:::i;:::-;3868:5;-1:-1:-1;3925:2:1;3910:18;;3897:32;3938:33;3897:32;3938:33;:::i;:::-;3598:456;;3990:7;;-1:-1:-1;;;4044:2:1;4029:18;;;;4016:32;;3598:456::o;4059:127::-;4120:10;4115:3;4111:20;4108:1;4101:31;4151:4;4148:1;4141:15;4175:4;4172:1;4165:15;4191:632;4256:5;4286:18;4327:2;4319:6;4316:14;4313:40;;;4333:18;;:::i;:::-;4408:2;4402:9;4376:2;4462:15;;-1:-1:-1;;4458:24:1;;;4484:2;4454:33;4450:42;4438:55;;;4508:18;;;4528:22;;;4505:46;4502:72;;;4554:18;;:::i;:::-;4594:10;4590:2;4583:22;4623:6;4614:15;;4653:6;4645;4638:22;4693:3;4684:6;4679:3;4675:16;4672:25;4669:45;;;4710:1;4707;4700:12;4669:45;4760:6;4755:3;4748:4;4740:6;4736:17;4723:44;4815:1;4808:4;4799:6;4791;4787:19;4783:30;4776:41;;;;4191:632;;;;;:::o;4828:451::-;4897:6;4950:2;4938:9;4929:7;4925:23;4921:32;4918:52;;;4966:1;4963;4956:12;4918:52;5006:9;4993:23;5039:18;5031:6;5028:30;5025:50;;;5071:1;5068;5061:12;5025:50;5094:22;;5147:4;5139:13;;5135:27;-1:-1:-1;5125:55:1;;5176:1;5173;5166:12;5125:55;5199:74;5265:7;5260:2;5247:16;5242:2;5238;5234:11;5199:74;:::i;5284:437::-;5370:6;5378;5431:2;5419:9;5410:7;5406:23;5402:32;5399:52;;;5447:1;5444;5437:12;5399:52;5487:9;5474:23;5520:18;5512:6;5509:30;5506:50;;;5552:1;5549;5542:12;5506:50;5591:70;5653:7;5644:6;5633:9;5629:22;5591:70;:::i;:::-;5680:8;;5565:96;;-1:-1:-1;5284:437:1;-1:-1:-1;;;;5284:437:1:o;5726:416::-;5791:6;5799;5852:2;5840:9;5831:7;5827:23;5823:32;5820:52;;;5868:1;5865;5858:12;5820:52;5907:9;5894:23;5926:31;5951:5;5926:31;:::i;:::-;5976:5;-1:-1:-1;6033:2:1;6018:18;;6005:32;6075:15;;6068:23;6056:36;;6046:64;;6106:1;6103;6096:12;6046:64;6129:7;6119:17;;;5726:416;;;;;:::o;6332:795::-;6427:6;6435;6443;6451;6504:3;6492:9;6483:7;6479:23;6475:33;6472:53;;;6521:1;6518;6511:12;6472:53;6560:9;6547:23;6579:31;6604:5;6579:31;:::i;:::-;6629:5;-1:-1:-1;6686:2:1;6671:18;;6658:32;6699:33;6658:32;6699:33;:::i;:::-;6751:7;-1:-1:-1;6805:2:1;6790:18;;6777:32;;-1:-1:-1;6860:2:1;6845:18;;6832:32;6887:18;6876:30;;6873:50;;;6919:1;6916;6909:12;6873:50;6942:22;;6995:4;6987:13;;6983:27;-1:-1:-1;6973:55:1;;7024:1;7021;7014:12;6973:55;7047:74;7113:7;7108:2;7095:16;7090:2;7086;7082:11;7047:74;:::i;:::-;7037:84;;;6332:795;;;;;;;:::o;7132:572::-;7227:6;7235;7243;7296:2;7284:9;7275:7;7271:23;7267:32;7264:52;;;7312:1;7309;7302:12;7264:52;7351:9;7338:23;7370:31;7395:5;7370:31;:::i;:::-;7420:5;-1:-1:-1;7476:2:1;7461:18;;7448:32;7503:18;7492:30;;7489:50;;;7535:1;7532;7525:12;7489:50;7574:70;7636:7;7627:6;7616:9;7612:22;7574:70;:::i;:::-;7132:572;;7663:8;;-1:-1:-1;7548:96:1;;-1:-1:-1;;;;7132:572:1:o;7891:388::-;7959:6;7967;8020:2;8008:9;7999:7;7995:23;7991:32;7988:52;;;8036:1;8033;8026:12;7988:52;8075:9;8062:23;8094:31;8119:5;8094:31;:::i;:::-;8144:5;-1:-1:-1;8201:2:1;8186:18;;8173:32;8214:33;8173:32;8214:33;:::i;8284:380::-;8363:1;8359:12;;;;8406;;;8427:61;;8481:4;8473:6;8469:17;8459:27;;8427:61;8534:2;8526:6;8523:14;8503:18;8500:38;8497:161;;8580:10;8575:3;8571:20;8568:1;8561:31;8615:4;8612:1;8605:15;8643:4;8640:1;8633:15;8497:161;;8284:380;;;:::o;9014:127::-;9075:10;9070:3;9066:20;9063:1;9056:31;9106:4;9103:1;9096:15;9130:4;9127:1;9120:15;9146:128;9186:3;9217:1;9213:6;9210:1;9207:13;9204:39;;;9223:18;;:::i;:::-;-1:-1:-1;9259:9:1;;9146:128::o;9966:336::-;10168:2;10150:21;;;10207:2;10187:18;;;10180:30;-1:-1:-1;;;10241:2:1;10226:18;;10219:42;10293:2;10278:18;;9966:336::o;11299:356::-;11501:2;11483:21;;;11520:18;;;11513:30;11579:34;11574:2;11559:18;;11552:62;11646:2;11631:18;;11299:356::o;12554:127::-;12615:10;12610:3;12606:20;12603:1;12596:31;12646:4;12643:1;12636:15;12670:4;12667:1;12660:15;12686:251;12756:6;12809:2;12797:9;12788:7;12784:23;12780:32;12777:52;;;12825:1;12822;12815:12;12777:52;12857:9;12851:16;12876:31;12901:5;12876:31;:::i;13644:135::-;13683:3;13704:17;;;13701:43;;13724:18;;:::i;:::-;-1:-1:-1;13771:1:1;13760:13;;13644:135::o;14126:125::-;14166:4;14194:1;14191;14188:8;14185:34;;;14199:18;;:::i;:::-;-1:-1:-1;14236:9:1;;14126:125::o;14945:168::-;14985:7;15051:1;15047;15043:6;15039:14;15036:1;15033:21;15028:1;15021:9;15014:17;15010:45;15007:71;;;15058:18;;:::i;:::-;-1:-1:-1;15098:9:1;;14945:168::o;16294:185::-;16336:3;16374:5;16368:12;16389:52;16434:6;16429:3;16422:4;16415:5;16411:16;16389:52;:::i;:::-;16457:16;;;;;16294:185;-1:-1:-1;;16294:185:1:o;16602:1301::-;16879:3;16908:1;16941:6;16935:13;16971:3;16993:1;17021:9;17017:2;17013:18;17003:28;;17081:2;17070:9;17066:18;17103;17093:61;;17147:4;17139:6;17135:17;17125:27;;17093:61;17173:2;17221;17213:6;17210:14;17190:18;17187:38;17184:165;;-1:-1:-1;;;17248:33:1;;17304:4;17301:1;17294:15;17334:4;17255:3;17322:17;17184:165;17365:18;17392:104;;;;17510:1;17505:320;;;;17358:467;;17392:104;-1:-1:-1;;17425:24:1;;17413:37;;17470:16;;;;-1:-1:-1;17392:104:1;;17505:320;16241:1;16234:14;;;16278:4;16265:18;;17600:1;17614:165;17628:6;17625:1;17622:13;17614:165;;;17706:14;;17693:11;;;17686:35;17749:16;;;;17643:10;;17614:165;;;17618:3;;17808:6;17803:3;17799:16;17792:23;;17358:467;;;;;;;17841:56;17866:30;17892:3;17884:6;17866:30;:::i;:::-;-1:-1:-1;;;16544:20:1;;16589:1;16580:11;;16484:113;17841:56;17834:63;16602:1301;-1:-1:-1;;;;;16602:1301:1:o;18315:500::-;-1:-1:-1;;;;;18584:15:1;;;18566:34;;18636:15;;18631:2;18616:18;;18609:43;18683:2;18668:18;;18661:34;;;18731:3;18726:2;18711:18;;18704:31;;;18509:4;;18752:57;;18789:19;;18781:6;18752:57;:::i;:::-;18744:65;18315:500;-1:-1:-1;;;;;;18315:500:1:o;18820:249::-;18889:6;18942:2;18930:9;18921:7;18917:23;18913:32;18910:52;;;18958:1;18955;18948:12;18910:52;18990:9;18984:16;19009:30;19033:5;19009:30;:::i;19074:127::-;19135:10;19130:3;19126:20;19123:1;19116:31;19166:4;19163:1;19156:15;19190:4;19187:1;19180:15;19206:120;19246:1;19272;19262:35;;19277:18;;:::i;:::-;-1:-1:-1;19311:9:1;;19206:120::o;19331:112::-;19363:1;19389;19379:35;;19394:18;;:::i;:::-;-1:-1:-1;19428:9:1;;19331:112::o

Swarm Source

ipfs://aeb86cd0030cafb3cd2fa96f89ecf5bbcb38ccc3a423ba422f356e035571f19f
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.