ETH Price: $3,111.73 (+0.45%)

Token

YecheGoldenOpportunitiesV2 (GOLDENV2)
 

Overview

Max Total Supply

256 GOLDENV2

Holders

180

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 GOLDENV2
0xbf6204a520962780590b28d843d345a8eb08da4b
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:
YecheGoldenOpportunitiesV2

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-12-31
*/

// File: IOperatorFilterRegistry.sol


pragma solidity ^0.8.7;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

// File: OperatorFilterer.sol


pragma solidity ^0.8.7;


/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

// File: DefaultOperatorFilterer.sol


pragma solidity ^0.8.7;


/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

// File: @openzeppelin/contracts/utils/Strings.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/access/Ownable.sol


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

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev 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);
    }
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/interfaces/IERC2981.sol


// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

// File: @openzeppelin/contracts/token/common/ERC2981.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;



/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must 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);
}

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


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

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,
     * consuming from one or the other at each step according to the instructions given by
     * `proofFlags`.
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// File: @openzeppelin/contracts/utils/Counters.sol


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

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: erc721a/contracts/IERC721A.sol


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

    // =============================================================
    //                            STRUCTS
    // =============================================================

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

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

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

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`,
     * checking first that contract recipients are aware of the ERC721 protocol
     * to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move
     * this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external payable;

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom}
     * whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the
     * zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external payable;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom}
     * for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

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

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

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

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

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

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

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

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

// File: erc721a/contracts/ERC721A.sol


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

pragma solidity ^0.8.4;


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

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

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

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

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

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

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

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

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

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

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

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

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

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

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

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

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

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

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

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

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

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

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

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

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

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

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

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

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

    /**
     * @dev Returns the token collection name.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

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

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

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

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

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

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

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

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

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

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

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the
     * zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) public payable virtual override {
        address owner = ownerOf(tokenId);

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

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

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom}
     * for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

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

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

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

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

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns whether the call correctly returned the expected magic value.
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

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

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

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

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

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

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

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

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

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

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

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

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

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

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

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

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

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

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

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

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

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

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value) internal pure virtual returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

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

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

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

// File: contracts/YecheGoldenOpportunitiesV2.sol

//SPDX-License-Identifier: UNLICENSED 
pragma solidity ^0.8.7;










contract YecheGoldenOpportunitiesV2 is ERC721A, DefaultOperatorFilterer, Ownable, ReentrancyGuard, ERC2981 {
    using Counters for Counters.Counter;

    address public split;
    uint96 private royaltyBps = 1000;
    mapping (address => bool) private gifters; 

    mapping(uint256 => uint256) public tokenToGiveaway;

    struct Giveaway {
        bool mintPaused;
        uint256 maxSupply;
        uint256 startTime;
        uint256 endTime;
        uint256 editionIDCounter;
        uint256 numEligibleAnyone;
        string baseURI;
        address[] whitelistedProjects;
        mapping(address => uint256) whitelistedNumEligible;
        mapping(address => bool) giveawayClaimed;
        mapping(uint256 => uint256) tokenIDtoEditionID;
    }

    Giveaway[] public giveaways;

    modifier onlyGifter() {
        require(gifters[msg.sender] == true, "only gifters can gift");
        _;
    }

    modifier callerIsUser() {
        require(tx.origin == msg.sender, "the caller is another contract.");
        _;
    }

    constructor() ERC721A("YecheGoldenOpportunitiesV2", "GOLDENV2") {
        gifters[msg.sender] = true;
    }

    function setSplitAddress(address _address) public onlyOwner {
        split = _address;
        _setDefaultRoyalty(split, royaltyBps);
    }

    function addGiveaway(
        uint256 _maxSupply,
        uint256 _startTime,
        uint256 _endTime,
        uint256 _numEligibleAnyone,
        string memory _baseURI
    ) external onlyOwner {
        Giveaway storage giveaway = giveaways.push();
        giveaway.mintPaused = true;
        giveaway.maxSupply = _maxSupply;
        giveaway.startTime = _startTime;
        giveaway.endTime = _endTime;
        giveaway.numEligibleAnyone = _numEligibleAnyone;
        giveaway.editionIDCounter = 0;
        giveaway.baseURI = _baseURI;
    }

    function updateGiveawayMintPaused(bool _mintPaused, uint256 _giveawayIndex) external onlyOwner {
        require(_giveawayIndex < giveaways.length, "Invalid giveaway index");
        Giveaway storage giveaway = giveaways[_giveawayIndex];
        giveaway.mintPaused = _mintPaused;
    }

    function updateGiveawaySupply(uint256 _maxSupply, uint256 _giveawayIndex) external onlyOwner {
        require(_giveawayIndex < giveaways.length, "Invalid giveaway index");
        Giveaway storage giveaway = giveaways[_giveawayIndex];
        giveaway.maxSupply = _maxSupply;
    }

    function updateGiveawayWindow(uint256 _startTime, uint256 _endTime, uint256 _giveawayIndex) external onlyOwner {
        require(_giveawayIndex < giveaways.length, "Invalid giveaway index");
        Giveaway storage giveaway = giveaways[_giveawayIndex];
        giveaway.startTime = _startTime;
        giveaway.endTime = _endTime;
    }

    function updateGiveawayBaseURI(string memory _baseURI, uint256 _giveawayIndex) external onlyOwner {
        require(_giveawayIndex < giveaways.length, "Invalid giveaway index");
        Giveaway storage giveaway = giveaways[_giveawayIndex];
        giveaway.baseURI = _baseURI;
    }

    function addWhitelistedProject(
        uint256 _giveawayIndex,
        address _projectContract,
        uint256 _numEligible
    ) external onlyOwner {
        require(_giveawayIndex < giveaways.length, "Invalid giveaway index");
        Giveaway storage giveaway = giveaways[_giveawayIndex];
        giveaway.whitelistedProjects.push(_projectContract);
        giveaway.whitelistedNumEligible[_projectContract] = _numEligible;
    }

    function maxEligibleToMint(address wallet, uint256 giveawayIndex) public view returns (uint256) {
        uint256 maxEligible = giveaways[giveawayIndex].numEligibleAnyone;

        for(uint256 i = 0; i < giveaways[giveawayIndex].whitelistedProjects.length; i++) {
            address project = giveaways[giveawayIndex].whitelistedProjects[i];
            uint256 numEligible = giveaways[giveawayIndex].whitelistedNumEligible[project];
            uint256 balance = IERC721(project).balanceOf(wallet);

            if(balance > 0 && numEligible > maxEligible) {
                maxEligible = numEligible;
            }
        }

        return maxEligible;
    }

    function gift(uint256 giveawayIndex, uint256 quantity, address to) public onlyGifter {
        require(giveawayIndex < giveaways.length, "Invalid giveaway index");

        Giveaway storage giveaway = giveaways[giveawayIndex];

        require(quantity <= giveaway.maxSupply - giveaway.editionIDCounter, "Cannot gift more NFTs than the max supply for this giveaway");

        uint256 minTokenID = totalSupply();
        uint256 maxTokenID = minTokenID + quantity - 1;

        for(uint256 i = minTokenID; i <= maxTokenID; i++) {
            giveaway.tokenIDtoEditionID[i] = giveaway.editionIDCounter;
            tokenToGiveaway[i] = giveawayIndex;
            giveaway.editionIDCounter++;
        }

        _safeMint(to, quantity);
    }

    function mint(uint256 giveawayIndex) public nonReentrant callerIsUser {
        require(giveawayIndex < giveaways.length, "Invalid giveaway index");

        Giveaway storage giveaway = giveaways[giveawayIndex];

        require(giveaway.mintPaused == false, "Minting is paused for this giveaway");

        require(giveaway.giveawayClaimed[msg.sender] == false, "You already claimed your giveaway");

        uint256 numEligible = maxEligibleToMint(msg.sender, giveawayIndex);

        require(numEligible > 0, "You are not eligible to mint");

        if(giveaway.startTime != 0 && giveaway.endTime != 0) {
            require(block.timestamp >= giveaway.startTime && block.timestamp <= giveaway.endTime, "Giveaway is not currently active");
        }

        require(numEligible <= giveaway.maxSupply - giveaway.editionIDCounter, "Not enough tokens left to mint"); 
 
        uint256 minTokenID = totalSupply();
        uint256 maxTokenID = minTokenID + numEligible - 1;

        for(uint256 i = minTokenID; i <= maxTokenID; i++) {
            giveaway.tokenIDtoEditionID[i] = giveaway.editionIDCounter;

            tokenToGiveaway[i] = giveawayIndex;

            giveaway.editionIDCounter++;
        }

        giveaway.giveawayClaimed[msg.sender] = true;

        _safeMint(msg.sender, numEligible);
    }

    // Overrides the ERC721 tokenURI function to return the correct metadata URI for a given token
    function tokenURI(uint256 _tokenID) public view override returns (string memory) {
        require(_exists(_tokenID), "ERC721Metadata: URI query for nonexistent token");
        uint256 giveawayIndex = tokenToGiveaway[_tokenID];
        string memory baseURI = giveaways[giveawayIndex].baseURI;
        uint256 editionID = giveaways[giveawayIndex].tokenIDtoEditionID[_tokenID];
        return string(abi.encodePacked(baseURI, Strings.toString(editionID)));
    }

    function updateGifters(address _address, bool canGift) public onlyOwner {
        gifters[_address] = canGift;
    }

    function updateRoyalty(uint96 _royaltyBps) public onlyOwner {
        require(split!=address(0), "split address not set, please set split address before updating royalty");
        royaltyBps = _royaltyBps;
        _setDefaultRoyalty(split, royaltyBps);
    }

    // Opensea Operator filter registry
    function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(address operator, uint256 tokenID) public payable override onlyAllowedOperatorApproval(operator) {
        super.approve(operator, tokenID);
    }

    function transferFrom(address from, address to, uint256 tokenID) public payable override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenID);
    }

    function safeTransferFrom(address from, address to, uint256 tokenID) public payable override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenID);
    }

    function safeTransferFrom(address from, address to, uint256 tokenID, bytes memory data)
        public
        payable
        override
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenID, data);
    }

    function supportsInterface(
    bytes4 interfaceId
    ) public view virtual override(ERC721A, ERC2981) returns (bool) {
        return 
            ERC721A.supportsInterface(interfaceId) || 
            ERC2981.supportsInterface(interfaceId);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"},{"internalType":"uint256","name":"_numEligibleAnyone","type":"uint256"},{"internalType":"string","name":"_baseURI","type":"string"}],"name":"addGiveaway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_giveawayIndex","type":"uint256"},{"internalType":"address","name":"_projectContract","type":"address"},{"internalType":"uint256","name":"_numEligible","type":"uint256"}],"name":"addWhitelistedProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"giveawayIndex","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"gift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"giveaways","outputs":[{"internalType":"bool","name":"mintPaused","type":"bool"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"editionIDCounter","type":"uint256"},{"internalType":"uint256","name":"numEligibleAnyone","type":"uint256"},{"internalType":"string","name":"baseURI","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"giveawayIndex","type":"uint256"}],"name":"maxEligibleToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"giveawayIndex","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setSplitAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"split","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenToGiveaway","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenID","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"canGift","type":"bool"}],"name":"updateGifters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"},{"internalType":"uint256","name":"_giveawayIndex","type":"uint256"}],"name":"updateGiveawayBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_mintPaused","type":"bool"},{"internalType":"uint256","name":"_giveawayIndex","type":"uint256"}],"name":"updateGiveawayMintPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"uint256","name":"_giveawayIndex","type":"uint256"}],"name":"updateGiveawaySupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"},{"internalType":"uint256","name":"_giveawayIndex","type":"uint256"}],"name":"updateGiveawayWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_royaltyBps","type":"uint96"}],"name":"updateRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600c80546001600160a01b0316607d60a31b1790553480156200002657600080fd5b50604080518082018252601a81527f5965636865476f6c64656e4f70706f7274756e6974696573563200000000000060208083019182528351808501909452600884526723a7a62222a72b1960c11b908401528151733cc6cdda760b79bafa08df41ecfa224f810dceb693600193929091620000a5916002916200028e565b508051620000bb9060039060208401906200028e565b506000805550506daaeb6d7670e522a718067333cd4e3b15620002075780156200015557604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200013657600080fd5b505af11580156200014b573d6000803e3d6000fd5b5050505062000207565b6001600160a01b03821615620001a65760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af2903906044016200011b565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620001ed57600080fd5b505af115801562000202573d6000803e3d6000fd5b505050505b50620002159050336200023c565b60016009819055336000908152600d60205260409020805460ff1916909117905562000371565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200029c9062000334565b90600052602060002090601f016020900481019282620002c057600085556200030b565b82601f10620002db57805160ff19168380011785556200030b565b828001600101855582156200030b579182015b828111156200030b578251825591602001919060010190620002ee565b50620003199291506200031d565b5090565b5b808211156200031957600081556001016200031e565b600181811c908216806200034957607f821691505b602082108114156200036b57634e487b7160e01b600052602260045260246000fd5b50919050565b612adf80620003816000396000f3fe6080604052600436106101f95760003560e01c80637120d5a31161010d578063b88d4fde116100a0578063e985e9c51161006f578063e985e9c5146105c7578063f2fde38b14610610578063f73285fb14610630578063f765417614610650578063fb19bc071461067057600080fd5b8063b88d4fde14610554578063c260804c14610567578063c87b56dd14610587578063e5ad0b2b146105a757600080fd5b806395d89b41116100dc57806395d89b41146104df578063a0712d68146104f4578063a22cb46514610514578063a7cc2c251461053457600080fd5b80637120d5a31461046c578063715018a61461048c578063856e0504146104a15780638da5cb5b146104c157600080fd5b80632a55205a1161019057806341f434341161015f57806341f43434146103ca57806342842e0e146103ec5780636352211e146103ff57806367f6326c1461041f57806370a082311461044c57600080fd5b80632a55205a146103185780633708d8f5146103575780633a204328146103775780633e06df3d1461039757600080fd5b8063095ea7b3116101cc578063095ea7b3146102af57806318160ddd146102c257806323b872dd146102e55780632625ebdf146102f857600080fd5b806301ffc9a7146101fe57806302acd0881461023357806306fdde0314610255578063081812fc14610277575b600080fd5b34801561020a57600080fd5b5061021e6102193660046125f9565b610690565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b5061025361024e36600461255d565b6106b0565b005b34801561026157600080fd5b5061026a61070e565b60405161022a91906128bd565b34801561028357600080fd5b50610297610292366004612678565b6107a0565b6040516001600160a01b03909116815260200161022a565b6102536102bd366004612594565b6107e4565b3480156102ce57600080fd5b50600154600054035b60405190815260200161022a565b6102536102f33660046124a5565b6107fd565b34801561030457600080fd5b506102536103133660046126aa565b610828565b34801561032457600080fd5b506103386103333660046126cf565b6108dc565b604080516001600160a01b03909316835260208301919091520161022a565b34801561036357600080fd5b50610253610372366004612633565b610988565b34801561038357600080fd5b50610253610392366004612752565b610a10565b3480156103a357600080fd5b506103b76103b2366004612678565b610b79565b60405161022a9796959493929190612877565b3480156103d657600080fd5b506102976daaeb6d7670e522a718067333cd4e81565b6102536103fa3660046124a5565b610c60565b34801561040b57600080fd5b5061029761041a366004612678565b610c85565b34801561042b57600080fd5b506102d761043a366004612678565b600e6020526000908152604090205481565b34801561045857600080fd5b506102d7610467366004612457565b610c90565b34801561047857600080fd5b506102536104873660046125db565b610cdf565b34801561049857600080fd5b50610253610d63565b3480156104ad57600080fd5b506102536104bc366004612457565b610d99565b3480156104cd57600080fd5b506008546001600160a01b0316610297565b3480156104eb57600080fd5b5061026a610dfe565b34801561050057600080fd5b5061025361050f366004612678565b610e0d565b34801561052057600080fd5b5061025361052f36600461255d565b6111ba565b34801561054057600080fd5b5061025361054f3660046126cf565b6111ce565b6102536105623660046124e1565b611249565b34801561057357600080fd5b506102536105823660046126f1565b611276565b34801561059357600080fd5b5061026a6105a2366004612678565b611434565b3480156105b357600080fd5b506102536105c23660046127b6565b6115d3565b3480156105d357600080fd5b5061021e6105e2366004612472565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561061c57600080fd5b5061025361062b366004612457565b6116c4565b34801561063c57600080fd5b5061025361064b366004612726565b61175c565b34801561065c57600080fd5b50600c54610297906001600160a01b031681565b34801561067c57600080fd5b506102d761068b366004612594565b6117de565b600061069b82611972565b806106aa57506106aa826119c0565b92915050565b6008546001600160a01b031633146106e35760405162461bcd60e51b81526004016106da90612900565b60405180910390fd5b6001600160a01b03919091166000908152600d60205260409020805460ff1916911515919091179055565b60606002805461071d906129c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610749906129c3565b80156107965780601f1061076b57610100808354040283529160200191610796565b820191906000526020600020905b81548152906001019060200180831161077957829003601f168201915b5050505050905090565b60006107ab826119f5565b6107c8576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b816107ee81611a1c565b6107f88383611ae4565b505050565b826001600160a01b03811633146108175761081733611a1c565b610822848484611b84565b50505050565b6008546001600160a01b031633146108525760405162461bcd60e51b81526004016106da90612900565b600f5483106108735760405162461bcd60e51b81526004016106da906128d0565b6000600f848154811061088857610888612a59565b600091825260208083206007600b9093020191820180546001810182559084528184200180546001600160a01b039097166001600160a01b0319909716871790559482526008019093525060409091205550565b6000828152600b602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610951575060408051808201909152600a546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610970906001600160601b031687612961565b61097a919061294d565b915196919550909350505050565b6008546001600160a01b031633146109b25760405162461bcd60e51b81526004016106da90612900565b600f5481106109d35760405162461bcd60e51b81526004016106da906128d0565b6000600f82815481106109e8576109e8612a59565b90600052602060002090600b020190508281600601908051906020019061082292919061230c565b6008546001600160a01b03163314610a3a5760405162461bcd60e51b81526004016106da90612900565b600f80546001808201835560009283527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802600b909202918201805460ff191690911781557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80382018890557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80482018790557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80582018690557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80782018590557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8068201929092558251610b70917f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8080190602085019061230c565b50505050505050565b600f8181548110610b8957600080fd5b90600052602060002090600b02016000915090508060000160009054906101000a900460ff1690806001015490806002015490806003015490806004015490806005015490806006018054610bdd906129c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610c09906129c3565b8015610c565780601f10610c2b57610100808354040283529160200191610c56565b820191906000526020600020905b815481529060010190602001808311610c3957829003601f168201915b5050505050905087565b826001600160a01b0381163314610c7a57610c7a33611a1c565b610822848484611d12565b60006106aa82611d2d565b60006001600160a01b038216610cb9576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b6008546001600160a01b03163314610d095760405162461bcd60e51b81526004016106da90612900565b600f548110610d2a5760405162461bcd60e51b81526004016106da906128d0565b6000600f8281548110610d3f57610d3f612a59565b60009182526020909120600b90910201805460ff1916931515939093179092555050565b6008546001600160a01b03163314610d8d5760405162461bcd60e51b81526004016106da90612900565b610d976000611d95565b565b6008546001600160a01b03163314610dc35760405162461bcd60e51b81526004016106da90612900565b600c80546001600160a01b0319166001600160a01b03831690811791829055610dfb91600160a01b90046001600160601b0316611de7565b50565b60606003805461071d906129c3565b60026009541415610e605760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106da565b6002600955323314610eb45760405162461bcd60e51b815260206004820152601f60248201527f7468652063616c6c657220697320616e6f7468657220636f6e74726163742e0060448201526064016106da565b600f548110610ed55760405162461bcd60e51b81526004016106da906128d0565b6000600f8281548110610eea57610eea612a59565b60009182526020909120600b90910201805490915060ff1615610f5b5760405162461bcd60e51b815260206004820152602360248201527f4d696e74696e672069732070617573656420666f72207468697320676976656160448201526277617960e81b60648201526084016106da565b33600090815260098201602052604090205460ff1615610fc75760405162461bcd60e51b815260206004820152602160248201527f596f7520616c726561647920636c61696d656420796f757220676976656177616044820152607960f81b60648201526084016106da565b6000610fd333846117de565b9050600081116110255760405162461bcd60e51b815260206004820152601c60248201527f596f7520617265206e6f7420656c696769626c6520746f206d696e740000000060448201526064016106da565b60028201541580159061103b5750600382015415155b156110a45781600201544210158015611058575081600301544211155b6110a45760405162461bcd60e51b815260206004820181905260248201527f4769766561776179206973206e6f742063757272656e746c792061637469766560448201526064016106da565b816004015482600101546110b89190612980565b8111156111075760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f75676820746f6b656e73206c65667420746f206d696e74000060448201526064016106da565b60006111166001546000540390565b9050600060016111268484612935565b6111309190612980565b9050815b818111611187576004850180546000838152600a88016020908152604080832093909355600e90529081208890558154919061116f836129fe565b9190505550808061117f906129fe565b915050611134565b503360008181526009860160205260409020805460ff191660011790556111ae9084611ee4565b50506001600955505050565b816111c481611a1c565b6107f88383611f02565b6008546001600160a01b031633146111f85760405162461bcd60e51b81526004016106da90612900565b600f5481106112195760405162461bcd60e51b81526004016106da906128d0565b6000600f828154811061122e5761122e612a59565b600091825260209091206001600b9092020101929092555050565b836001600160a01b03811633146112635761126333611a1c565b61126f85858585611f6e565b5050505050565b336000908152600d602052604090205460ff1615156001146112d25760405162461bcd60e51b81526020600482015260156024820152741bdb9b1e4819da599d195c9cc818d85b8819da599d605a1b60448201526064016106da565b600f5483106112f35760405162461bcd60e51b81526004016106da906128d0565b6000600f848154811061130857611308612a59565b90600052602060002090600b020190508060040154816001015461132c9190612980565b8311156113a15760405162461bcd60e51b815260206004820152603b60248201527f43616e6e6f742067696674206d6f7265204e465473207468616e20746865206d60448201527f617820737570706c7920666f722074686973206769766561776179000000000060648201526084016106da565b60006113b06001546000540390565b9050600060016113c08684612935565b6113ca9190612980565b9050815b818111611421576004840180546000838152600a87016020908152604080832093909355600e905290812089905581549190611409836129fe565b91905055508080611419906129fe565b9150506113ce565b5061142c8486611ee4565b505050505050565b606061143f826119f5565b6114a35760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016106da565b6000828152600e6020526040812054600f8054919291839081106114c9576114c9612a59565b90600052602060002090600b020160060180546114e5906129c3565b80601f0160208091040260200160405190810160405280929190818152602001828054611511906129c3565b801561155e5780601f106115335761010080835404028352916020019161155e565b820191906000526020600020905b81548152906001019060200180831161154157829003601f168201915b505050505090506000600f838154811061157a5761157a612a59565b90600052602060002090600b0201600a016000868152602001908152602001600020549050816115a982611fb2565b6040516020016115ba92919061280b565b6040516020818303038152906040529350505050919050565b6008546001600160a01b031633146115fd5760405162461bcd60e51b81526004016106da90612900565b600c546001600160a01b031661168b5760405162461bcd60e51b815260206004820152604760248201527f73706c69742061646472657373206e6f74207365742c20706c6561736520736560448201527f742073706c69742061646472657373206265666f7265207570646174696e6720606482015266726f79616c747960c81b608482015260a4016106da565b600c80546001600160a01b03908116600160a01b6001600160601b03858116820283811795869055610dfb959416909217920416611de7565b6008546001600160a01b031633146116ee5760405162461bcd60e51b81526004016106da90612900565b6001600160a01b0381166117535760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106da565b610dfb81611d95565b6008546001600160a01b031633146117865760405162461bcd60e51b81526004016106da90612900565b600f5481106117a75760405162461bcd60e51b81526004016106da906128d0565b6000600f82815481106117bc576117bc612a59565b60009182526020909120600b9091020160028101949094555050600390910155565b600080600f83815481106117f4576117f4612a59565b90600052602060002090600b020160050154905060005b600f848154811061181e5761181e612a59565b90600052602060002090600b02016007018054905081101561196a576000600f858154811061184f5761184f612a59565b90600052602060002090600b0201600701828154811061187157611871612a59565b6000918252602082200154600f80546001600160a01b039092169350908790811061189e5761189e612a59565b600091825260208083206001600160a01b03868116808652600b9490940290910160080190915260408084205490516370a0823160e01b8152918b16600483015293506370a082319060240160206040518083038186803b15801561190257600080fd5b505afa158015611916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193a9190612691565b905060008111801561194b57508482115b15611954578194505b5050508080611962906129fe565b91505061180b565b509392505050565b60006301ffc9a760e01b6001600160e01b0319831614806119a357506380ac58cd60e01b6001600160e01b03198316145b806106aa5750506001600160e01b031916635b5e139f60e01b1490565b60006001600160e01b0319821663152a902d60e11b14806106aa57506301ffc9a760e01b6001600160e01b03198316146106aa565b60008054821080156106aa575050600090815260046020526040902054600160e01b161590565b6daaeb6d7670e522a718067333cd4e3b15610dfb57604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c61711349060440160206040518083038186803b158015611a8457600080fd5b505afa158015611a98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611abc91906125be565b610dfb57604051633b79c77360e21b81526001600160a01b03821660048201526024016106da565b6000611aef82610c85565b9050336001600160a01b03821614611b2857611b0b81336105e2565b611b28576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000611b8f82611d2d565b9050836001600160a01b0316816001600160a01b031614611bc25760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417611c0f57611bf286336105e2565b611c0f57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516611c3657604051633a954ecd60e21b815260040160405180910390fd5b8015611c4157600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040902055600160e11b8316611ccc5760018401600081815260046020526040902054611cca576000548114611cca5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461142c565b6107f883838360405180602001604052806000815250611249565b600081600054811015611d7c57600081815260046020526040902054600160e01b8116611d7a575b80611d73575060001901600081815260046020526040902054611d55565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b0382161115611e555760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084016106da565b6001600160a01b038216611eab5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016106da565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600a55565b611efe8282604051806020016040528060008152506120b8565b5050565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611f798484846107fd565b6001600160a01b0383163b1561082257611f958484848461211e565b610822576040516368d2bf6b60e11b815260040160405180910390fd5b606081611fd65750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120005780611fea816129fe565b9150611ff99050600a8361294d565b9150611fda565b60008167ffffffffffffffff81111561201b5761201b612a6f565b6040519080825280601f01601f191660200182016040528015612045576020820181803683370190505b5090505b84156120b05761205a600183612980565b9150612067600a86612a19565b612072906030612935565b60f81b81838151811061208757612087612a59565b60200101906001600160f81b031916908160001a9053506120a9600a8661294d565b9450612049565b949350505050565b6120c28383612215565b6001600160a01b0383163b156107f8576000548281035b6120ec600086838060010194508661211e565b612109576040516368d2bf6b60e11b815260040160405180910390fd5b8181106120d957816000541461126f57600080fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061215390339089908890889060040161283a565b602060405180830381600087803b15801561216d57600080fd5b505af192505050801561219d575060408051601f3d908101601f1916820190925261219a91810190612616565b60015b6121f8573d8080156121cb576040519150601f19603f3d011682016040523d82523d6000602084013e6121d0565b606091505b5080516121f0576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b600054816122365760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b8181146122e557808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001016122ad565b508161230357604051622e076360e81b815260040160405180910390fd5b60005550505050565b828054612318906129c3565b90600052602060002090601f01602090048101928261233a5760008555612380565b82601f1061235357805160ff1916838001178555612380565b82800160010185558215612380579182015b82811115612380578251825591602001919060010190612365565b5061238c929150612390565b5090565b5b8082111561238c5760008155600101612391565b600067ffffffffffffffff808411156123c0576123c0612a6f565b604051601f8501601f19908116603f011681019082821181831017156123e8576123e8612a6f565b8160405280935085815286868601111561240157600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461243257600080fd5b919050565b600082601f83011261244857600080fd5b611d73838335602085016123a5565b60006020828403121561246957600080fd5b611d738261241b565b6000806040838503121561248557600080fd5b61248e8361241b565b915061249c6020840161241b565b90509250929050565b6000806000606084860312156124ba57600080fd5b6124c38461241b565b92506124d16020850161241b565b9150604084013590509250925092565b600080600080608085870312156124f757600080fd5b6125008561241b565b935061250e6020860161241b565b925060408501359150606085013567ffffffffffffffff81111561253157600080fd5b8501601f8101871361254257600080fd5b612551878235602084016123a5565b91505092959194509250565b6000806040838503121561257057600080fd5b6125798361241b565b9150602083013561258981612a85565b809150509250929050565b600080604083850312156125a757600080fd5b6125b08361241b565b946020939093013593505050565b6000602082840312156125d057600080fd5b8151611d7381612a85565b600080604083850312156125ee57600080fd5b82356125b081612a85565b60006020828403121561260b57600080fd5b8135611d7381612a93565b60006020828403121561262857600080fd5b8151611d7381612a93565b6000806040838503121561264657600080fd5b823567ffffffffffffffff81111561265d57600080fd5b61266985828601612437565b95602094909401359450505050565b60006020828403121561268a57600080fd5b5035919050565b6000602082840312156126a357600080fd5b5051919050565b6000806000606084860312156126bf57600080fd5b833592506124d16020850161241b565b600080604083850312156126e257600080fd5b50508035926020909101359150565b60008060006060848603121561270657600080fd5b833592506020840135915061271d6040850161241b565b90509250925092565b60008060006060848603121561273b57600080fd5b505081359360208301359350604090920135919050565b600080600080600060a0868803121561276a57600080fd5b85359450602086013593506040860135925060608601359150608086013567ffffffffffffffff81111561279d57600080fd5b6127a988828901612437565b9150509295509295909350565b6000602082840312156127c857600080fd5b81356001600160601b0381168114611d7357600080fd5b600081518084526127f7816020860160208601612997565b601f01601f19169290920160200192915050565b6000835161281d818460208801612997565b835190830190612831818360208801612997565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061286d908301846127df565b9695505050505050565b87151581528660208201528560408201528460608201528360808201528260a082015260e060c082015260006128b060e08301846127df565b9998505050505050505050565b602081526000611d7360208301846127df565b602080825260169082015275092dcecc2d8d2c840ced2eccac2eec2f240d2dcc8caf60531b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000821982111561294857612948612a2d565b500190565b60008261295c5761295c612a43565b500490565b600081600019048311821515161561297b5761297b612a2d565b500290565b60008282101561299257612992612a2d565b500390565b60005b838110156129b257818101518382015260200161299a565b838111156108225750506000910152565b600181811c908216806129d757607f821691505b602082108114156129f857634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612a1257612a12612a2d565b5060010190565b600082612a2857612a28612a43565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610dfb57600080fd5b6001600160e01b031981168114610dfb57600080fdfea26469706673582212209ca00fc126322af60a46106d4fd2f30214f1c306e0d6e264438f496f51a3452d64736f6c63430008070033

Deployed Bytecode

0x6080604052600436106101f95760003560e01c80637120d5a31161010d578063b88d4fde116100a0578063e985e9c51161006f578063e985e9c5146105c7578063f2fde38b14610610578063f73285fb14610630578063f765417614610650578063fb19bc071461067057600080fd5b8063b88d4fde14610554578063c260804c14610567578063c87b56dd14610587578063e5ad0b2b146105a757600080fd5b806395d89b41116100dc57806395d89b41146104df578063a0712d68146104f4578063a22cb46514610514578063a7cc2c251461053457600080fd5b80637120d5a31461046c578063715018a61461048c578063856e0504146104a15780638da5cb5b146104c157600080fd5b80632a55205a1161019057806341f434341161015f57806341f43434146103ca57806342842e0e146103ec5780636352211e146103ff57806367f6326c1461041f57806370a082311461044c57600080fd5b80632a55205a146103185780633708d8f5146103575780633a204328146103775780633e06df3d1461039757600080fd5b8063095ea7b3116101cc578063095ea7b3146102af57806318160ddd146102c257806323b872dd146102e55780632625ebdf146102f857600080fd5b806301ffc9a7146101fe57806302acd0881461023357806306fdde0314610255578063081812fc14610277575b600080fd5b34801561020a57600080fd5b5061021e6102193660046125f9565b610690565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b5061025361024e36600461255d565b6106b0565b005b34801561026157600080fd5b5061026a61070e565b60405161022a91906128bd565b34801561028357600080fd5b50610297610292366004612678565b6107a0565b6040516001600160a01b03909116815260200161022a565b6102536102bd366004612594565b6107e4565b3480156102ce57600080fd5b50600154600054035b60405190815260200161022a565b6102536102f33660046124a5565b6107fd565b34801561030457600080fd5b506102536103133660046126aa565b610828565b34801561032457600080fd5b506103386103333660046126cf565b6108dc565b604080516001600160a01b03909316835260208301919091520161022a565b34801561036357600080fd5b50610253610372366004612633565b610988565b34801561038357600080fd5b50610253610392366004612752565b610a10565b3480156103a357600080fd5b506103b76103b2366004612678565b610b79565b60405161022a9796959493929190612877565b3480156103d657600080fd5b506102976daaeb6d7670e522a718067333cd4e81565b6102536103fa3660046124a5565b610c60565b34801561040b57600080fd5b5061029761041a366004612678565b610c85565b34801561042b57600080fd5b506102d761043a366004612678565b600e6020526000908152604090205481565b34801561045857600080fd5b506102d7610467366004612457565b610c90565b34801561047857600080fd5b506102536104873660046125db565b610cdf565b34801561049857600080fd5b50610253610d63565b3480156104ad57600080fd5b506102536104bc366004612457565b610d99565b3480156104cd57600080fd5b506008546001600160a01b0316610297565b3480156104eb57600080fd5b5061026a610dfe565b34801561050057600080fd5b5061025361050f366004612678565b610e0d565b34801561052057600080fd5b5061025361052f36600461255d565b6111ba565b34801561054057600080fd5b5061025361054f3660046126cf565b6111ce565b6102536105623660046124e1565b611249565b34801561057357600080fd5b506102536105823660046126f1565b611276565b34801561059357600080fd5b5061026a6105a2366004612678565b611434565b3480156105b357600080fd5b506102536105c23660046127b6565b6115d3565b3480156105d357600080fd5b5061021e6105e2366004612472565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561061c57600080fd5b5061025361062b366004612457565b6116c4565b34801561063c57600080fd5b5061025361064b366004612726565b61175c565b34801561065c57600080fd5b50600c54610297906001600160a01b031681565b34801561067c57600080fd5b506102d761068b366004612594565b6117de565b600061069b82611972565b806106aa57506106aa826119c0565b92915050565b6008546001600160a01b031633146106e35760405162461bcd60e51b81526004016106da90612900565b60405180910390fd5b6001600160a01b03919091166000908152600d60205260409020805460ff1916911515919091179055565b60606002805461071d906129c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610749906129c3565b80156107965780601f1061076b57610100808354040283529160200191610796565b820191906000526020600020905b81548152906001019060200180831161077957829003601f168201915b5050505050905090565b60006107ab826119f5565b6107c8576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b816107ee81611a1c565b6107f88383611ae4565b505050565b826001600160a01b03811633146108175761081733611a1c565b610822848484611b84565b50505050565b6008546001600160a01b031633146108525760405162461bcd60e51b81526004016106da90612900565b600f5483106108735760405162461bcd60e51b81526004016106da906128d0565b6000600f848154811061088857610888612a59565b600091825260208083206007600b9093020191820180546001810182559084528184200180546001600160a01b039097166001600160a01b0319909716871790559482526008019093525060409091205550565b6000828152600b602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610951575060408051808201909152600a546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610970906001600160601b031687612961565b61097a919061294d565b915196919550909350505050565b6008546001600160a01b031633146109b25760405162461bcd60e51b81526004016106da90612900565b600f5481106109d35760405162461bcd60e51b81526004016106da906128d0565b6000600f82815481106109e8576109e8612a59565b90600052602060002090600b020190508281600601908051906020019061082292919061230c565b6008546001600160a01b03163314610a3a5760405162461bcd60e51b81526004016106da90612900565b600f80546001808201835560009283527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802600b909202918201805460ff191690911781557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80382018890557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80482018790557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80582018690557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80782018590557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8068201929092558251610b70917f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8080190602085019061230c565b50505050505050565b600f8181548110610b8957600080fd5b90600052602060002090600b02016000915090508060000160009054906101000a900460ff1690806001015490806002015490806003015490806004015490806005015490806006018054610bdd906129c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610c09906129c3565b8015610c565780601f10610c2b57610100808354040283529160200191610c56565b820191906000526020600020905b815481529060010190602001808311610c3957829003601f168201915b5050505050905087565b826001600160a01b0381163314610c7a57610c7a33611a1c565b610822848484611d12565b60006106aa82611d2d565b60006001600160a01b038216610cb9576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b6008546001600160a01b03163314610d095760405162461bcd60e51b81526004016106da90612900565b600f548110610d2a5760405162461bcd60e51b81526004016106da906128d0565b6000600f8281548110610d3f57610d3f612a59565b60009182526020909120600b90910201805460ff1916931515939093179092555050565b6008546001600160a01b03163314610d8d5760405162461bcd60e51b81526004016106da90612900565b610d976000611d95565b565b6008546001600160a01b03163314610dc35760405162461bcd60e51b81526004016106da90612900565b600c80546001600160a01b0319166001600160a01b03831690811791829055610dfb91600160a01b90046001600160601b0316611de7565b50565b60606003805461071d906129c3565b60026009541415610e605760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106da565b6002600955323314610eb45760405162461bcd60e51b815260206004820152601f60248201527f7468652063616c6c657220697320616e6f7468657220636f6e74726163742e0060448201526064016106da565b600f548110610ed55760405162461bcd60e51b81526004016106da906128d0565b6000600f8281548110610eea57610eea612a59565b60009182526020909120600b90910201805490915060ff1615610f5b5760405162461bcd60e51b815260206004820152602360248201527f4d696e74696e672069732070617573656420666f72207468697320676976656160448201526277617960e81b60648201526084016106da565b33600090815260098201602052604090205460ff1615610fc75760405162461bcd60e51b815260206004820152602160248201527f596f7520616c726561647920636c61696d656420796f757220676976656177616044820152607960f81b60648201526084016106da565b6000610fd333846117de565b9050600081116110255760405162461bcd60e51b815260206004820152601c60248201527f596f7520617265206e6f7420656c696769626c6520746f206d696e740000000060448201526064016106da565b60028201541580159061103b5750600382015415155b156110a45781600201544210158015611058575081600301544211155b6110a45760405162461bcd60e51b815260206004820181905260248201527f4769766561776179206973206e6f742063757272656e746c792061637469766560448201526064016106da565b816004015482600101546110b89190612980565b8111156111075760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f75676820746f6b656e73206c65667420746f206d696e74000060448201526064016106da565b60006111166001546000540390565b9050600060016111268484612935565b6111309190612980565b9050815b818111611187576004850180546000838152600a88016020908152604080832093909355600e90529081208890558154919061116f836129fe565b9190505550808061117f906129fe565b915050611134565b503360008181526009860160205260409020805460ff191660011790556111ae9084611ee4565b50506001600955505050565b816111c481611a1c565b6107f88383611f02565b6008546001600160a01b031633146111f85760405162461bcd60e51b81526004016106da90612900565b600f5481106112195760405162461bcd60e51b81526004016106da906128d0565b6000600f828154811061122e5761122e612a59565b600091825260209091206001600b9092020101929092555050565b836001600160a01b03811633146112635761126333611a1c565b61126f85858585611f6e565b5050505050565b336000908152600d602052604090205460ff1615156001146112d25760405162461bcd60e51b81526020600482015260156024820152741bdb9b1e4819da599d195c9cc818d85b8819da599d605a1b60448201526064016106da565b600f5483106112f35760405162461bcd60e51b81526004016106da906128d0565b6000600f848154811061130857611308612a59565b90600052602060002090600b020190508060040154816001015461132c9190612980565b8311156113a15760405162461bcd60e51b815260206004820152603b60248201527f43616e6e6f742067696674206d6f7265204e465473207468616e20746865206d60448201527f617820737570706c7920666f722074686973206769766561776179000000000060648201526084016106da565b60006113b06001546000540390565b9050600060016113c08684612935565b6113ca9190612980565b9050815b818111611421576004840180546000838152600a87016020908152604080832093909355600e905290812089905581549190611409836129fe565b91905055508080611419906129fe565b9150506113ce565b5061142c8486611ee4565b505050505050565b606061143f826119f5565b6114a35760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016106da565b6000828152600e6020526040812054600f8054919291839081106114c9576114c9612a59565b90600052602060002090600b020160060180546114e5906129c3565b80601f0160208091040260200160405190810160405280929190818152602001828054611511906129c3565b801561155e5780601f106115335761010080835404028352916020019161155e565b820191906000526020600020905b81548152906001019060200180831161154157829003601f168201915b505050505090506000600f838154811061157a5761157a612a59565b90600052602060002090600b0201600a016000868152602001908152602001600020549050816115a982611fb2565b6040516020016115ba92919061280b565b6040516020818303038152906040529350505050919050565b6008546001600160a01b031633146115fd5760405162461bcd60e51b81526004016106da90612900565b600c546001600160a01b031661168b5760405162461bcd60e51b815260206004820152604760248201527f73706c69742061646472657373206e6f74207365742c20706c6561736520736560448201527f742073706c69742061646472657373206265666f7265207570646174696e6720606482015266726f79616c747960c81b608482015260a4016106da565b600c80546001600160a01b03908116600160a01b6001600160601b03858116820283811795869055610dfb959416909217920416611de7565b6008546001600160a01b031633146116ee5760405162461bcd60e51b81526004016106da90612900565b6001600160a01b0381166117535760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106da565b610dfb81611d95565b6008546001600160a01b031633146117865760405162461bcd60e51b81526004016106da90612900565b600f5481106117a75760405162461bcd60e51b81526004016106da906128d0565b6000600f82815481106117bc576117bc612a59565b60009182526020909120600b9091020160028101949094555050600390910155565b600080600f83815481106117f4576117f4612a59565b90600052602060002090600b020160050154905060005b600f848154811061181e5761181e612a59565b90600052602060002090600b02016007018054905081101561196a576000600f858154811061184f5761184f612a59565b90600052602060002090600b0201600701828154811061187157611871612a59565b6000918252602082200154600f80546001600160a01b039092169350908790811061189e5761189e612a59565b600091825260208083206001600160a01b03868116808652600b9490940290910160080190915260408084205490516370a0823160e01b8152918b16600483015293506370a082319060240160206040518083038186803b15801561190257600080fd5b505afa158015611916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193a9190612691565b905060008111801561194b57508482115b15611954578194505b5050508080611962906129fe565b91505061180b565b509392505050565b60006301ffc9a760e01b6001600160e01b0319831614806119a357506380ac58cd60e01b6001600160e01b03198316145b806106aa5750506001600160e01b031916635b5e139f60e01b1490565b60006001600160e01b0319821663152a902d60e11b14806106aa57506301ffc9a760e01b6001600160e01b03198316146106aa565b60008054821080156106aa575050600090815260046020526040902054600160e01b161590565b6daaeb6d7670e522a718067333cd4e3b15610dfb57604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c61711349060440160206040518083038186803b158015611a8457600080fd5b505afa158015611a98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611abc91906125be565b610dfb57604051633b79c77360e21b81526001600160a01b03821660048201526024016106da565b6000611aef82610c85565b9050336001600160a01b03821614611b2857611b0b81336105e2565b611b28576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000611b8f82611d2d565b9050836001600160a01b0316816001600160a01b031614611bc25760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417611c0f57611bf286336105e2565b611c0f57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516611c3657604051633a954ecd60e21b815260040160405180910390fd5b8015611c4157600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040902055600160e11b8316611ccc5760018401600081815260046020526040902054611cca576000548114611cca5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461142c565b6107f883838360405180602001604052806000815250611249565b600081600054811015611d7c57600081815260046020526040902054600160e01b8116611d7a575b80611d73575060001901600081815260046020526040902054611d55565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b0382161115611e555760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084016106da565b6001600160a01b038216611eab5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016106da565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600a55565b611efe8282604051806020016040528060008152506120b8565b5050565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611f798484846107fd565b6001600160a01b0383163b1561082257611f958484848461211e565b610822576040516368d2bf6b60e11b815260040160405180910390fd5b606081611fd65750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120005780611fea816129fe565b9150611ff99050600a8361294d565b9150611fda565b60008167ffffffffffffffff81111561201b5761201b612a6f565b6040519080825280601f01601f191660200182016040528015612045576020820181803683370190505b5090505b84156120b05761205a600183612980565b9150612067600a86612a19565b612072906030612935565b60f81b81838151811061208757612087612a59565b60200101906001600160f81b031916908160001a9053506120a9600a8661294d565b9450612049565b949350505050565b6120c28383612215565b6001600160a01b0383163b156107f8576000548281035b6120ec600086838060010194508661211e565b612109576040516368d2bf6b60e11b815260040160405180910390fd5b8181106120d957816000541461126f57600080fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061215390339089908890889060040161283a565b602060405180830381600087803b15801561216d57600080fd5b505af192505050801561219d575060408051601f3d908101601f1916820190925261219a91810190612616565b60015b6121f8573d8080156121cb576040519150601f19603f3d011682016040523d82523d6000602084013e6121d0565b606091505b5080516121f0576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b600054816122365760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b8181146122e557808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001016122ad565b508161230357604051622e076360e81b815260040160405180910390fd5b60005550505050565b828054612318906129c3565b90600052602060002090601f01602090048101928261233a5760008555612380565b82601f1061235357805160ff1916838001178555612380565b82800160010185558215612380579182015b82811115612380578251825591602001919060010190612365565b5061238c929150612390565b5090565b5b8082111561238c5760008155600101612391565b600067ffffffffffffffff808411156123c0576123c0612a6f565b604051601f8501601f19908116603f011681019082821181831017156123e8576123e8612a6f565b8160405280935085815286868601111561240157600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461243257600080fd5b919050565b600082601f83011261244857600080fd5b611d73838335602085016123a5565b60006020828403121561246957600080fd5b611d738261241b565b6000806040838503121561248557600080fd5b61248e8361241b565b915061249c6020840161241b565b90509250929050565b6000806000606084860312156124ba57600080fd5b6124c38461241b565b92506124d16020850161241b565b9150604084013590509250925092565b600080600080608085870312156124f757600080fd5b6125008561241b565b935061250e6020860161241b565b925060408501359150606085013567ffffffffffffffff81111561253157600080fd5b8501601f8101871361254257600080fd5b612551878235602084016123a5565b91505092959194509250565b6000806040838503121561257057600080fd5b6125798361241b565b9150602083013561258981612a85565b809150509250929050565b600080604083850312156125a757600080fd5b6125b08361241b565b946020939093013593505050565b6000602082840312156125d057600080fd5b8151611d7381612a85565b600080604083850312156125ee57600080fd5b82356125b081612a85565b60006020828403121561260b57600080fd5b8135611d7381612a93565b60006020828403121561262857600080fd5b8151611d7381612a93565b6000806040838503121561264657600080fd5b823567ffffffffffffffff81111561265d57600080fd5b61266985828601612437565b95602094909401359450505050565b60006020828403121561268a57600080fd5b5035919050565b6000602082840312156126a357600080fd5b5051919050565b6000806000606084860312156126bf57600080fd5b833592506124d16020850161241b565b600080604083850312156126e257600080fd5b50508035926020909101359150565b60008060006060848603121561270657600080fd5b833592506020840135915061271d6040850161241b565b90509250925092565b60008060006060848603121561273b57600080fd5b505081359360208301359350604090920135919050565b600080600080600060a0868803121561276a57600080fd5b85359450602086013593506040860135925060608601359150608086013567ffffffffffffffff81111561279d57600080fd5b6127a988828901612437565b9150509295509295909350565b6000602082840312156127c857600080fd5b81356001600160601b0381168114611d7357600080fd5b600081518084526127f7816020860160208601612997565b601f01601f19169290920160200192915050565b6000835161281d818460208801612997565b835190830190612831818360208801612997565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061286d908301846127df565b9695505050505050565b87151581528660208201528560408201528460608201528360808201528260a082015260e060c082015260006128b060e08301846127df565b9998505050505050505050565b602081526000611d7360208301846127df565b602080825260169082015275092dcecc2d8d2c840ced2eccac2eec2f240d2dcc8caf60531b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000821982111561294857612948612a2d565b500190565b60008261295c5761295c612a43565b500490565b600081600019048311821515161561297b5761297b612a2d565b500290565b60008282101561299257612992612a2d565b500390565b60005b838110156129b257818101518382015260200161299a565b838111156108225750506000910152565b600181811c908216806129d757607f821691505b602082108114156129f857634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612a1257612a12612a2d565b5060010190565b600082612a2857612a28612a43565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610dfb57600080fd5b6001600160e01b031981168114610dfb57600080fdfea26469706673582212209ca00fc126322af60a46106d4fd2f30214f1c306e0d6e264438f496f51a3452d64736f6c63430008070033

Deployed Bytecode Sourcemap

87278:8643:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95663:255;;;;;;;;;;-1:-1:-1;95663:255:0;;;;;:::i;:::-;;:::i;:::-;;;9247:14:1;;9240:22;9222:41;;9210:2;9195:18;95663:255:0;;;;;;;;94249:118;;;;;;;;;;-1:-1:-1;94249:118:0;;;;;:::i;:::-;;:::i;:::-;;55011:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;61502:218::-;;;;;;;;;;-1:-1:-1;61502:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7957:32:1;;;7939:51;;7927:2;7912:18;61502:218:0;7793:203:1;94871:165:0;;;;;;:::i;:::-;;:::i;50762:323::-;;;;;;;;;;-1:-1:-1;51036:12:0;;50823:7;51020:13;:28;50762:323;;;16709:25:1;;;16697:2;16682:18;50762:323:0;16563:177:1;95044:171:0;;;;;;:::i;:::-;;:::i;90418:444::-;;;;;;;;;;-1:-1:-1;90418:444:0;;;;;:::i;:::-;;:::i;18141:442::-;;;;;;;;;;-1:-1:-1;18141:442:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;8995:32:1;;;8977:51;;9059:2;9044:18;;9037:34;;;;8950:18;18141:442:0;8803:274:1;90123:287:0;;;;;;;;;;-1:-1:-1;90123:287:0;;;;;:::i;:::-;;:::i;88613:560::-;;;;;;;;;;-1:-1:-1;88613:560:0;;;;;:::i;:::-;;:::i;88057:27::-;;;;;;;;;;-1:-1:-1;88057:27:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;:::i;2867:143::-;;;;;;;;;;;;2967:42;2867:143;;95223:179;;;;;;:::i;:::-;;:::i;56404:152::-;;;;;;;;;;-1:-1:-1;56404:152:0;;;;;:::i;:::-;;:::i;87553:50::-;;;;;;;;;;-1:-1:-1;87553:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;51946:233;;;;;;;;;;-1:-1:-1;51946:233:0;;;;;:::i;:::-;;:::i;89181:290::-;;;;;;;;;;-1:-1:-1;89181:290:0;;;;;:::i;:::-;;:::i;12824:103::-;;;;;;;;;;;;;:::i;88462:143::-;;;;;;;;;;-1:-1:-1;88462:143:0;;;;;:::i;:::-;;:::i;12173:87::-;;;;;;;;;;-1:-1:-1;12246:6:0;;-1:-1:-1;;;;;12246:6:0;12173:87;;55187:104;;;;;;;;;;;;;:::i;92319:1346::-;;;;;;;;;;-1:-1:-1;92319:1346:0;;;;;:::i;:::-;;:::i;94687:176::-;;;;;;;;;;-1:-1:-1;94687:176:0;;;;;:::i;:::-;;:::i;89479:286::-;;;;;;;;;;-1:-1:-1;89479:286:0;;;;;:::i;:::-;;:::i;95410:245::-;;;;;;:::i;:::-;;:::i;91554:757::-;;;;;;;;;;-1:-1:-1;91554:757:0;;;;;:::i;:::-;;:::i;93773:468::-;;;;;;;;;;-1:-1:-1;93773:468:0;;;;;:::i;:::-;;:::i;94375:263::-;;;;;;;;;;-1:-1:-1;94375:263:0;;;;;:::i;:::-;;:::i;62451:164::-;;;;;;;;;;-1:-1:-1;62451:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;62572:25:0;;;62548:4;62572:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;62451:164;13082:201;;;;;;;;;;-1:-1:-1;13082:201:0;;;;;:::i;:::-;;:::i;89773:342::-;;;;;;;;;;-1:-1:-1;89773:342:0;;;;;:::i;:::-;;:::i;87436:20::-;;;;;;;;;;-1:-1:-1;87436:20:0;;;;-1:-1:-1;;;;;87436:20:0;;;90870:676;;;;;;;;;;-1:-1:-1;90870:676:0;;;;;:::i;:::-;;:::i;95663:255::-;95778:4;95816:38;95842:11;95816:25;:38::i;:::-;:94;;;;95872:38;95898:11;95872:25;:38::i;:::-;95795:115;95663:255;-1:-1:-1;;95663:255:0:o;94249:118::-;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;94332:17:0;;;::::1;;::::0;;;:7:::1;:17;::::0;;;;:27;;-1:-1:-1;;94332:27:0::1;::::0;::::1;;::::0;;;::::1;::::0;;94249:118::o;55011:100::-;55065:13;55098:5;55091:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55011:100;:::o;61502:218::-;61578:7;61603:16;61611:7;61603;:16::i;:::-;61598:64;;61628:34;;-1:-1:-1;;;61628:34:0;;;;;;;;;;;61598:64;-1:-1:-1;61682:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;61682:30:0;;61502:218::o;94871:165::-;94975:8;4388:30;4409:8;4388:20;:30::i;:::-;94996:32:::1;95010:8;95020:7;94996:13;:32::i;:::-;94871:165:::0;;;:::o;95044:171::-;95153:4;-1:-1:-1;;;;;4208:18:0;;4216:10;4208:18;4204:83;;4243:32;4264:10;4243:20;:32::i;:::-;95170:37:::1;95189:4;95195:2;95199:7;95170:18;:37::i;:::-;95044:171:::0;;;;:::o;90418:444::-;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;90610:9:::1;:16:::0;90593:33;::::1;90585:68;;;;-1:-1:-1::0;;;90585:68:0::1;;;;;;;:::i;:::-;90664:25;90692:9;90702:14;90692:25;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;90728:28:::1;90692:25;::::0;;::::1;;90728:28:::0;;::::1;:51:::0;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;;-1:-1:-1;;;;;90728:51:0;;::::1;-1:-1:-1::0;;;;;;90728:51:0;;::::1;::::0;::::1;::::0;;90790:49;;;:31:::1;;:49:::0;;;-1:-1:-1;90790:49:0;;;;:64;-1:-1:-1;90418:444:0:o;18141:442::-;18238:7;18296:27;;;:17;:27;;;;;;;;18267:56;;;;;;;;;-1:-1:-1;;;;;18267:56:0;;;;;-1:-1:-1;;;18267:56:0;;;-1:-1:-1;;;;;18267:56:0;;;;;;;;18238:7;;18336:92;;-1:-1:-1;18387:29:0;;;;;;;;;18397:19;18387:29;-1:-1:-1;;;;;18387:29:0;;;;-1:-1:-1;;;18387:29:0;;-1:-1:-1;;;;;18387:29:0;;;;;18336:92;18478:23;;;;18440:21;;18949:5;;18465:36;;-1:-1:-1;;;;;18465:36:0;:10;:36;:::i;:::-;18464:58;;;;:::i;:::-;18543:16;;;;;-1:-1:-1;18141:442:0;;-1:-1:-1;;;;18141:442:0:o;90123:287::-;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;90257:9:::1;:16:::0;90240:33;::::1;90232:68;;;;-1:-1:-1::0;;;90232:68:0::1;;;;;;;:::i;:::-;90311:25;90339:9;90349:14;90339:25;;;;;;;;:::i;:::-;;;;;;;;;;;90311:53;;90394:8;90375;:16;;:27;;;;;;;;;;;;:::i;88613:560::-:0;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;88854:9:::1;:16:::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;88854:16:0;;;;::::1;::::0;;::::1;::::0;;::::1;88881:26:::0;;-1:-1:-1;;88881:26:0::1;::::0;;::::1;::::0;;88918:18;;;:31;;;88960:18;;;:31;;;89002:16;;;:27;;;89040:26;;;:47;;;89098:25;;;:29;;;;89138:27;;::::1;::::0;:16;;;88854::::1;89138:27:::0;::::1;::::0;::::1;:::i;:::-;;88815:358;88613:560:::0;;;;;:::o;88057:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;95223:179::-;95336:4;-1:-1:-1;;;;;4208:18:0;;4216:10;4208:18;4204:83;;4243:32;4264:10;4243:20;:32::i;:::-;95353:41:::1;95376:4;95382:2;95386:7;95353:22;:41::i;56404:152::-:0;56476:7;56519:27;56538:7;56519:18;:27::i;51946:233::-;52018:7;-1:-1:-1;;;;;52042:19:0;;52038:60;;52070:28;;-1:-1:-1;;;52070:28:0;;;;;;;;;;;52038:60;-1:-1:-1;;;;;;52116:25:0;;;;;:18;:25;;;;;;46105:13;52116:55;;51946:233::o;89181:290::-;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;89312:9:::1;:16:::0;89295:33;::::1;89287:68;;;;-1:-1:-1::0;;;89287:68:0::1;;;;;;;:::i;:::-;89366:25;89394:9;89404:14;89394:25;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;89430:33:::0;;-1:-1:-1;;89430:33:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;-1:-1:-1;;89181:290:0:o;12824:103::-;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;12889:30:::1;12916:1;12889:18;:30::i;:::-;12824:103::o:0;88462:143::-;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;88533:5:::1;:16:::0;;-1:-1:-1;;;;;;88533:16:0::1;-1:-1:-1::0;;;;;88533:16:0;::::1;::::0;;::::1;::::0;;;;88560:37:::1;::::0;-1:-1:-1;;;88586:10:0;::::1;-1:-1:-1::0;;;;;88586:10:0::1;88560:18;:37::i;:::-;88462:143:::0;:::o;55187:104::-;55243:13;55276:7;55269:14;;;;;:::i;92319:1346::-;9271:1;9869:7;;:19;;9861:63;;;;-1:-1:-1;;;9861:63:0;;16051:2:1;9861:63:0;;;16033:21:1;16090:2;16070:18;;;16063:30;16129:33;16109:18;;;16102:61;16180:18;;9861:63:0;15849:355:1;9861:63:0;9271:1;10002:7;:18;88258:9:::1;88271:10;88258:23;88250:67;;;::::0;-1:-1:-1;;;88250:67:0;;12080:2:1;88250:67:0::1;::::0;::::1;12062:21:1::0;12119:2;12099:18;;;12092:30;12158:33;12138:18;;;12131:61;12209:18;;88250:67:0::1;11878:355:1::0;88250:67:0::1;92424:9:::2;:16:::0;92408:32;::::2;92400:67;;;;-1:-1:-1::0;;;92400:67:0::2;;;;;;;:::i;:::-;92480:25;92508:9;92518:13;92508:24;;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;92553:19:::0;;92508:24;;-1:-1:-1;92553:19:0::2;;:28;92545:76;;;::::0;-1:-1:-1;;;92545:76:0;;14525:2:1;92545:76:0::2;::::0;::::2;14507:21:1::0;14564:2;14544:18;;;14537:30;14603:34;14583:18;;;14576:62;-1:-1:-1;;;14654:18:1;;;14647:33;14697:19;;92545:76:0::2;14323:399:1::0;92545:76:0::2;92667:10;92642:36;::::0;;;:24:::2;::::0;::::2;:36;::::0;;;;;::::2;;:45;92634:91;;;::::0;-1:-1:-1;;;92634:91:0;;13336:2:1;92634:91:0::2;::::0;::::2;13318:21:1::0;13375:2;13355:18;;;13348:30;13414:34;13394:18;;;13387:62;-1:-1:-1;;;13465:18:1;;;13458:31;13506:19;;92634:91:0::2;13134:397:1::0;92634:91:0::2;92738:19;92760:44;92778:10;92790:13;92760:17;:44::i;:::-;92738:66;;92839:1;92825:11;:15;92817:56;;;::::0;-1:-1:-1;;;92817:56:0;;10604:2:1;92817:56:0::2;::::0;::::2;10586:21:1::0;10643:2;10623:18;;;10616:30;10682;10662:18;;;10655:58;10730:18;;92817:56:0::2;10402:352:1::0;92817:56:0::2;92889:18;::::0;::::2;::::0;:23;;::::2;::::0;:48:::2;;-1:-1:-1::0;92916:16:0::2;::::0;::::2;::::0;:21;::::2;92889:48;92886:201;;;92981:8;:18;;;92962:15;:37;;:76;;;;;93022:8;:16;;;93003:15;:35;;92962:76;92954:121;;;::::0;-1:-1:-1;;;92954:121:0;;15340:2:1;92954:121:0::2;::::0;::::2;15322:21:1::0;;;15359:18;;;15352:30;15418:34;15398:18;;;15391:62;15470:18;;92954:121:0::2;15138:356:1::0;92954:121:0::2;93143:8;:25;;;93122:8;:18;;;:46;;;;:::i;:::-;93107:11;:61;;93099:104;;;::::0;-1:-1:-1;;;93099:104:0;;13738:2:1;93099:104:0::2;::::0;::::2;13720:21:1::0;13777:2;13757:18;;;13750:30;13816:32;13796:18;;;13789:60;13866:18;;93099:104:0::2;13536:354:1::0;93099:104:0::2;93218:18;93239:13;51036:12:::0;;50823:7;51020:13;:28;;50762:323;93239:13:::2;93218:34:::0;-1:-1:-1;93263:18:0::2;93311:1;93284:24;93297:11:::0;93218:34;93284:24:::2;:::i;:::-;:28;;;;:::i;:::-;93263:49:::0;-1:-1:-1;93341:10:0;93325:230:::2;93358:10;93353:1;:15;93325:230;;93423:25;::::0;::::2;::::0;;93390:30:::2;::::0;;;:27:::2;::::0;::::2;:30;::::0;;;;;;;:58;;;;93465:15:::2;:18:::0;;;;;:34;;;93516:27;;;93423:25;93516:27:::2;::::0;::::2;:::i;:::-;;;;;;93370:3;;;;;:::i;:::-;;;;93325:230;;;-1:-1:-1::0;93592:10:0::2;93567:36;::::0;;;:24:::2;::::0;::::2;:36;::::0;;;;:43;;-1:-1:-1;;93567:43:0::2;93606:4;93567:43;::::0;;93623:34:::2;::::0;93645:11;93623:9:::2;:34::i;:::-;-1:-1:-1::0;;9227:1:0;10181:7;:22;-1:-1:-1;;;92319:1346:0:o;94687:176::-;94791:8;4388:30;4409:8;4388:20;:30::i;:::-;94812:43:::1;94836:8;94846;94812:23;:43::i;89479:286::-:0;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;89608:9:::1;:16:::0;89591:33;::::1;89583:68;;;;-1:-1:-1::0;;;89583:68:0::1;;;;;;;:::i;:::-;89662:25;89690:9;89700:14;89690:25;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;89726:18:::1;89690:25;::::0;;::::1;;89726:18;:31:::0;;;;-1:-1:-1;;89479:286:0:o;95410:245::-;95578:4;-1:-1:-1;;;;;4208:18:0;;4216:10;4208:18;4204:83;;4243:32;4264:10;4243:20;:32::i;:::-;95600:47:::1;95623:4;95629:2;95633:7;95642:4;95600:22;:47::i;:::-;95410:245:::0;;;;;:::o;91554:757::-;88142:10;88134:19;;;;:7;:19;;;;;;;;:27;;:19;:27;88126:61;;;;-1:-1:-1;;;88126:61:0;;15701:2:1;88126:61:0;;;15683:21:1;15740:2;15720:18;;;15713:30;-1:-1:-1;;;15759:18:1;;;15752:51;15820:18;;88126:61:0;15499:345:1;88126:61:0;91674:9:::1;:16:::0;91658:32;::::1;91650:67;;;;-1:-1:-1::0;;;91650:67:0::1;;;;;;;:::i;:::-;91730:25;91758:9;91768:13;91758:24;;;;;;;;:::i;:::-;;;;;;;;;;;91730:52;;91836:8;:25;;;91815:8;:18;;;:46;;;;:::i;:::-;91803:8;:58;;91795:130;;;::::0;-1:-1:-1;;;91795:130:0;;14097:2:1;91795:130:0::1;::::0;::::1;14079:21:1::0;14136:2;14116:18;;;14109:30;14175:34;14155:18;;;14148:62;14246:29;14226:18;;;14219:57;14293:19;;91795:130:0::1;13895:423:1::0;91795:130:0::1;91938:18;91959:13;51036:12:::0;;50823:7;51020:13;:28;;50762:323;91959:13:::1;91938:34:::0;-1:-1:-1;91983:18:0::1;92028:1;92004:21;92017:8:::0;91938:34;92004:21:::1;:::i;:::-;:25;;;;:::i;:::-;91983:46:::0;-1:-1:-1;92058:10:0;92042:226:::1;92075:10;92070:1;:15;92042:226;;92140:25;::::0;::::1;::::0;;92107:30:::1;::::0;;;:27:::1;::::0;::::1;:30;::::0;;;;;;;:58;;;;92180:15:::1;:18:::0;;;;;:34;;;92229:27;;;92140:25;92229:27:::1;::::0;::::1;:::i;:::-;;;;;;92087:3;;;;;:::i;:::-;;;;92042:226;;;;92280:23;92290:2;92294:8;92280:9;:23::i;:::-;91639:672;;;91554:757:::0;;;:::o;93773:468::-;93839:13;93873:17;93881:8;93873:7;:17::i;:::-;93865:77;;;;-1:-1:-1;;;93865:77:0;;12920:2:1;93865:77:0;;;12902:21:1;12959:2;12939:18;;;12932:30;12998:34;12978:18;;;12971:62;-1:-1:-1;;;13049:18:1;;;13042:45;13104:19;;93865:77:0;12718:411:1;93865:77:0;93953:21;93977:25;;;:15;:25;;;;;;94037:9;:24;;93977:25;;93953:21;93977:25;;94037:24;;;;;;:::i;:::-;;;;;;;;;;;:32;;94013:56;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94080:17;94100:9;94110:13;94100:24;;;;;;;;:::i;:::-;;;;;;;;;;;:43;;:53;94144:8;94100:53;;;;;;;;;;;;94080:73;;94195:7;94204:27;94221:9;94204:16;:27::i;:::-;94178:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;94164:69;;;;;93773:468;;;:::o;94375:263::-;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;94454:5:::1;::::0;-1:-1:-1;;;;;94454:5:0::1;94446:101;;;::::0;-1:-1:-1;;;94446:101:0;;12440:2:1;94446:101:0::1;::::0;::::1;12422:21:1::0;12479:2;12459:18;;;12452:30;12518:34;12498:18;;;12491:62;12589:34;12569:18;;;12562:62;-1:-1:-1;;;12640:19:1;;;12633:38;12688:19;;94446:101:0::1;12238:475:1::0;94446:101:0::1;94558:10;:24:::0;;-1:-1:-1;;;;;94558:24:0;;::::1;-1:-1:-1::0;;;;;;;;94558:24:0;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;94593:37:::1;::::0;94612:5;;;;;;94619:10:::1;;94593:18;:37::i;13082:201::-:0;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;13171:22:0;::::1;13163:73;;;::::0;-1:-1:-1;;;13163:73:0;;10961:2:1;13163:73:0::1;::::0;::::1;10943:21:1::0;11000:2;10980:18;;;10973:30;11039:34;11019:18;;;11012:62;-1:-1:-1;;;11090:18:1;;;11083:36;11136:19;;13163:73:0::1;10759:402:1::0;13163:73:0::1;13247:28;13266:8;13247:18;:28::i;89773:342::-:0;12246:6;;-1:-1:-1;;;;;12246:6:0;10977:10;12393:23;12385:68;;;;-1:-1:-1;;;12385:68:0;;;;;;;:::i;:::-;89920:9:::1;:16:::0;89903:33;::::1;89895:68;;;;-1:-1:-1::0;;;89895:68:0::1;;;;;;;:::i;:::-;89974:25;90002:9;90012:14;90002:25;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;90038:18;::::0;::::1;:31:::0;;;;-1:-1:-1;;90080:16:0::1;::::0;;::::1;:27:::0;89773:342::o;90870:676::-;90957:7;90977:19;90999:9;91009:13;90999:24;;;;;;;;:::i;:::-;;;;;;;;;;;:42;;;90977:64;;91058:9;91054:454;91077:9;91087:13;91077:24;;;;;;;;:::i;:::-;;;;;;;;;;;:44;;:51;;;;91073:1;:55;91054:454;;;91150:15;91168:9;91178:13;91168:24;;;;;;;;:::i;:::-;;;;;;;;;;;:44;;91213:1;91168:47;;;;;;;;:::i;:::-;;;;;;;;;;91252:9;:24;;-1:-1:-1;;;;;91168:47:0;;;;-1:-1:-1;91252:9:0;91262:13;;91252:24;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;91252:56:0;;;;;;:24;;;;;;;;:47;;:56;;;;;;;;91341:34;;-1:-1:-1;;;91341:34:0;;7957:32:1;;;91341:34:0;;;7939:51:1;91252:56:0;-1:-1:-1;91341:26:0;;7912:18:1;;91341:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91323:52;;91405:1;91395:7;:11;:40;;;;;91424:11;91410;:25;91395:40;91392:105;;;91470:11;91456:25;;91392:105;91135:373;;;91130:3;;;;;:::i;:::-;;;;91054:454;;;-1:-1:-1;91527:11:0;90870:676;-1:-1:-1;;;90870:676:0:o;54109:639::-;54194:4;-1:-1:-1;;;;;;;;;54518:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;54595:25:0;;;54518:102;:179;;;-1:-1:-1;;;;;;;;54672:25:0;-1:-1:-1;;;54672:25:0;;54109:639::o;17871:215::-;17973:4;-1:-1:-1;;;;;;17997:41:0;;-1:-1:-1;;;17997:41:0;;:81;;-1:-1:-1;;;;;;;;;;15532:40:0;;;18042:36;15423:157;62873:282;62938:4;63028:13;;63018:7;:23;62975:153;;;;-1:-1:-1;;63079:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;63079:44:0;:49;;62873:282::o;4446:419::-;2967:42;4637:45;:49;4633:225;;4708:67;;-1:-1:-1;;;4708:67:0;;4759:4;4708:67;;;8213:34:1;-1:-1:-1;;;;;8283:15:1;;8263:18;;;8256:43;2967:42:0;;4708;;8148:18:1;;4708:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4703:144;;4803:28;;-1:-1:-1;;;4803:28:0;;-1:-1:-1;;;;;7957:32:1;;4803:28:0;;;7939:51:1;7912:18;;4803:28:0;7793:203:1;60935:408:0;61024:13;61040:16;61048:7;61040;:16::i;:::-;61024:32;-1:-1:-1;10977:10:0;-1:-1:-1;;;;;61073:28:0;;;61069:175;;61121:44;61138:5;10977:10;62451:164;:::i;61121:44::-;61116:128;;61193:35;;-1:-1:-1;;;61193:35:0;;;;;;;;;;;61116:128;61256:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;61256:35:0;-1:-1:-1;;;;;61256:35:0;;;;;;;;;61307:28;;61256:24;;61307:28;;;;;;;61013:330;60935:408;;:::o;65141:2825::-;65283:27;65313;65332:7;65313:18;:27::i;:::-;65283:57;;65398:4;-1:-1:-1;;;;;65357:45:0;65373:19;-1:-1:-1;;;;;65357:45:0;;65353:86;;65411:28;;-1:-1:-1;;;65411:28:0;;;;;;;;;;;65353:86;65453:27;64249:24;;;:15;:24;;;;;64477:26;;10977:10;63874:30;;;-1:-1:-1;;;;;63567:28:0;;63852:20;;;63849:56;65639:180;;65732:43;65749:4;10977:10;62451:164;:::i;65732:43::-;65727:92;;65784:35;;-1:-1:-1;;;65784:35:0;;;;;;;;;;;65727:92;-1:-1:-1;;;;;65836:16:0;;65832:52;;65861:23;;-1:-1:-1;;;65861:23:0;;;;;;;;;;;65832:52;66033:15;66030:160;;;66173:1;66152:19;66145:30;66030:160;-1:-1:-1;;;;;66570:24:0;;;;;;;:18;:24;;;;;;66568:26;;-1:-1:-1;;66568:26:0;;;66639:22;;;;;;;;;66637:24;;-1:-1:-1;66637:24:0;;;59793:11;59768:23;59764:41;59751:63;-1:-1:-1;;;59751:63:0;66932:26;;;;:17;:26;;;;;:175;-1:-1:-1;;;67227:47:0;;67223:627;;67332:1;67322:11;;67300:19;67455:30;;;:17;:30;;;;;;67451:384;;67593:13;;67578:11;:28;67574:242;;67740:30;;;;:17;:30;;;;;:52;;;67574:242;67281:569;67223:627;67897:7;67893:2;-1:-1:-1;;;;;67878:27:0;67887:4;-1:-1:-1;;;;;67878:27:0;;;;;;;;;;;67916:42;95044:171;68062:193;68208:39;68225:4;68231:2;68235:7;68208:39;;;;;;;;;;;;:16;:39::i;57559:1275::-;57626:7;57661;57763:13;;57756:4;:20;57752:1015;;;57801:14;57818:23;;;:17;:23;;;;;;-1:-1:-1;;;57907:24:0;;57903:845;;58572:113;58579:11;58572:113;;-1:-1:-1;;;58650:6:0;58632:25;;;;:17;:25;;;;;;58572:113;;;58718:6;57559:1275;-1:-1:-1;;;57559:1275:0:o;57903:845::-;57778:989;57752:1015;58795:31;;-1:-1:-1;;;58795:31:0;;;;;;;;;;;13443:191;13536:6;;;-1:-1:-1;;;;;13553:17:0;;;-1:-1:-1;;;;;;13553:17:0;;;;;;;13586:40;;13536:6;;;13553:17;13536:6;;13586:40;;13517:16;;13586:40;13506:128;13443:191;:::o;19233:332::-;18949:5;-1:-1:-1;;;;;19336:33:0;;;;19328:88;;;;-1:-1:-1;;;19328:88:0;;14929:2:1;19328:88:0;;;14911:21:1;14968:2;14948:18;;;14941:30;15007:34;14987:18;;;14980:62;-1:-1:-1;;;15058:18:1;;;15051:40;15108:19;;19328:88:0;14727:406:1;19328:88:0;-1:-1:-1;;;;;19435:22:0;;19427:60;;;;-1:-1:-1;;;19427:60:0;;16411:2:1;19427:60:0;;;16393:21:1;16450:2;16430:18;;;16423:30;16489:27;16469:18;;;16462:55;16534:18;;19427:60:0;16209:349:1;19427:60:0;19522:35;;;;;;;;;-1:-1:-1;;;;;19522:35:0;;;;;;-1:-1:-1;;;;;19522:35:0;;;;;;;;;;-1:-1:-1;;;19500:57:0;;;;:19;:57;19233:332::o;79013:112::-;79090:27;79100:2;79104:8;79090:27;;;;;;;;;;;;:9;:27::i;:::-;79013:112;;:::o;62060:234::-;10977:10;62155:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;62155:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;62155:60:0;;;;;;;;;;62231:55;;9222:41:1;;;62155:49:0;;10977:10;62231:55;;9195:18:1;62231:55:0;;;;;;;62060:234;;:::o;68853:407::-;69028:31;69041:4;69047:2;69051:7;69028:12;:31::i;:::-;-1:-1:-1;;;;;69074:14:0;;;:19;69070:183;;69113:56;69144:4;69150:2;69154:7;69163:5;69113:30;:56::i;:::-;69108:145;;69197:40;;-1:-1:-1;;;69197:40:0;;;;;;;;;;;5700:723;5756:13;5977:10;5973:53;;-1:-1:-1;;6004:10:0;;;;;;;;;;;;-1:-1:-1;;;6004:10:0;;;;;5700:723::o;5973:53::-;6051:5;6036:12;6092:78;6099:9;;6092:78;;6125:8;;;;:::i;:::-;;-1:-1:-1;6148:10:0;;-1:-1:-1;6156:2:0;6148:10;;:::i;:::-;;;6092:78;;;6180:19;6212:6;6202:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6202:17:0;;6180:39;;6230:154;6237:10;;6230:154;;6264:11;6274:1;6264:11;;:::i;:::-;;-1:-1:-1;6333:10:0;6341:2;6333:5;:10;:::i;:::-;6320:24;;:2;:24;:::i;:::-;6307:39;;6290:6;6297;6290:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;6290:56:0;;;;;;;;-1:-1:-1;6361:11:0;6370:2;6361:11;;:::i;:::-;;;6230:154;;;6408:6;5700:723;-1:-1:-1;;;;5700:723:0:o;78240:689::-;78371:19;78377:2;78381:8;78371:5;:19::i;:::-;-1:-1:-1;;;;;78432:14:0;;;:19;78428:483;;78472:11;78486:13;78534:14;;;78567:233;78598:62;78637:1;78641:2;78645:7;;;;;;78654:5;78598:30;:62::i;:::-;78593:167;;78696:40;;-1:-1:-1;;;78696:40:0;;;;;;;;;;;78593:167;78795:3;78787:5;:11;78567:233;;78882:3;78865:13;;:20;78861:34;;78887:8;;;71344:716;71528:88;;-1:-1:-1;;;71528:88:0;;71507:4;;-1:-1:-1;;;;;71528:45:0;;;;;:88;;10977:10;;71595:4;;71601:7;;71610:5;;71528:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71528:88:0;;;;;;;;-1:-1:-1;;71528:88:0;;;;;;;;;;;;:::i;:::-;;;71524:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71811:13:0;;71807:235;;71857:40;;-1:-1:-1;;;71857:40:0;;;;;;;;;;;71807:235;72000:6;71994:13;71985:6;71981:2;71977:15;71970:38;71524:529;-1:-1:-1;;;;;;71687:64:0;-1:-1:-1;;;71687:64:0;;-1:-1:-1;71344:716:0;;;;;;:::o;72522:2966::-;72595:20;72618:13;72646;72642:44;;72668:18;;-1:-1:-1;;;72668:18:0;;;;;;;;;;;72642:44;-1:-1:-1;;;;;73174:22:0;;;;;;:18;:22;;;;46243:2;73174:22;;;:71;;73212:32;73200:45;;73174:71;;;73488:31;;;:17;:31;;;;;-1:-1:-1;60224:15:0;;60198:24;60194:46;59793:11;59768:23;59764:41;59761:52;59751:63;;73488:173;;73723:23;;;;73488:31;;73174:22;;74488:25;73174:22;;74341:335;75002:1;74988:12;74984:20;74942:346;75043:3;75034:7;75031:16;74942:346;;75261:7;75251:8;75248:1;75221:25;75218:1;75215;75210:59;75096:1;75083:15;74942:346;;;-1:-1:-1;75321:13:0;75317:45;;75343:19;;-1:-1:-1;;;75343:19:0;;;;;;;;;;;75317:45;75379:13;:19;-1:-1:-1;94871:165:0;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:631:1;78:5;108:18;149:2;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:173::-;718:20;;-1:-1:-1;;;;;767:31:1;;757:42;;747:70;;813:1;810;803:12;747:70;650:173;;;:::o;828:221::-;871:5;924:3;917:4;909:6;905:17;901:27;891:55;;942:1;939;932:12;891:55;964:79;1039:3;1030:6;1017:20;1010:4;1002:6;998:17;964:79;:::i;1054:186::-;1113:6;1166:2;1154:9;1145:7;1141:23;1137:32;1134:52;;;1182:1;1179;1172:12;1134:52;1205:29;1224:9;1205:29;:::i;1245:260::-;1313:6;1321;1374:2;1362:9;1353:7;1349:23;1345:32;1342:52;;;1390:1;1387;1380:12;1342:52;1413:29;1432:9;1413:29;:::i;:::-;1403:39;;1461:38;1495:2;1484:9;1480:18;1461:38;:::i;:::-;1451:48;;1245:260;;;;;:::o;1510:328::-;1587:6;1595;1603;1656:2;1644:9;1635:7;1631:23;1627:32;1624:52;;;1672:1;1669;1662:12;1624:52;1695:29;1714:9;1695:29;:::i;:::-;1685:39;;1743:38;1777:2;1766:9;1762:18;1743:38;:::i;:::-;1733:48;;1828:2;1817:9;1813:18;1800:32;1790:42;;1510:328;;;;;:::o;1843:666::-;1938:6;1946;1954;1962;2015:3;2003:9;1994:7;1990:23;1986:33;1983:53;;;2032:1;2029;2022:12;1983:53;2055:29;2074:9;2055:29;:::i;:::-;2045:39;;2103:38;2137:2;2126:9;2122:18;2103:38;:::i;:::-;2093:48;;2188:2;2177:9;2173:18;2160:32;2150:42;;2243:2;2232:9;2228:18;2215:32;2270:18;2262:6;2259:30;2256:50;;;2302:1;2299;2292:12;2256:50;2325:22;;2378:4;2370:13;;2366:27;-1:-1:-1;2356:55:1;;2407:1;2404;2397:12;2356:55;2430:73;2495:7;2490:2;2477:16;2472:2;2468;2464:11;2430:73;:::i;:::-;2420:83;;;1843:666;;;;;;;:::o;2514:315::-;2579:6;2587;2640:2;2628:9;2619:7;2615:23;2611:32;2608:52;;;2656:1;2653;2646:12;2608:52;2679:29;2698:9;2679:29;:::i;:::-;2669:39;;2758:2;2747:9;2743:18;2730:32;2771:28;2793:5;2771:28;:::i;:::-;2818:5;2808:15;;;2514:315;;;;;:::o;2834:254::-;2902:6;2910;2963:2;2951:9;2942:7;2938:23;2934:32;2931:52;;;2979:1;2976;2969:12;2931:52;3002:29;3021:9;3002:29;:::i;:::-;2992:39;3078:2;3063:18;;;;3050:32;;-1:-1:-1;;;2834:254:1:o;3093:245::-;3160:6;3213:2;3201:9;3192:7;3188:23;3184:32;3181:52;;;3229:1;3226;3219:12;3181:52;3261:9;3255:16;3280:28;3302:5;3280:28;:::i;3343:309::-;3408:6;3416;3469:2;3457:9;3448:7;3444:23;3440:32;3437:52;;;3485:1;3482;3475:12;3437:52;3524:9;3511:23;3543:28;3565:5;3543:28;:::i;3657:245::-;3715:6;3768:2;3756:9;3747:7;3743:23;3739:32;3736:52;;;3784:1;3781;3774:12;3736:52;3823:9;3810:23;3842:30;3866:5;3842:30;:::i;3907:249::-;3976:6;4029:2;4017:9;4008:7;4004:23;4000:32;3997:52;;;4045:1;4042;4035:12;3997:52;4077:9;4071:16;4096:30;4120:5;4096:30;:::i;4161:390::-;4239:6;4247;4300:2;4288:9;4279:7;4275:23;4271:32;4268:52;;;4316:1;4313;4306:12;4268:52;4356:9;4343:23;4389:18;4381:6;4378:30;4375:50;;;4421:1;4418;4411:12;4375:50;4444;4486:7;4477:6;4466:9;4462:22;4444:50;:::i;:::-;4434:60;4541:2;4526:18;;;;4513:32;;-1:-1:-1;;;;4161:390:1:o;4556:180::-;4615:6;4668:2;4656:9;4647:7;4643:23;4639:32;4636:52;;;4684:1;4681;4674:12;4636:52;-1:-1:-1;4707:23:1;;4556:180;-1:-1:-1;4556:180:1:o;4741:184::-;4811:6;4864:2;4852:9;4843:7;4839:23;4835:32;4832:52;;;4880:1;4877;4870:12;4832:52;-1:-1:-1;4903:16:1;;4741:184;-1:-1:-1;4741:184:1:o;4930:322::-;5007:6;5015;5023;5076:2;5064:9;5055:7;5051:23;5047:32;5044:52;;;5092:1;5089;5082:12;5044:52;5128:9;5115:23;5105:33;;5157:38;5191:2;5180:9;5176:18;5157:38;:::i;5257:248::-;5325:6;5333;5386:2;5374:9;5365:7;5361:23;5357:32;5354:52;;;5402:1;5399;5392:12;5354:52;-1:-1:-1;;5425:23:1;;;5495:2;5480:18;;;5467:32;;-1:-1:-1;5257:248:1:o;5510:322::-;5587:6;5595;5603;5656:2;5644:9;5635:7;5631:23;5627:32;5624:52;;;5672:1;5669;5662:12;5624:52;5708:9;5695:23;5685:33;;5765:2;5754:9;5750:18;5737:32;5727:42;;5788:38;5822:2;5811:9;5807:18;5788:38;:::i;:::-;5778:48;;5510:322;;;;;:::o;5837:316::-;5914:6;5922;5930;5983:2;5971:9;5962:7;5958:23;5954:32;5951:52;;;5999:1;5996;5989:12;5951:52;-1:-1:-1;;6022:23:1;;;6092:2;6077:18;;6064:32;;-1:-1:-1;6143:2:1;6128:18;;;6115:32;;5837:316;-1:-1:-1;5837:316:1:o;6158:596::-;6263:6;6271;6279;6287;6295;6348:3;6336:9;6327:7;6323:23;6319:33;6316:53;;;6365:1;6362;6355:12;6316:53;6401:9;6388:23;6378:33;;6458:2;6447:9;6443:18;6430:32;6420:42;;6509:2;6498:9;6494:18;6481:32;6471:42;;6560:2;6549:9;6545:18;6532:32;6522:42;;6615:3;6604:9;6600:19;6587:33;6643:18;6635:6;6632:30;6629:50;;;6675:1;6672;6665:12;6629:50;6698;6740:7;6731:6;6720:9;6716:22;6698:50;:::i;:::-;6688:60;;;6158:596;;;;;;;;:::o;6759:292::-;6817:6;6870:2;6858:9;6849:7;6845:23;6841:32;6838:52;;;6886:1;6883;6876:12;6838:52;6925:9;6912:23;-1:-1:-1;;;;;6968:5:1;6964:38;6957:5;6954:49;6944:77;;7017:1;7014;7007:12;7056:257;7097:3;7135:5;7129:12;7162:6;7157:3;7150:19;7178:63;7234:6;7227:4;7222:3;7218:14;7211:4;7204:5;7200:16;7178:63;:::i;:::-;7295:2;7274:15;-1:-1:-1;;7270:29:1;7261:39;;;;7302:4;7257:50;;7056:257;-1:-1:-1;;7056:257:1:o;7318:470::-;7497:3;7535:6;7529:13;7551:53;7597:6;7592:3;7585:4;7577:6;7573:17;7551:53;:::i;:::-;7667:13;;7626:16;;;;7689:57;7667:13;7626:16;7723:4;7711:17;;7689:57;:::i;:::-;7762:20;;7318:470;-1:-1:-1;;;;7318:470:1:o;8310:488::-;-1:-1:-1;;;;;8579:15:1;;;8561:34;;8631:15;;8626:2;8611:18;;8604:43;8678:2;8663:18;;8656:34;;;8726:3;8721:2;8706:18;;8699:31;;;8504:4;;8747:45;;8772:19;;8764:6;8747:45;:::i;:::-;8739:53;8310:488;-1:-1:-1;;;;;;8310:488:1:o;9274:660::-;9599:6;9592:14;9585:22;9574:9;9567:41;9644:6;9639:2;9628:9;9624:18;9617:34;9687:6;9682:2;9671:9;9667:18;9660:34;9730:6;9725:2;9714:9;9710:18;9703:34;9774:6;9768:3;9757:9;9753:19;9746:35;9818:6;9812:3;9801:9;9797:19;9790:35;9862:3;9856;9845:9;9841:19;9834:32;9548:4;9883:45;9923:3;9912:9;9908:19;9900:6;9883:45;:::i;:::-;9875:53;9274:660;-1:-1:-1;;;;;;;;;9274:660:1:o;10178:219::-;10327:2;10316:9;10309:21;10290:4;10347:44;10387:2;10376:9;10372:18;10364:6;10347:44;:::i;11166:346::-;11368:2;11350:21;;;11407:2;11387:18;;;11380:30;-1:-1:-1;;;11441:2:1;11426:18;;11419:52;11503:2;11488:18;;11166:346::o;11517:356::-;11719:2;11701:21;;;11738:18;;;11731:30;11797:34;11792:2;11777:18;;11770:62;11864:2;11849:18;;11517:356::o;16745:128::-;16785:3;16816:1;16812:6;16809:1;16806:13;16803:39;;;16822:18;;:::i;:::-;-1:-1:-1;16858:9:1;;16745:128::o;16878:120::-;16918:1;16944;16934:35;;16949:18;;:::i;:::-;-1:-1:-1;16983:9:1;;16878:120::o;17003:168::-;17043:7;17109:1;17105;17101:6;17097:14;17094:1;17091:21;17086:1;17079:9;17072:17;17068:45;17065:71;;;17116:18;;:::i;:::-;-1:-1:-1;17156:9:1;;17003:168::o;17176:125::-;17216:4;17244:1;17241;17238:8;17235:34;;;17249:18;;:::i;:::-;-1:-1:-1;17286:9:1;;17176:125::o;17306:258::-;17378:1;17388:113;17402:6;17399:1;17396:13;17388:113;;;17478:11;;;17472:18;17459:11;;;17452:39;17424:2;17417:10;17388:113;;;17519:6;17516:1;17513:13;17510:48;;;-1:-1:-1;;17554:1:1;17536:16;;17529:27;17306:258::o;17569:380::-;17648:1;17644:12;;;;17691;;;17712:61;;17766:4;17758:6;17754:17;17744:27;;17712:61;17819:2;17811:6;17808:14;17788:18;17785:38;17782:161;;;17865:10;17860:3;17856:20;17853:1;17846:31;17900:4;17897:1;17890:15;17928:4;17925:1;17918:15;17782:161;;17569:380;;;:::o;17954:135::-;17993:3;-1:-1:-1;;18014:17:1;;18011:43;;;18034:18;;:::i;:::-;-1:-1:-1;18081:1:1;18070:13;;17954:135::o;18094:112::-;18126:1;18152;18142:35;;18157:18;;:::i;:::-;-1:-1:-1;18191:9:1;;18094:112::o;18211:127::-;18272:10;18267:3;18263:20;18260:1;18253:31;18303:4;18300:1;18293:15;18327:4;18324:1;18317:15;18343:127;18404:10;18399:3;18395:20;18392:1;18385:31;18435:4;18432:1;18425:15;18459:4;18456:1;18449:15;18475:127;18536:10;18531:3;18527:20;18524:1;18517:31;18567:4;18564:1;18557:15;18591:4;18588:1;18581:15;18607:127;18668:10;18663:3;18659:20;18656:1;18649:31;18699:4;18696:1;18689:15;18723:4;18720:1;18713:15;18739:118;18825:5;18818:13;18811:21;18804:5;18801:32;18791:60;;18847:1;18844;18837:12;18862:131;-1:-1:-1;;;;;;18936:32:1;;18926:43;;18916:71;;18983:1;18980;18973:12

Swarm Source

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