ETH Price: $3,121.42 (+0.28%)

Frunkers (Frunkers)
 

Overview

TokenID

2677

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
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:
Frunkers

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-07-23
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/utils/Strings.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

// File: @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 (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: erc721a/contracts/IERC721A.sol


// ERC721A Contracts v4.2.0
// 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();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/ERC721A.sol


// ERC721A Contracts v4.2.0
// 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 {
    // Reference type for token approval.
    struct TokenApprovalRef {
        address value;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId].value;
    }

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

        _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]`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

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

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

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

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

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

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

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

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

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

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

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

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: contracts/frunk.sol



pragma solidity >=0.8.9 <0.9.0;








contract Frunkers is ERC721A, Ownable, ReentrancyGuard {
    string public baseURI;
    string public endPoint = ".json";
    string public hiddenMetadataUri = "ipfs://QmaqBbNHkyuEXjG2PvAxsMuf5sJditFesWgxGBibnWmVbP/hidden.json";
    bool public revealed = true;

    uint256 public price = 0.0000 ether;
    uint256 public maxPerTx = 5;
    uint256 public maxPerWallet = 50;
    uint256 public maxSupply = 10022;

    constructor() ERC721A("Frunkers", "Frunkers")  {}

    
    function toggleRevealed() external onlyOwner {
        revealed = !revealed;
    }
    
    function setBaseURI(string calldata baseURI_) external onlyOwner {
        baseURI = baseURI_;
    }

    function mint(uint256 amount) external payable {

        require(msg.sender == tx.origin, "You can't mint from a contract.");
        require(msg.value == amount * price, "Please send the exact amount in order to mint.");
        require(totalSupply() + amount <= maxSupply, "Sold out.");
        require(numberMinted(msg.sender) + amount <= maxPerWallet, "You have exceeded the mint limit per wallet.");
        require(amount <= maxPerTx, "You have exceeded the mint limit per transaction.");

        _safeMint(msg.sender, amount);
    }

    function ownerMint(uint256 amount) external onlyOwner {
        require(totalSupply() + amount <= maxSupply, "Can't mint");

        _safeMint(msg.sender, amount);
    }
    
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
        if (revealed == false) {
        return hiddenMetadataUri;
        }

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

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

    function numberMinted(address owner) public view returns (uint256) {
        return _numberMinted(owner);
    }



    function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
    }

    function withdraw() external onlyOwner nonReentrant {
        (bool success, ) = msg.sender.call{value: address(this).balance}("");
        require(success, "Transfer failed.");
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endPoint","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hiddenMetadataUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600b90816200004a9190620004db565b50604051806080016040528060418152602001620037d860419139600c9081620000759190620004db565b506001600d60006101000a81548160ff0219169083151502179055506000600e556005600f556032601055612726601155348015620000b357600080fd5b506040518060400160405280600881526020017f4672756e6b6572730000000000000000000000000000000000000000000000008152506040518060400160405280600881526020017f4672756e6b6572730000000000000000000000000000000000000000000000008152508160029081620001319190620004db565b508060039081620001439190620004db565b50620001546200018a60201b60201c565b60008190555050506200017c620001706200019360201b60201c565b6200019b60201b60201c565b6001600981905550620005c2565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620002e357607f821691505b602082108103620002f957620002f86200029b565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003637fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000324565b6200036f868362000324565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003bc620003b6620003b08462000387565b62000391565b62000387565b9050919050565b6000819050919050565b620003d8836200039b565b620003f0620003e782620003c3565b84845462000331565b825550505050565b600090565b62000407620003f8565b62000414818484620003cd565b505050565b5b818110156200043c5762000430600082620003fd565b6001810190506200041a565b5050565b601f8211156200048b576200045581620002ff565b620004608462000314565b8101602085101562000470578190505b620004886200047f8562000314565b83018262000419565b50505b505050565b600082821c905092915050565b6000620004b06000198460080262000490565b1980831691505092915050565b6000620004cb83836200049d565b9150826002028217905092915050565b620004e68262000261565b67ffffffffffffffff8111156200050257620005016200026c565b5b6200050e8254620002ca565b6200051b82828562000440565b600060209050601f8311600181146200055357600084156200053e578287015190505b6200054a8582620004bd565b865550620005ba565b601f1984166200056386620002ff565b60005b828110156200058d5784890151825560018201915060208501945060208101905062000566565b86831015620005ad5784890151620005a9601f8916826200049d565b8355505b6001600288020188555050505b505050505050565b61320680620005d26000396000f3fe6080604052600436106101d85760003560e01c8063715018a611610102578063b88d4fde11610095578063e985e9c511610064578063e985e9c51461067b578063f19e75d4146106b8578063f2fde38b146106e1578063f968adbe1461070a576101d8565b8063b88d4fde146105ad578063c87b56dd146105d6578063d5abeb0114610613578063dc33e6811461063e576101d8565b8063a035b1fe116100d1578063a035b1fe14610512578063a0712d681461053d578063a22cb46514610559578063a45ba8e714610582576101d8565b8063715018a61461047a5780638da5cb5b1461049157806395d89b41146104bc57806399e51e1c146104e7576101d8565b806342842e0e1161017a5780635bc020bc116101495780635bc020bc146103be5780636352211e146103d55780636c0360eb1461041257806370a082311461043d576101d8565b806342842e0e14610316578063453c23101461033f578063518302271461036a57806355f804b314610395576101d8565b8063095ea7b3116101b6578063095ea7b31461028257806318160ddd146102ab57806323b872dd146102d65780633ccfd60b146102ff576101d8565b806301ffc9a7146101dd57806306fdde031461021a578063081812fc14610245575b600080fd5b3480156101e957600080fd5b5061020460048036038101906101ff919061211d565b610735565b6040516102119190612165565b60405180910390f35b34801561022657600080fd5b5061022f6107c7565b60405161023c9190612219565b60405180910390f35b34801561025157600080fd5b5061026c60048036038101906102679190612271565b610859565b60405161027991906122df565b60405180910390f35b34801561028e57600080fd5b506102a960048036038101906102a49190612326565b6108d8565b005b3480156102b757600080fd5b506102c0610a1c565b6040516102cd9190612375565b60405180910390f35b3480156102e257600080fd5b506102fd60048036038101906102f89190612390565b610a33565b005b34801561030b57600080fd5b50610314610d55565b005b34801561032257600080fd5b5061033d60048036038101906103389190612390565b610e61565b005b34801561034b57600080fd5b50610354610e81565b6040516103619190612375565b60405180910390f35b34801561037657600080fd5b5061037f610e87565b60405161038c9190612165565b60405180910390f35b3480156103a157600080fd5b506103bc60048036038101906103b79190612448565b610e9a565b005b3480156103ca57600080fd5b506103d3610eb8565b005b3480156103e157600080fd5b506103fc60048036038101906103f79190612271565b610eec565b60405161040991906122df565b60405180910390f35b34801561041e57600080fd5b50610427610efe565b6040516104349190612219565b60405180910390f35b34801561044957600080fd5b50610464600480360381019061045f9190612495565b610f8c565b6040516104719190612375565b60405180910390f35b34801561048657600080fd5b5061048f611044565b005b34801561049d57600080fd5b506104a6611058565b6040516104b391906122df565b60405180910390f35b3480156104c857600080fd5b506104d1611082565b6040516104de9190612219565b60405180910390f35b3480156104f357600080fd5b506104fc611114565b6040516105099190612219565b60405180910390f35b34801561051e57600080fd5b506105276111a2565b6040516105349190612375565b60405180910390f35b61055760048036038101906105529190612271565b6111a8565b005b34801561056557600080fd5b50610580600480360381019061057b91906124ee565b611366565b005b34801561058e57600080fd5b506105976114dd565b6040516105a49190612219565b60405180910390f35b3480156105b957600080fd5b506105d460048036038101906105cf919061265e565b61156b565b005b3480156105e257600080fd5b506105fd60048036038101906105f89190612271565b6115de565b60405161060a9190612219565b60405180910390f35b34801561061f57600080fd5b5061062861172e565b6040516106359190612375565b60405180910390f35b34801561064a57600080fd5b5061066560048036038101906106609190612495565b611734565b6040516106729190612375565b60405180910390f35b34801561068757600080fd5b506106a2600480360381019061069d91906126e1565b611746565b6040516106af9190612165565b60405180910390f35b3480156106c457600080fd5b506106df60048036038101906106da9190612271565b6117da565b005b3480156106ed57600080fd5b5061070860048036038101906107039190612495565b611846565b005b34801561071657600080fd5b5061071f6118c9565b60405161072c9190612375565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061079057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107c05750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546107d690612750565b80601f016020809104026020016040519081016040528092919081815260200182805461080290612750565b801561084f5780601f106108245761010080835404028352916020019161084f565b820191906000526020600020905b81548152906001019060200180831161083257829003601f168201915b5050505050905090565b6000610864826118cf565b61089a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006108e382610eec565b90508073ffffffffffffffffffffffffffffffffffffffff1661090461192e565b73ffffffffffffffffffffffffffffffffffffffff1614610967576109308161092b61192e565b611746565b610966576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610a26611936565b6001546000540303905090565b6000610a3e8261193f565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610aa5576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610ab184611a0b565b91509150610ac78187610ac261192e565b611a32565b610b1357610adc86610ad761192e565b611746565b610b12576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b79576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b868686866001611a76565b8015610b9157600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610c5f85610c3b888887611a7c565b7c020000000000000000000000000000000000000000000000000000000017611aa4565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610ce55760006001850190506000600460008381526020019081526020016000205403610ce3576000548114610ce2578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610d4d8686866001611acf565b505050505050565b610d5d611ad5565b600260095403610da2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d99906127cd565b60405180910390fd5b600260098190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051610dd09061281e565b60006040518083038185875af1925050503d8060008114610e0d576040519150601f19603f3d011682016040523d82523d6000602084013e610e12565b606091505b5050905080610e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4d9061287f565b60405180910390fd5b506001600981905550565b610e7c8383836040518060200160405280600081525061156b565b505050565b60105481565b600d60009054906101000a900460ff1681565b610ea2611ad5565b8181600a9182610eb3929190612a56565b505050565b610ec0611ad5565b600d60009054906101000a900460ff1615600d60006101000a81548160ff021916908315150217905550565b6000610ef78261193f565b9050919050565b600a8054610f0b90612750565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3790612750565b8015610f845780601f10610f5957610100808354040283529160200191610f84565b820191906000526020600020905b815481529060010190602001808311610f6757829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610ff3576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61104c611ad5565b6110566000611b53565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606003805461109190612750565b80601f01602080910402602001604051908101604052809291908181526020018280546110bd90612750565b801561110a5780601f106110df5761010080835404028352916020019161110a565b820191906000526020600020905b8154815290600101906020018083116110ed57829003601f168201915b5050505050905090565b600b805461112190612750565b80601f016020809104026020016040519081016040528092919081815260200182805461114d90612750565b801561119a5780601f1061116f5761010080835404028352916020019161119a565b820191906000526020600020905b81548152906001019060200180831161117d57829003601f168201915b505050505081565b600e5481565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611216576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120d90612b72565b60405180910390fd5b600e54816112249190612bc1565b3414611265576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125c90612c8d565b60405180910390fd5b60115481611271610a1c565b61127b9190612cad565b11156112bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b390612d4f565b60405180910390fd5b601054816112c933611734565b6112d39190612cad565b1115611314576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130b90612de1565b60405180910390fd5b600f54811115611359576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135090612e73565b60405180910390fd5b6113633382611c19565b50565b61136e61192e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036113d2576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006113df61192e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661148c61192e565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516114d19190612165565b60405180910390a35050565b600c80546114ea90612750565b80601f016020809104026020016040519081016040528092919081815260200182805461151690612750565b80156115635780601f1061153857610100808354040283529160200191611563565b820191906000526020600020905b81548152906001019060200180831161154657829003601f168201915b505050505081565b611576848484610a33565b60008373ffffffffffffffffffffffffffffffffffffffff163b146115d8576115a184848484611c37565b6115d7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606115e9826118cf565b61161f576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60001515600d60009054906101000a900460ff161515036116cc57600c805461164790612750565b80601f016020809104026020016040519081016040528092919081815260200182805461167390612750565b80156116c05780601f10611695576101008083540402835291602001916116c0565b820191906000526020600020905b8154815290600101906020018083116116a357829003601f168201915b50505050509050611729565b6000600a80546116db90612750565b9050036116f75760405180602001604052806000815250611726565b600a61170283611d87565b600b60405160200161171693929190612f52565b6040516020818303038152906040525b90505b919050565b60115481565b600061173f82611de1565b9050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6117e2611ad5565b601154816117ee610a1c565b6117f89190612cad565b1115611839576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183090612fcf565b60405180910390fd5b6118433382611c19565b50565b61184e611ad5565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b490613061565b60405180910390fd5b6118c681611b53565b50565b600f5481565b6000816118da611936565b111580156118e9575060005482105b8015611927575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b6000808290508061194e611936565b116119d4576000548110156119d35760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036119d1575b600081036119c757600460008360019003935083815260200190815260200160002054905061199d565b8092505050611a06565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611a93868684611e38565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b611add611e41565b73ffffffffffffffffffffffffffffffffffffffff16611afb611058565b73ffffffffffffffffffffffffffffffffffffffff1614611b51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b48906130cd565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611c33828260405180602001604052806000815250611e49565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611c5d61192e565b8786866040518563ffffffff1660e01b8152600401611c7f9493929190613142565b6020604051808303816000875af1925050508015611cbb57506040513d601f19601f82011682018060405250810190611cb891906131a3565b60015b611d34573d8060008114611ceb576040519150601f19603f3d011682016040523d82523d6000602084013e611cf0565b606091505b506000815103611d2c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b8015611dcd57600183039250600a81066030018353600a81049050611dad565b508181036020830392508083525050919050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b60009392505050565b600033905090565b611e538383611ee6565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611ee157600080549050600083820390505b611e936000868380600101945086611c37565b611ec9576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611e80578160005414611ede57600080fd5b50505b505050565b60008054905060008203611f26576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f336000848385611a76565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611faa83611f9b6000866000611a7c565b611fa4856120a1565b17611aa4565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461204b57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612010565b5060008203612086576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061209c6000848385611acf565b505050565b60006001821460e11b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6120fa816120c5565b811461210557600080fd5b50565b600081359050612117816120f1565b92915050565b600060208284031215612133576121326120bb565b5b600061214184828501612108565b91505092915050565b60008115159050919050565b61215f8161214a565b82525050565b600060208201905061217a6000830184612156565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156121ba57808201518184015260208101905061219f565b838111156121c9576000848401525b50505050565b6000601f19601f8301169050919050565b60006121eb82612180565b6121f5818561218b565b935061220581856020860161219c565b61220e816121cf565b840191505092915050565b6000602082019050818103600083015261223381846121e0565b905092915050565b6000819050919050565b61224e8161223b565b811461225957600080fd5b50565b60008135905061226b81612245565b92915050565b600060208284031215612287576122866120bb565b5b60006122958482850161225c565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006122c98261229e565b9050919050565b6122d9816122be565b82525050565b60006020820190506122f460008301846122d0565b92915050565b612303816122be565b811461230e57600080fd5b50565b600081359050612320816122fa565b92915050565b6000806040838503121561233d5761233c6120bb565b5b600061234b85828601612311565b925050602061235c8582860161225c565b9150509250929050565b61236f8161223b565b82525050565b600060208201905061238a6000830184612366565b92915050565b6000806000606084860312156123a9576123a86120bb565b5b60006123b786828701612311565b93505060206123c886828701612311565b92505060406123d98682870161225c565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f840112612408576124076123e3565b5b8235905067ffffffffffffffff811115612425576124246123e8565b5b602083019150836001820283011115612441576124406123ed565b5b9250929050565b6000806020838503121561245f5761245e6120bb565b5b600083013567ffffffffffffffff81111561247d5761247c6120c0565b5b612489858286016123f2565b92509250509250929050565b6000602082840312156124ab576124aa6120bb565b5b60006124b984828501612311565b91505092915050565b6124cb8161214a565b81146124d657600080fd5b50565b6000813590506124e8816124c2565b92915050565b60008060408385031215612505576125046120bb565b5b600061251385828601612311565b9250506020612524858286016124d9565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61256b826121cf565b810181811067ffffffffffffffff8211171561258a57612589612533565b5b80604052505050565b600061259d6120b1565b90506125a98282612562565b919050565b600067ffffffffffffffff8211156125c9576125c8612533565b5b6125d2826121cf565b9050602081019050919050565b82818337600083830152505050565b60006126016125fc846125ae565b612593565b90508281526020810184848401111561261d5761261c61252e565b5b6126288482856125df565b509392505050565b600082601f830112612645576126446123e3565b5b81356126558482602086016125ee565b91505092915050565b60008060008060808587031215612678576126776120bb565b5b600061268687828801612311565b945050602061269787828801612311565b93505060406126a88782880161225c565b925050606085013567ffffffffffffffff8111156126c9576126c86120c0565b5b6126d587828801612630565b91505092959194509250565b600080604083850312156126f8576126f76120bb565b5b600061270685828601612311565b925050602061271785828601612311565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061276857607f821691505b60208210810361277b5761277a612721565b5b50919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006127b7601f8361218b565b91506127c282612781565b602082019050919050565b600060208201905081810360008301526127e6816127aa565b9050919050565b600081905092915050565b50565b60006128086000836127ed565b9150612813826127f8565b600082019050919050565b6000612829826127fb565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b600061286960108361218b565b915061287482612833565b602082019050919050565b600060208201905081810360008301526128988161285c565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261290c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826128cf565b61291686836128cf565b95508019841693508086168417925050509392505050565b6000819050919050565b600061295361294e6129498461223b565b61292e565b61223b565b9050919050565b6000819050919050565b61296d83612938565b6129816129798261295a565b8484546128dc565b825550505050565b600090565b612996612989565b6129a1818484612964565b505050565b5b818110156129c5576129ba60008261298e565b6001810190506129a7565b5050565b601f821115612a0a576129db816128aa565b6129e4846128bf565b810160208510156129f3578190505b612a076129ff856128bf565b8301826129a6565b50505b505050565b600082821c905092915050565b6000612a2d60001984600802612a0f565b1980831691505092915050565b6000612a468383612a1c565b9150826002028217905092915050565b612a60838361289f565b67ffffffffffffffff811115612a7957612a78612533565b5b612a838254612750565b612a8e8282856129c9565b6000601f831160018114612abd5760008415612aab578287013590505b612ab58582612a3a565b865550612b1d565b601f198416612acb866128aa565b60005b82811015612af357848901358255600182019150602085019450602081019050612ace565b86831015612b105784890135612b0c601f891682612a1c565b8355505b6001600288020188555050505b50505050505050565b7f596f752063616e2774206d696e742066726f6d206120636f6e74726163742e00600082015250565b6000612b5c601f8361218b565b9150612b6782612b26565b602082019050919050565b60006020820190508181036000830152612b8b81612b4f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bcc8261223b565b9150612bd78361223b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612c1057612c0f612b92565b5b828202905092915050565b7f506c656173652073656e642074686520657861637420616d6f756e7420696e2060008201527f6f7264657220746f206d696e742e000000000000000000000000000000000000602082015250565b6000612c77602e8361218b565b9150612c8282612c1b565b604082019050919050565b60006020820190508181036000830152612ca681612c6a565b9050919050565b6000612cb88261223b565b9150612cc38361223b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612cf857612cf7612b92565b5b828201905092915050565b7f536f6c64206f75742e0000000000000000000000000000000000000000000000600082015250565b6000612d3960098361218b565b9150612d4482612d03565b602082019050919050565b60006020820190508181036000830152612d6881612d2c565b9050919050565b7f596f75206861766520657863656564656420746865206d696e74206c696d697460008201527f207065722077616c6c65742e0000000000000000000000000000000000000000602082015250565b6000612dcb602c8361218b565b9150612dd682612d6f565b604082019050919050565b60006020820190508181036000830152612dfa81612dbe565b9050919050565b7f596f75206861766520657863656564656420746865206d696e74206c696d697460008201527f20706572207472616e73616374696f6e2e000000000000000000000000000000602082015250565b6000612e5d60318361218b565b9150612e6882612e01565b604082019050919050565b60006020820190508181036000830152612e8c81612e50565b9050919050565b600081905092915050565b60008154612eab81612750565b612eb58186612e93565b94506001821660008114612ed05760018114612ee557612f18565b60ff1983168652811515820286019350612f18565b612eee856128aa565b60005b83811015612f1057815481890152600182019150602081019050612ef1565b838801955050505b50505092915050565b6000612f2c82612180565b612f368185612e93565b9350612f4681856020860161219c565b80840191505092915050565b6000612f5e8286612e9e565b9150612f6a8285612f21565b9150612f768284612e9e565b9150819050949350505050565b7f43616e2774206d696e7400000000000000000000000000000000000000000000600082015250565b6000612fb9600a8361218b565b9150612fc482612f83565b602082019050919050565b60006020820190508181036000830152612fe881612fac565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061304b60268361218b565b915061305682612fef565b604082019050919050565b6000602082019050818103600083015261307a8161303e565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006130b760208361218b565b91506130c282613081565b602082019050919050565b600060208201905081810360008301526130e6816130aa565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613114826130ed565b61311e81856130f8565b935061312e81856020860161219c565b613137816121cf565b840191505092915050565b600060808201905061315760008301876122d0565b61316460208301866122d0565b6131716040830185612366565b81810360608301526131838184613109565b905095945050505050565b60008151905061319d816120f1565b92915050565b6000602082840312156131b9576131b86120bb565b5b60006131c78482850161318e565b9150509291505056fea264697066735822122065ce64c3b3747b9109eee4f6986ad817c57154b22b956028a5a44d6b27158adb64736f6c634300080f0033697066733a2f2f516d617142624e486b797545586a473250764178734d756635734a646974466573576778474269626e576d5662502f68696464656e2e6a736f6e

Deployed Bytecode

0x6080604052600436106101d85760003560e01c8063715018a611610102578063b88d4fde11610095578063e985e9c511610064578063e985e9c51461067b578063f19e75d4146106b8578063f2fde38b146106e1578063f968adbe1461070a576101d8565b8063b88d4fde146105ad578063c87b56dd146105d6578063d5abeb0114610613578063dc33e6811461063e576101d8565b8063a035b1fe116100d1578063a035b1fe14610512578063a0712d681461053d578063a22cb46514610559578063a45ba8e714610582576101d8565b8063715018a61461047a5780638da5cb5b1461049157806395d89b41146104bc57806399e51e1c146104e7576101d8565b806342842e0e1161017a5780635bc020bc116101495780635bc020bc146103be5780636352211e146103d55780636c0360eb1461041257806370a082311461043d576101d8565b806342842e0e14610316578063453c23101461033f578063518302271461036a57806355f804b314610395576101d8565b8063095ea7b3116101b6578063095ea7b31461028257806318160ddd146102ab57806323b872dd146102d65780633ccfd60b146102ff576101d8565b806301ffc9a7146101dd57806306fdde031461021a578063081812fc14610245575b600080fd5b3480156101e957600080fd5b5061020460048036038101906101ff919061211d565b610735565b6040516102119190612165565b60405180910390f35b34801561022657600080fd5b5061022f6107c7565b60405161023c9190612219565b60405180910390f35b34801561025157600080fd5b5061026c60048036038101906102679190612271565b610859565b60405161027991906122df565b60405180910390f35b34801561028e57600080fd5b506102a960048036038101906102a49190612326565b6108d8565b005b3480156102b757600080fd5b506102c0610a1c565b6040516102cd9190612375565b60405180910390f35b3480156102e257600080fd5b506102fd60048036038101906102f89190612390565b610a33565b005b34801561030b57600080fd5b50610314610d55565b005b34801561032257600080fd5b5061033d60048036038101906103389190612390565b610e61565b005b34801561034b57600080fd5b50610354610e81565b6040516103619190612375565b60405180910390f35b34801561037657600080fd5b5061037f610e87565b60405161038c9190612165565b60405180910390f35b3480156103a157600080fd5b506103bc60048036038101906103b79190612448565b610e9a565b005b3480156103ca57600080fd5b506103d3610eb8565b005b3480156103e157600080fd5b506103fc60048036038101906103f79190612271565b610eec565b60405161040991906122df565b60405180910390f35b34801561041e57600080fd5b50610427610efe565b6040516104349190612219565b60405180910390f35b34801561044957600080fd5b50610464600480360381019061045f9190612495565b610f8c565b6040516104719190612375565b60405180910390f35b34801561048657600080fd5b5061048f611044565b005b34801561049d57600080fd5b506104a6611058565b6040516104b391906122df565b60405180910390f35b3480156104c857600080fd5b506104d1611082565b6040516104de9190612219565b60405180910390f35b3480156104f357600080fd5b506104fc611114565b6040516105099190612219565b60405180910390f35b34801561051e57600080fd5b506105276111a2565b6040516105349190612375565b60405180910390f35b61055760048036038101906105529190612271565b6111a8565b005b34801561056557600080fd5b50610580600480360381019061057b91906124ee565b611366565b005b34801561058e57600080fd5b506105976114dd565b6040516105a49190612219565b60405180910390f35b3480156105b957600080fd5b506105d460048036038101906105cf919061265e565b61156b565b005b3480156105e257600080fd5b506105fd60048036038101906105f89190612271565b6115de565b60405161060a9190612219565b60405180910390f35b34801561061f57600080fd5b5061062861172e565b6040516106359190612375565b60405180910390f35b34801561064a57600080fd5b5061066560048036038101906106609190612495565b611734565b6040516106729190612375565b60405180910390f35b34801561068757600080fd5b506106a2600480360381019061069d91906126e1565b611746565b6040516106af9190612165565b60405180910390f35b3480156106c457600080fd5b506106df60048036038101906106da9190612271565b6117da565b005b3480156106ed57600080fd5b5061070860048036038101906107039190612495565b611846565b005b34801561071657600080fd5b5061071f6118c9565b60405161072c9190612375565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061079057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107c05750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546107d690612750565b80601f016020809104026020016040519081016040528092919081815260200182805461080290612750565b801561084f5780601f106108245761010080835404028352916020019161084f565b820191906000526020600020905b81548152906001019060200180831161083257829003601f168201915b5050505050905090565b6000610864826118cf565b61089a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006108e382610eec565b90508073ffffffffffffffffffffffffffffffffffffffff1661090461192e565b73ffffffffffffffffffffffffffffffffffffffff1614610967576109308161092b61192e565b611746565b610966576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610a26611936565b6001546000540303905090565b6000610a3e8261193f565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610aa5576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610ab184611a0b565b91509150610ac78187610ac261192e565b611a32565b610b1357610adc86610ad761192e565b611746565b610b12576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b79576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b868686866001611a76565b8015610b9157600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610c5f85610c3b888887611a7c565b7c020000000000000000000000000000000000000000000000000000000017611aa4565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610ce55760006001850190506000600460008381526020019081526020016000205403610ce3576000548114610ce2578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610d4d8686866001611acf565b505050505050565b610d5d611ad5565b600260095403610da2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d99906127cd565b60405180910390fd5b600260098190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051610dd09061281e565b60006040518083038185875af1925050503d8060008114610e0d576040519150601f19603f3d011682016040523d82523d6000602084013e610e12565b606091505b5050905080610e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4d9061287f565b60405180910390fd5b506001600981905550565b610e7c8383836040518060200160405280600081525061156b565b505050565b60105481565b600d60009054906101000a900460ff1681565b610ea2611ad5565b8181600a9182610eb3929190612a56565b505050565b610ec0611ad5565b600d60009054906101000a900460ff1615600d60006101000a81548160ff021916908315150217905550565b6000610ef78261193f565b9050919050565b600a8054610f0b90612750565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3790612750565b8015610f845780601f10610f5957610100808354040283529160200191610f84565b820191906000526020600020905b815481529060010190602001808311610f6757829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610ff3576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61104c611ad5565b6110566000611b53565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606003805461109190612750565b80601f01602080910402602001604051908101604052809291908181526020018280546110bd90612750565b801561110a5780601f106110df5761010080835404028352916020019161110a565b820191906000526020600020905b8154815290600101906020018083116110ed57829003601f168201915b5050505050905090565b600b805461112190612750565b80601f016020809104026020016040519081016040528092919081815260200182805461114d90612750565b801561119a5780601f1061116f5761010080835404028352916020019161119a565b820191906000526020600020905b81548152906001019060200180831161117d57829003601f168201915b505050505081565b600e5481565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611216576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120d90612b72565b60405180910390fd5b600e54816112249190612bc1565b3414611265576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125c90612c8d565b60405180910390fd5b60115481611271610a1c565b61127b9190612cad565b11156112bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b390612d4f565b60405180910390fd5b601054816112c933611734565b6112d39190612cad565b1115611314576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130b90612de1565b60405180910390fd5b600f54811115611359576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135090612e73565b60405180910390fd5b6113633382611c19565b50565b61136e61192e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036113d2576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006113df61192e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661148c61192e565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516114d19190612165565b60405180910390a35050565b600c80546114ea90612750565b80601f016020809104026020016040519081016040528092919081815260200182805461151690612750565b80156115635780601f1061153857610100808354040283529160200191611563565b820191906000526020600020905b81548152906001019060200180831161154657829003601f168201915b505050505081565b611576848484610a33565b60008373ffffffffffffffffffffffffffffffffffffffff163b146115d8576115a184848484611c37565b6115d7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606115e9826118cf565b61161f576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60001515600d60009054906101000a900460ff161515036116cc57600c805461164790612750565b80601f016020809104026020016040519081016040528092919081815260200182805461167390612750565b80156116c05780601f10611695576101008083540402835291602001916116c0565b820191906000526020600020905b8154815290600101906020018083116116a357829003601f168201915b50505050509050611729565b6000600a80546116db90612750565b9050036116f75760405180602001604052806000815250611726565b600a61170283611d87565b600b60405160200161171693929190612f52565b6040516020818303038152906040525b90505b919050565b60115481565b600061173f82611de1565b9050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6117e2611ad5565b601154816117ee610a1c565b6117f89190612cad565b1115611839576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183090612fcf565b60405180910390fd5b6118433382611c19565b50565b61184e611ad5565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b490613061565b60405180910390fd5b6118c681611b53565b50565b600f5481565b6000816118da611936565b111580156118e9575060005482105b8015611927575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b6000808290508061194e611936565b116119d4576000548110156119d35760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036119d1575b600081036119c757600460008360019003935083815260200190815260200160002054905061199d565b8092505050611a06565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611a93868684611e38565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b611add611e41565b73ffffffffffffffffffffffffffffffffffffffff16611afb611058565b73ffffffffffffffffffffffffffffffffffffffff1614611b51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b48906130cd565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611c33828260405180602001604052806000815250611e49565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611c5d61192e565b8786866040518563ffffffff1660e01b8152600401611c7f9493929190613142565b6020604051808303816000875af1925050508015611cbb57506040513d601f19601f82011682018060405250810190611cb891906131a3565b60015b611d34573d8060008114611ceb576040519150601f19603f3d011682016040523d82523d6000602084013e611cf0565b606091505b506000815103611d2c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b8015611dcd57600183039250600a81066030018353600a81049050611dad565b508181036020830392508083525050919050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b60009392505050565b600033905090565b611e538383611ee6565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611ee157600080549050600083820390505b611e936000868380600101945086611c37565b611ec9576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611e80578160005414611ede57600080fd5b50505b505050565b60008054905060008203611f26576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f336000848385611a76565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611faa83611f9b6000866000611a7c565b611fa4856120a1565b17611aa4565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461204b57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612010565b5060008203612086576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061209c6000848385611acf565b505050565b60006001821460e11b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6120fa816120c5565b811461210557600080fd5b50565b600081359050612117816120f1565b92915050565b600060208284031215612133576121326120bb565b5b600061214184828501612108565b91505092915050565b60008115159050919050565b61215f8161214a565b82525050565b600060208201905061217a6000830184612156565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156121ba57808201518184015260208101905061219f565b838111156121c9576000848401525b50505050565b6000601f19601f8301169050919050565b60006121eb82612180565b6121f5818561218b565b935061220581856020860161219c565b61220e816121cf565b840191505092915050565b6000602082019050818103600083015261223381846121e0565b905092915050565b6000819050919050565b61224e8161223b565b811461225957600080fd5b50565b60008135905061226b81612245565b92915050565b600060208284031215612287576122866120bb565b5b60006122958482850161225c565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006122c98261229e565b9050919050565b6122d9816122be565b82525050565b60006020820190506122f460008301846122d0565b92915050565b612303816122be565b811461230e57600080fd5b50565b600081359050612320816122fa565b92915050565b6000806040838503121561233d5761233c6120bb565b5b600061234b85828601612311565b925050602061235c8582860161225c565b9150509250929050565b61236f8161223b565b82525050565b600060208201905061238a6000830184612366565b92915050565b6000806000606084860312156123a9576123a86120bb565b5b60006123b786828701612311565b93505060206123c886828701612311565b92505060406123d98682870161225c565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f840112612408576124076123e3565b5b8235905067ffffffffffffffff811115612425576124246123e8565b5b602083019150836001820283011115612441576124406123ed565b5b9250929050565b6000806020838503121561245f5761245e6120bb565b5b600083013567ffffffffffffffff81111561247d5761247c6120c0565b5b612489858286016123f2565b92509250509250929050565b6000602082840312156124ab576124aa6120bb565b5b60006124b984828501612311565b91505092915050565b6124cb8161214a565b81146124d657600080fd5b50565b6000813590506124e8816124c2565b92915050565b60008060408385031215612505576125046120bb565b5b600061251385828601612311565b9250506020612524858286016124d9565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61256b826121cf565b810181811067ffffffffffffffff8211171561258a57612589612533565b5b80604052505050565b600061259d6120b1565b90506125a98282612562565b919050565b600067ffffffffffffffff8211156125c9576125c8612533565b5b6125d2826121cf565b9050602081019050919050565b82818337600083830152505050565b60006126016125fc846125ae565b612593565b90508281526020810184848401111561261d5761261c61252e565b5b6126288482856125df565b509392505050565b600082601f830112612645576126446123e3565b5b81356126558482602086016125ee565b91505092915050565b60008060008060808587031215612678576126776120bb565b5b600061268687828801612311565b945050602061269787828801612311565b93505060406126a88782880161225c565b925050606085013567ffffffffffffffff8111156126c9576126c86120c0565b5b6126d587828801612630565b91505092959194509250565b600080604083850312156126f8576126f76120bb565b5b600061270685828601612311565b925050602061271785828601612311565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061276857607f821691505b60208210810361277b5761277a612721565b5b50919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006127b7601f8361218b565b91506127c282612781565b602082019050919050565b600060208201905081810360008301526127e6816127aa565b9050919050565b600081905092915050565b50565b60006128086000836127ed565b9150612813826127f8565b600082019050919050565b6000612829826127fb565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b600061286960108361218b565b915061287482612833565b602082019050919050565b600060208201905081810360008301526128988161285c565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261290c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826128cf565b61291686836128cf565b95508019841693508086168417925050509392505050565b6000819050919050565b600061295361294e6129498461223b565b61292e565b61223b565b9050919050565b6000819050919050565b61296d83612938565b6129816129798261295a565b8484546128dc565b825550505050565b600090565b612996612989565b6129a1818484612964565b505050565b5b818110156129c5576129ba60008261298e565b6001810190506129a7565b5050565b601f821115612a0a576129db816128aa565b6129e4846128bf565b810160208510156129f3578190505b612a076129ff856128bf565b8301826129a6565b50505b505050565b600082821c905092915050565b6000612a2d60001984600802612a0f565b1980831691505092915050565b6000612a468383612a1c565b9150826002028217905092915050565b612a60838361289f565b67ffffffffffffffff811115612a7957612a78612533565b5b612a838254612750565b612a8e8282856129c9565b6000601f831160018114612abd5760008415612aab578287013590505b612ab58582612a3a565b865550612b1d565b601f198416612acb866128aa565b60005b82811015612af357848901358255600182019150602085019450602081019050612ace565b86831015612b105784890135612b0c601f891682612a1c565b8355505b6001600288020188555050505b50505050505050565b7f596f752063616e2774206d696e742066726f6d206120636f6e74726163742e00600082015250565b6000612b5c601f8361218b565b9150612b6782612b26565b602082019050919050565b60006020820190508181036000830152612b8b81612b4f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bcc8261223b565b9150612bd78361223b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612c1057612c0f612b92565b5b828202905092915050565b7f506c656173652073656e642074686520657861637420616d6f756e7420696e2060008201527f6f7264657220746f206d696e742e000000000000000000000000000000000000602082015250565b6000612c77602e8361218b565b9150612c8282612c1b565b604082019050919050565b60006020820190508181036000830152612ca681612c6a565b9050919050565b6000612cb88261223b565b9150612cc38361223b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612cf857612cf7612b92565b5b828201905092915050565b7f536f6c64206f75742e0000000000000000000000000000000000000000000000600082015250565b6000612d3960098361218b565b9150612d4482612d03565b602082019050919050565b60006020820190508181036000830152612d6881612d2c565b9050919050565b7f596f75206861766520657863656564656420746865206d696e74206c696d697460008201527f207065722077616c6c65742e0000000000000000000000000000000000000000602082015250565b6000612dcb602c8361218b565b9150612dd682612d6f565b604082019050919050565b60006020820190508181036000830152612dfa81612dbe565b9050919050565b7f596f75206861766520657863656564656420746865206d696e74206c696d697460008201527f20706572207472616e73616374696f6e2e000000000000000000000000000000602082015250565b6000612e5d60318361218b565b9150612e6882612e01565b604082019050919050565b60006020820190508181036000830152612e8c81612e50565b9050919050565b600081905092915050565b60008154612eab81612750565b612eb58186612e93565b94506001821660008114612ed05760018114612ee557612f18565b60ff1983168652811515820286019350612f18565b612eee856128aa565b60005b83811015612f1057815481890152600182019150602081019050612ef1565b838801955050505b50505092915050565b6000612f2c82612180565b612f368185612e93565b9350612f4681856020860161219c565b80840191505092915050565b6000612f5e8286612e9e565b9150612f6a8285612f21565b9150612f768284612e9e565b9150819050949350505050565b7f43616e2774206d696e7400000000000000000000000000000000000000000000600082015250565b6000612fb9600a8361218b565b9150612fc482612f83565b602082019050919050565b60006020820190508181036000830152612fe881612fac565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061304b60268361218b565b915061305682612fef565b604082019050919050565b6000602082019050818103600083015261307a8161303e565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006130b760208361218b565b91506130c282613081565b602082019050919050565b600060208201905081810360008301526130e6816130aa565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613114826130ed565b61311e81856130f8565b935061312e81856020860161219c565b613137816121cf565b840191505092915050565b600060808201905061315760008301876122d0565b61316460208301866122d0565b6131716040830185612366565b81810360608301526131838184613109565b905095945050505050565b60008151905061319d816120f1565b92915050565b6000602082840312156131b9576131b86120bb565b5b60006131c78482850161318e565b9150509291505056fea264697066735822122065ce64c3b3747b9109eee4f6986ad817c57154b22b956028a5a44d6b27158adb64736f6c634300080f0033

Deployed Bytecode Sourcemap

60214:2347:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27317:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28219:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34702:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34143:400;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23970:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38409:2817;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62372:186;;;;;;;;;;;;;:::i;:::-;;41322:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60563:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60451:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60802:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60706:84;;;;;;;;;;;;;:::i;:::-;;29612:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60276:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25154:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8065:103;;;;;;;;;;;;;:::i;:::-;;7417:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28395:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60304:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60487:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60912:550;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35260:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60343:101;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42105:399;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61655:363;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60602:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62135:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35725:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61470:173;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;8323:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60529:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27317:639;27402:4;27741:10;27726:25;;:11;:25;;;;:102;;;;27818:10;27803:25;;:11;:25;;;;27726:102;:179;;;;27895:10;27880:25;;:11;:25;;;;27726:179;27706:199;;27317:639;;;:::o;28219:100::-;28273:13;28306:5;28299:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28219:100;:::o;34702:218::-;34778:7;34803:16;34811:7;34803;:16::i;:::-;34798:64;;34828:34;;;;;;;;;;;;;;34798:64;34882:15;:24;34898:7;34882:24;;;;;;;;;;;:30;;;;;;;;;;;;34875:37;;34702:218;;;:::o;34143:400::-;34224:13;34240:16;34248:7;34240;:16::i;:::-;34224:32;;34296:5;34273:28;;:19;:17;:19::i;:::-;:28;;;34269:175;;34321:44;34338:5;34345:19;:17;:19::i;:::-;34321:16;:44::i;:::-;34316:128;;34393:35;;;;;;;;;;;;;;34316:128;34269:175;34489:2;34456:15;:24;34472:7;34456:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;34527:7;34523:2;34507:28;;34516:5;34507:28;;;;;;;;;;;;34213:330;34143:400;;:::o;23970:323::-;24031:7;24259:15;:13;:15::i;:::-;24244:12;;24228:13;;:28;:46;24221:53;;23970:323;:::o;38409:2817::-;38543:27;38573;38592:7;38573:18;:27::i;:::-;38543:57;;38658:4;38617:45;;38633:19;38617:45;;;38613:86;;38671:28;;;;;;;;;;;;;;38613:86;38713:27;38742:23;38769:35;38796:7;38769:26;:35::i;:::-;38712:92;;;;38904:68;38929:15;38946:4;38952:19;:17;:19::i;:::-;38904:24;:68::i;:::-;38899:180;;38992:43;39009:4;39015:19;:17;:19::i;:::-;38992:16;:43::i;:::-;38987:92;;39044:35;;;;;;;;;;;;;;38987:92;38899:180;39110:1;39096:16;;:2;:16;;;39092:52;;39121:23;;;;;;;;;;;;;;39092:52;39157:43;39179:4;39185:2;39189:7;39198:1;39157:21;:43::i;:::-;39293:15;39290:160;;;39433:1;39412:19;39405:30;39290:160;39830:18;:24;39849:4;39830:24;;;;;;;;;;;;;;;;39828:26;;;;;;;;;;;;39899:18;:22;39918:2;39899:22;;;;;;;;;;;;;;;;39897:24;;;;;;;;;;;40221:146;40258:2;40307:45;40322:4;40328:2;40332:19;40307:14;:45::i;:::-;20369:8;40279:73;40221:18;:146::i;:::-;40192:17;:26;40210:7;40192:26;;;;;;;;;;;:175;;;;40538:1;20369:8;40487:19;:47;:52;40483:627;;40560:19;40592:1;40582:7;:11;40560:33;;40749:1;40715:17;:30;40733:11;40715:30;;;;;;;;;;;;:35;40711:384;;40853:13;;40838:11;:28;40834:242;;41033:19;41000:17;:30;41018:11;41000:30;;;;;;;;;;;:52;;;;40834:242;40711:384;40541:569;40483:627;41157:7;41153:2;41138:27;;41147:4;41138:27;;;;;;;;;;;;41176:42;41197:4;41203:2;41207:7;41216:1;41176:20;:42::i;:::-;38532:2694;;;38409:2817;;;:::o;62372:186::-;7303:13;:11;:13::i;:::-;4342:1:::1;4940:7;;:19:::0;4932:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;4342:1;5073:7;:18;;;;62436:12:::2;62454:10;:15;;62477:21;62454:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62435:68;;;62522:7;62514:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;62424:134;4298:1:::1;5252:7;:22;;;;62372:186::o:0;41322:185::-;41460:39;41477:4;41483:2;41487:7;41460:39;;;;;;;;;;;;:16;:39::i;:::-;41322:185;;;:::o;60563:32::-;;;;:::o;60451:27::-;;;;;;;;;;;;;:::o;60802:102::-;7303:13;:11;:13::i;:::-;60888:8:::1;;60878:7;:18;;;;;;;:::i;:::-;;60802:102:::0;;:::o;60706:84::-;7303:13;:11;:13::i;:::-;60774:8:::1;;;;;;;;;;;60773:9;60762:8;;:20;;;;;;;;;;;;;;;;;;60706:84::o:0;29612:152::-;29684:7;29727:27;29746:7;29727:18;:27::i;:::-;29704:52;;29612:152;;;:::o;60276:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;25154:233::-;25226:7;25267:1;25250:19;;:5;:19;;;25246:60;;25278:28;;;;;;;;;;;;;;25246:60;19313:13;25324:18;:25;25343:5;25324:25;;;;;;;;;;;;;;;;:55;25317:62;;25154:233;;;:::o;8065:103::-;7303:13;:11;:13::i;:::-;8130:30:::1;8157:1;8130:18;:30::i;:::-;8065:103::o:0;7417:87::-;7463:7;7490:6;;;;;;;;;;;7483:13;;7417:87;:::o;28395:104::-;28451:13;28484:7;28477:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28395:104;:::o;60304:32::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;60487:35::-;;;;:::o;60912:550::-;60994:9;60980:23;;:10;:23;;;60972:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;61080:5;;61071:6;:14;;;;:::i;:::-;61058:9;:27;61050:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;61181:9;;61171:6;61155:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;61147:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;61260:12;;61250:6;61223:24;61236:10;61223:12;:24::i;:::-;:33;;;;:::i;:::-;:49;;61215:106;;;;;;;;;;;;:::i;:::-;;;;;;;;;61350:8;;61340:6;:18;;61332:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;61425:29;61435:10;61447:6;61425:9;:29::i;:::-;60912:550;:::o;35260:308::-;35371:19;:17;:19::i;:::-;35359:31;;:8;:31;;;35355:61;;35399:17;;;;;;;;;;;;;;35355:61;35481:8;35429:18;:39;35448:19;:17;:19::i;:::-;35429:39;;;;;;;;;;;;;;;:49;35469:8;35429:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;35541:8;35505:55;;35520:19;:17;:19::i;:::-;35505:55;;;35551:8;35505:55;;;;;;:::i;:::-;;;;;;;;35260:308;;:::o;60343:101::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;42105:399::-;42272:31;42285:4;42291:2;42295:7;42272:12;:31::i;:::-;42336:1;42318:2;:14;;;:19;42314:183;;42357:56;42388:4;42394:2;42398:7;42407:5;42357:30;:56::i;:::-;42352:145;;42441:40;;;;;;;;;;;;;;42352:145;42314:183;42105:399;;;;:::o;61655:363::-;61728:13;61759:16;61767:7;61759;:16::i;:::-;61754:59;;61784:29;;;;;;;;;;;;;;61754:59;61840:5;61828:17;;:8;;;;;;;;;;;:17;;;61824:70;;61865:17;61858:24;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61824:70;61938:1;61919:7;61913:21;;;;;:::i;:::-;;;:26;:97;;;;;;;;;;;;;;;;;61966:7;61975:18;61985:7;61975:9;:18::i;:::-;61995:8;61949:55;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61913:97;61906:104;;61655:363;;;;:::o;60602:32::-;;;;:::o;62135:113::-;62193:7;62220:20;62234:5;62220:13;:20::i;:::-;62213:27;;62135:113;;;:::o;35725:164::-;35822:4;35846:18;:25;35865:5;35846:25;;;;;;;;;;;;;;;:35;35872:8;35846:35;;;;;;;;;;;;;;;;;;;;;;;;;35839:42;;35725:164;;;;:::o;61470:173::-;7303:13;:11;:13::i;:::-;61569:9:::1;;61559:6;61543:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;61535:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;61606:29;61616:10;61628:6;61606:9;:29::i;:::-;61470:173:::0;:::o;8323:201::-;7303:13;:11;:13::i;:::-;8432:1:::1;8412:22;;:8;:22;;::::0;8404:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;8488:28;8507:8;8488:18;:28::i;:::-;8323:201:::0;:::o;60529:27::-;;;;:::o;36147:282::-;36212:4;36268:7;36249:15;:13;:15::i;:::-;:26;;:66;;;;;36302:13;;36292:7;:23;36249:66;:153;;;;;36401:1;20089:8;36353:17;:26;36371:7;36353:26;;;;;;;;;;;;:44;:49;36249:153;36229:173;;36147:282;;;:::o;57913:105::-;57973:7;58000:10;57993:17;;57913:105;:::o;62026:101::-;62091:7;62118:1;62111:8;;62026:101;:::o;30767:1275::-;30834:7;30854:12;30869:7;30854:22;;30937:4;30918:15;:13;:15::i;:::-;:23;30914:1061;;30971:13;;30964:4;:20;30960:1015;;;31009:14;31026:17;:23;31044:4;31026:23;;;;;;;;;;;;31009:40;;31143:1;20089:8;31115:6;:24;:29;31111:845;;31780:113;31797:1;31787:6;:11;31780:113;;31840:17;:25;31858:6;;;;;;;31840:25;;;;;;;;;;;;31831:34;;31780:113;;;31926:6;31919:13;;;;;;31111:845;30986:989;30960:1015;30914:1061;32003:31;;;;;;;;;;;;;;30767:1275;;;;:::o;37310:479::-;37412:27;37441:23;37482:38;37523:15;:24;37539:7;37523:24;;;;;;;;;;;37482:65;;37694:18;37671:41;;37751:19;37745:26;37726:45;;37656:126;37310:479;;;:::o;36538:659::-;36687:11;36852:16;36845:5;36841:28;36832:37;;37012:16;37001:9;36997:32;36984:45;;37162:15;37151:9;37148:30;37140:5;37129:9;37126:20;37123:56;37113:66;;36538:659;;;;;:::o;43166:159::-;;;;;:::o;57222:311::-;57357:7;57377:16;20493:3;57403:19;:41;;57377:68;;20493:3;57471:31;57482:4;57488:2;57492:9;57471:10;:31::i;:::-;57463:40;;:62;;57456:69;;;57222:311;;;;;:::o;32590:450::-;32670:14;32838:16;32831:5;32827:28;32818:37;;33015:5;33001:11;32976:23;32972:41;32969:52;32962:5;32959:63;32949:73;;32590:450;;;;:::o;43990:158::-;;;;;:::o;7582:132::-;7657:12;:10;:12::i;:::-;7646:23;;:7;:5;:7::i;:::-;:23;;;7638:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;7582:132::o;8684:191::-;8758:16;8777:6;;;;;;;;;;;8758:25;;8803:8;8794:6;;:17;;;;;;;;;;;;;;;;;;8858:8;8827:40;;8848:8;8827:40;;;;;;;;;;;;8747:128;8684:191;:::o;51745:112::-;51822:27;51832:2;51836:8;51822:27;;;;;;;;;;;;:9;:27::i;:::-;51745:112;;:::o;44588:716::-;44751:4;44797:2;44772:45;;;44818:19;:17;:19::i;:::-;44839:4;44845:7;44854:5;44772:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;44768:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45072:1;45055:6;:13;:18;45051:235;;45101:40;;;;;;;;;;;;;;45051:235;45244:6;45238:13;45229:6;45225:2;45221:15;45214:38;44768:529;44941:54;;;44931:64;;;:6;:64;;;;44924:71;;;44588:716;;;;;;:::o;58120:2002::-;58185:17;58604:3;58597:4;58591:11;58587:21;58580:28;;58695:3;58689:4;58682:17;58801:3;59257:5;59387:1;59382:3;59378:11;59371:18;;59558:2;59552:4;59548:13;59544:2;59540:22;59535:3;59527:36;59599:2;59593:4;59589:13;59581:21;;59149:731;59618:4;59149:731;;;59809:1;59804:3;59800:11;59793:18;;59860:2;59854:4;59850:13;59846:2;59842:22;59837:3;59829:36;59713:2;59707:4;59703:13;59695:21;;59149:731;;;59153:464;59919:3;59914;59910:13;60034:2;60029:3;60025:12;60018:19;;60097:6;60092:3;60085:19;58224:1891;;58120:2002;;;:::o;25469:178::-;25530:7;19313:13;19451:2;25558:18;:25;25577:5;25558:25;;;;;;;;;;;;;;;;:50;;25557:82;25550:89;;25469:178;;;:::o;56923:147::-;57060:6;56923:147;;;;;:::o;5968:98::-;6021:7;6048:10;6041:17;;5968:98;:::o;50972:689::-;51103:19;51109:2;51113:8;51103:5;:19::i;:::-;51182:1;51164:2;:14;;;:19;51160:483;;51204:11;51218:13;;51204:27;;51250:13;51272:8;51266:3;:14;51250:30;;51299:233;51330:62;51369:1;51373:2;51377:7;;;;;;51386:5;51330:30;:62::i;:::-;51325:167;;51428:40;;;;;;;;;;;;;;51325:167;51527:3;51519:5;:11;51299:233;;51614:3;51597:13;;:20;51593:34;;51619:8;;;51593:34;51185:458;;51160:483;50972:689;;;:::o;45766:2454::-;45839:20;45862:13;;45839:36;;45902:1;45890:8;:13;45886:44;;45912:18;;;;;;;;;;;;;;45886:44;45943:61;45973:1;45977:2;45981:12;45995:8;45943:21;:61::i;:::-;46487:1;19451:2;46457:1;:26;;46456:32;46444:8;:45;46418:18;:22;46437:2;46418:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;46766:139;46803:2;46857:33;46880:1;46884:2;46888:1;46857:14;:33::i;:::-;46824:30;46845:8;46824:20;:30::i;:::-;:66;46766:18;:139::i;:::-;46732:17;:31;46750:12;46732:31;;;;;;;;;;;:173;;;;46922:16;46953:11;46982:8;46967:12;:23;46953:37;;47237:16;47233:2;47229:25;47217:37;;47609:12;47569:8;47528:1;47466:25;47407:1;47346;47319:335;47734:1;47720:12;47716:20;47674:346;47775:3;47766:7;47763:16;47674:346;;47993:7;47983:8;47980:1;47953:25;47950:1;47947;47942:59;47828:1;47819:7;47815:15;47804:26;;47674:346;;;47678:77;48065:1;48053:8;:13;48049:45;;48075:19;;;;;;;;;;;;;;48049:45;48127:3;48111:13;:19;;;;46192:1950;;48152:60;48181:1;48185:2;48189:12;48203:8;48152:20;:60::i;:::-;45828:2392;45766:2454;;:::o;33142:324::-;33212:14;33445:1;33435:8;33432:15;33406:24;33402:46;33392:56;;33142:324;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:118::-;5025:24;5043:5;5025:24;:::i;:::-;5020:3;5013:37;4938:118;;:::o;5062:222::-;5155:4;5193:2;5182:9;5178:18;5170:26;;5206:71;5274:1;5263:9;5259:17;5250:6;5206:71;:::i;:::-;5062:222;;;;:::o;5290:619::-;5367:6;5375;5383;5432:2;5420:9;5411:7;5407:23;5403:32;5400:119;;;5438:79;;:::i;:::-;5400:119;5558:1;5583:53;5628:7;5619:6;5608:9;5604:22;5583:53;:::i;:::-;5573:63;;5529:117;5685:2;5711:53;5756:7;5747:6;5736:9;5732:22;5711:53;:::i;:::-;5701:63;;5656:118;5813:2;5839:53;5884:7;5875:6;5864:9;5860:22;5839:53;:::i;:::-;5829:63;;5784:118;5290:619;;;;;:::o;5915:117::-;6024:1;6021;6014:12;6038:117;6147:1;6144;6137:12;6161:117;6270:1;6267;6260:12;6298:553;6356:8;6366:6;6416:3;6409:4;6401:6;6397:17;6393:27;6383:122;;6424:79;;:::i;:::-;6383:122;6537:6;6524:20;6514:30;;6567:18;6559:6;6556:30;6553:117;;;6589:79;;:::i;:::-;6553:117;6703:4;6695:6;6691:17;6679:29;;6757:3;6749:4;6741:6;6737:17;6727:8;6723:32;6720:41;6717:128;;;6764:79;;:::i;:::-;6717:128;6298:553;;;;;:::o;6857:529::-;6928:6;6936;6985:2;6973:9;6964:7;6960:23;6956:32;6953:119;;;6991:79;;:::i;:::-;6953:119;7139:1;7128:9;7124:17;7111:31;7169:18;7161:6;7158:30;7155:117;;;7191:79;;:::i;:::-;7155:117;7304:65;7361:7;7352:6;7341:9;7337:22;7304:65;:::i;:::-;7286:83;;;;7082:297;6857:529;;;;;:::o;7392:329::-;7451:6;7500:2;7488:9;7479:7;7475:23;7471:32;7468:119;;;7506:79;;:::i;:::-;7468:119;7626:1;7651:53;7696:7;7687:6;7676:9;7672:22;7651:53;:::i;:::-;7641:63;;7597:117;7392:329;;;;:::o;7727:116::-;7797:21;7812:5;7797:21;:::i;:::-;7790:5;7787:32;7777:60;;7833:1;7830;7823:12;7777:60;7727:116;:::o;7849:133::-;7892:5;7930:6;7917:20;7908:29;;7946:30;7970:5;7946:30;:::i;:::-;7849:133;;;;:::o;7988:468::-;8053:6;8061;8110:2;8098:9;8089:7;8085:23;8081:32;8078:119;;;8116:79;;:::i;:::-;8078:119;8236:1;8261:53;8306:7;8297:6;8286:9;8282:22;8261:53;:::i;:::-;8251:63;;8207:117;8363:2;8389:50;8431:7;8422:6;8411:9;8407:22;8389:50;:::i;:::-;8379:60;;8334:115;7988:468;;;;;:::o;8462:117::-;8571:1;8568;8561:12;8585:180;8633:77;8630:1;8623:88;8730:4;8727:1;8720:15;8754:4;8751:1;8744:15;8771:281;8854:27;8876:4;8854:27;:::i;:::-;8846:6;8842:40;8984:6;8972:10;8969:22;8948:18;8936:10;8933:34;8930:62;8927:88;;;8995:18;;:::i;:::-;8927:88;9035:10;9031:2;9024:22;8814:238;8771:281;;:::o;9058:129::-;9092:6;9119:20;;:::i;:::-;9109:30;;9148:33;9176:4;9168:6;9148:33;:::i;:::-;9058:129;;;:::o;9193:307::-;9254:4;9344:18;9336:6;9333:30;9330:56;;;9366:18;;:::i;:::-;9330:56;9404:29;9426:6;9404:29;:::i;:::-;9396:37;;9488:4;9482;9478:15;9470:23;;9193:307;;;:::o;9506:154::-;9590:6;9585:3;9580;9567:30;9652:1;9643:6;9638:3;9634:16;9627:27;9506:154;;;:::o;9666:410::-;9743:5;9768:65;9784:48;9825:6;9784:48;:::i;:::-;9768:65;:::i;:::-;9759:74;;9856:6;9849:5;9842:21;9894:4;9887:5;9883:16;9932:3;9923:6;9918:3;9914:16;9911:25;9908:112;;;9939:79;;:::i;:::-;9908:112;10029:41;10063:6;10058:3;10053;10029:41;:::i;:::-;9749:327;9666:410;;;;;:::o;10095:338::-;10150:5;10199:3;10192:4;10184:6;10180:17;10176:27;10166:122;;10207:79;;:::i;:::-;10166:122;10324:6;10311:20;10349:78;10423:3;10415:6;10408:4;10400:6;10396:17;10349:78;:::i;:::-;10340:87;;10156:277;10095:338;;;;:::o;10439:943::-;10534:6;10542;10550;10558;10607:3;10595:9;10586:7;10582:23;10578:33;10575:120;;;10614:79;;:::i;:::-;10575:120;10734:1;10759:53;10804:7;10795:6;10784:9;10780:22;10759:53;:::i;:::-;10749:63;;10705:117;10861:2;10887:53;10932:7;10923:6;10912:9;10908:22;10887:53;:::i;:::-;10877:63;;10832:118;10989:2;11015:53;11060:7;11051:6;11040:9;11036:22;11015:53;:::i;:::-;11005:63;;10960:118;11145:2;11134:9;11130:18;11117:32;11176:18;11168:6;11165:30;11162:117;;;11198:79;;:::i;:::-;11162:117;11303:62;11357:7;11348:6;11337:9;11333:22;11303:62;:::i;:::-;11293:72;;11088:287;10439:943;;;;;;;:::o;11388:474::-;11456:6;11464;11513:2;11501:9;11492:7;11488:23;11484:32;11481:119;;;11519:79;;:::i;:::-;11481:119;11639:1;11664:53;11709:7;11700:6;11689:9;11685:22;11664:53;:::i;:::-;11654:63;;11610:117;11766:2;11792:53;11837:7;11828:6;11817:9;11813:22;11792:53;:::i;:::-;11782:63;;11737:118;11388:474;;;;;:::o;11868:180::-;11916:77;11913:1;11906:88;12013:4;12010:1;12003:15;12037:4;12034:1;12027:15;12054:320;12098:6;12135:1;12129:4;12125:12;12115:22;;12182:1;12176:4;12172:12;12203:18;12193:81;;12259:4;12251:6;12247:17;12237:27;;12193:81;12321:2;12313:6;12310:14;12290:18;12287:38;12284:84;;12340:18;;:::i;:::-;12284:84;12105:269;12054:320;;;:::o;12380:181::-;12520:33;12516:1;12508:6;12504:14;12497:57;12380:181;:::o;12567:366::-;12709:3;12730:67;12794:2;12789:3;12730:67;:::i;:::-;12723:74;;12806:93;12895:3;12806:93;:::i;:::-;12924:2;12919:3;12915:12;12908:19;;12567:366;;;:::o;12939:419::-;13105:4;13143:2;13132:9;13128:18;13120:26;;13192:9;13186:4;13182:20;13178:1;13167:9;13163:17;13156:47;13220:131;13346:4;13220:131;:::i;:::-;13212:139;;12939:419;;;:::o;13364:147::-;13465:11;13502:3;13487:18;;13364:147;;;;:::o;13517:114::-;;:::o;13637:398::-;13796:3;13817:83;13898:1;13893:3;13817:83;:::i;:::-;13810:90;;13909:93;13998:3;13909:93;:::i;:::-;14027:1;14022:3;14018:11;14011:18;;13637:398;;;:::o;14041:379::-;14225:3;14247:147;14390:3;14247:147;:::i;:::-;14240:154;;14411:3;14404:10;;14041:379;;;:::o;14426:166::-;14566:18;14562:1;14554:6;14550:14;14543:42;14426:166;:::o;14598:366::-;14740:3;14761:67;14825:2;14820:3;14761:67;:::i;:::-;14754:74;;14837:93;14926:3;14837:93;:::i;:::-;14955:2;14950:3;14946:12;14939:19;;14598:366;;;:::o;14970:419::-;15136:4;15174:2;15163:9;15159:18;15151:26;;15223:9;15217:4;15213:20;15209:1;15198:9;15194:17;15187:47;15251:131;15377:4;15251:131;:::i;:::-;15243:139;;14970:419;;;:::o;15395:97::-;15454:6;15482:3;15472:13;;15395:97;;;;:::o;15498:141::-;15547:4;15570:3;15562:11;;15593:3;15590:1;15583:14;15627:4;15624:1;15614:18;15606:26;;15498:141;;;:::o;15645:93::-;15682:6;15729:2;15724;15717:5;15713:14;15709:23;15699:33;;15645:93;;;:::o;15744:107::-;15788:8;15838:5;15832:4;15828:16;15807:37;;15744:107;;;;:::o;15857:393::-;15926:6;15976:1;15964:10;15960:18;15999:97;16029:66;16018:9;15999:97;:::i;:::-;16117:39;16147:8;16136:9;16117:39;:::i;:::-;16105:51;;16189:4;16185:9;16178:5;16174:21;16165:30;;16238:4;16228:8;16224:19;16217:5;16214:30;16204:40;;15933:317;;15857:393;;;;;:::o;16256:60::-;16284:3;16305:5;16298:12;;16256:60;;;:::o;16322:142::-;16372:9;16405:53;16423:34;16432:24;16450:5;16432:24;:::i;:::-;16423:34;:::i;:::-;16405:53;:::i;:::-;16392:66;;16322:142;;;:::o;16470:75::-;16513:3;16534:5;16527:12;;16470:75;;;:::o;16551:269::-;16661:39;16692:7;16661:39;:::i;:::-;16722:91;16771:41;16795:16;16771:41;:::i;:::-;16763:6;16756:4;16750:11;16722:91;:::i;:::-;16716:4;16709:105;16627:193;16551:269;;;:::o;16826:73::-;16871:3;16826:73;:::o;16905:189::-;16982:32;;:::i;:::-;17023:65;17081:6;17073;17067:4;17023:65;:::i;:::-;16958:136;16905:189;;:::o;17100:186::-;17160:120;17177:3;17170:5;17167:14;17160:120;;;17231:39;17268:1;17261:5;17231:39;:::i;:::-;17204:1;17197:5;17193:13;17184:22;;17160:120;;;17100:186;;:::o;17292:543::-;17393:2;17388:3;17385:11;17382:446;;;17427:38;17459:5;17427:38;:::i;:::-;17511:29;17529:10;17511:29;:::i;:::-;17501:8;17497:44;17694:2;17682:10;17679:18;17676:49;;;17715:8;17700:23;;17676:49;17738:80;17794:22;17812:3;17794:22;:::i;:::-;17784:8;17780:37;17767:11;17738:80;:::i;:::-;17397:431;;17382:446;17292:543;;;:::o;17841:117::-;17895:8;17945:5;17939:4;17935:16;17914:37;;17841:117;;;;:::o;17964:169::-;18008:6;18041:51;18089:1;18085:6;18077:5;18074:1;18070:13;18041:51;:::i;:::-;18037:56;18122:4;18116;18112:15;18102:25;;18015:118;17964:169;;;;:::o;18138:295::-;18214:4;18360:29;18385:3;18379:4;18360:29;:::i;:::-;18352:37;;18422:3;18419:1;18415:11;18409:4;18406:21;18398:29;;18138:295;;;;:::o;18438:1403::-;18562:44;18602:3;18597;18562:44;:::i;:::-;18671:18;18663:6;18660:30;18657:56;;;18693:18;;:::i;:::-;18657:56;18737:38;18769:4;18763:11;18737:38;:::i;:::-;18822:67;18882:6;18874;18868:4;18822:67;:::i;:::-;18916:1;18945:2;18937:6;18934:14;18962:1;18957:632;;;;19633:1;19650:6;19647:84;;;19706:9;19701:3;19697:19;19684:33;19675:42;;19647:84;19757:67;19817:6;19810:5;19757:67;:::i;:::-;19751:4;19744:81;19606:229;18927:908;;18957:632;19009:4;19005:9;18997:6;18993:22;19043:37;19075:4;19043:37;:::i;:::-;19102:1;19116:215;19130:7;19127:1;19124:14;19116:215;;;19216:9;19211:3;19207:19;19194:33;19186:6;19179:49;19267:1;19259:6;19255:14;19245:24;;19314:2;19303:9;19299:18;19286:31;;19153:4;19150:1;19146:12;19141:17;;19116:215;;;19359:6;19350:7;19347:19;19344:186;;;19424:9;19419:3;19415:19;19402:33;19467:48;19509:4;19501:6;19497:17;19486:9;19467:48;:::i;:::-;19459:6;19452:64;19367:163;19344:186;19576:1;19572;19564:6;19560:14;19556:22;19550:4;19543:36;18964:625;;;18927:908;;18537:1304;;;18438:1403;;;:::o;19847:181::-;19987:33;19983:1;19975:6;19971:14;19964:57;19847:181;:::o;20034:366::-;20176:3;20197:67;20261:2;20256:3;20197:67;:::i;:::-;20190:74;;20273:93;20362:3;20273:93;:::i;:::-;20391:2;20386:3;20382:12;20375:19;;20034:366;;;:::o;20406:419::-;20572:4;20610:2;20599:9;20595:18;20587:26;;20659:9;20653:4;20649:20;20645:1;20634:9;20630:17;20623:47;20687:131;20813:4;20687:131;:::i;:::-;20679:139;;20406:419;;;:::o;20831:180::-;20879:77;20876:1;20869:88;20976:4;20973:1;20966:15;21000:4;20997:1;20990:15;21017:348;21057:7;21080:20;21098:1;21080:20;:::i;:::-;21075:25;;21114:20;21132:1;21114:20;:::i;:::-;21109:25;;21302:1;21234:66;21230:74;21227:1;21224:81;21219:1;21212:9;21205:17;21201:105;21198:131;;;21309:18;;:::i;:::-;21198:131;21357:1;21354;21350:9;21339:20;;21017:348;;;;:::o;21371:233::-;21511:34;21507:1;21499:6;21495:14;21488:58;21580:16;21575:2;21567:6;21563:15;21556:41;21371:233;:::o;21610:366::-;21752:3;21773:67;21837:2;21832:3;21773:67;:::i;:::-;21766:74;;21849:93;21938:3;21849:93;:::i;:::-;21967:2;21962:3;21958:12;21951:19;;21610:366;;;:::o;21982:419::-;22148:4;22186:2;22175:9;22171:18;22163:26;;22235:9;22229:4;22225:20;22221:1;22210:9;22206:17;22199:47;22263:131;22389:4;22263:131;:::i;:::-;22255:139;;21982:419;;;:::o;22407:305::-;22447:3;22466:20;22484:1;22466:20;:::i;:::-;22461:25;;22500:20;22518:1;22500:20;:::i;:::-;22495:25;;22654:1;22586:66;22582:74;22579:1;22576:81;22573:107;;;22660:18;;:::i;:::-;22573:107;22704:1;22701;22697:9;22690:16;;22407:305;;;;:::o;22718:159::-;22858:11;22854:1;22846:6;22842:14;22835:35;22718:159;:::o;22883:365::-;23025:3;23046:66;23110:1;23105:3;23046:66;:::i;:::-;23039:73;;23121:93;23210:3;23121:93;:::i;:::-;23239:2;23234:3;23230:12;23223:19;;22883:365;;;:::o;23254:419::-;23420:4;23458:2;23447:9;23443:18;23435:26;;23507:9;23501:4;23497:20;23493:1;23482:9;23478:17;23471:47;23535:131;23661:4;23535:131;:::i;:::-;23527:139;;23254:419;;;:::o;23679:231::-;23819:34;23815:1;23807:6;23803:14;23796:58;23888:14;23883:2;23875:6;23871:15;23864:39;23679:231;:::o;23916:366::-;24058:3;24079:67;24143:2;24138:3;24079:67;:::i;:::-;24072:74;;24155:93;24244:3;24155:93;:::i;:::-;24273:2;24268:3;24264:12;24257:19;;23916:366;;;:::o;24288:419::-;24454:4;24492:2;24481:9;24477:18;24469:26;;24541:9;24535:4;24531:20;24527:1;24516:9;24512:17;24505:47;24569:131;24695:4;24569:131;:::i;:::-;24561:139;;24288:419;;;:::o;24713:236::-;24853:34;24849:1;24841:6;24837:14;24830:58;24922:19;24917:2;24909:6;24905:15;24898:44;24713:236;:::o;24955:366::-;25097:3;25118:67;25182:2;25177:3;25118:67;:::i;:::-;25111:74;;25194:93;25283:3;25194:93;:::i;:::-;25312:2;25307:3;25303:12;25296:19;;24955:366;;;:::o;25327:419::-;25493:4;25531:2;25520:9;25516:18;25508:26;;25580:9;25574:4;25570:20;25566:1;25555:9;25551:17;25544:47;25608:131;25734:4;25608:131;:::i;:::-;25600:139;;25327:419;;;:::o;25752:148::-;25854:11;25891:3;25876:18;;25752:148;;;;:::o;25930:874::-;26033:3;26070:5;26064:12;26099:36;26125:9;26099:36;:::i;:::-;26151:89;26233:6;26228:3;26151:89;:::i;:::-;26144:96;;26271:1;26260:9;26256:17;26287:1;26282:166;;;;26462:1;26457:341;;;;26249:549;;26282:166;26366:4;26362:9;26351;26347:25;26342:3;26335:38;26428:6;26421:14;26414:22;26406:6;26402:35;26397:3;26393:45;26386:52;;26282:166;;26457:341;26524:38;26556:5;26524:38;:::i;:::-;26584:1;26598:154;26612:6;26609:1;26606:13;26598:154;;;26686:7;26680:14;26676:1;26671:3;26667:11;26660:35;26736:1;26727:7;26723:15;26712:26;;26634:4;26631:1;26627:12;26622:17;;26598:154;;;26781:6;26776:3;26772:16;26765:23;;26464:334;;26249:549;;26037:767;;25930:874;;;;:::o;26810:377::-;26916:3;26944:39;26977:5;26944:39;:::i;:::-;26999:89;27081:6;27076:3;26999:89;:::i;:::-;26992:96;;27097:52;27142:6;27137:3;27130:4;27123:5;27119:16;27097:52;:::i;:::-;27174:6;27169:3;27165:16;27158:23;;26920:267;26810:377;;;;:::o;27193:583::-;27415:3;27437:92;27525:3;27516:6;27437:92;:::i;:::-;27430:99;;27546:95;27637:3;27628:6;27546:95;:::i;:::-;27539:102;;27658:92;27746:3;27737:6;27658:92;:::i;:::-;27651:99;;27767:3;27760:10;;27193:583;;;;;;:::o;27782:160::-;27922:12;27918:1;27910:6;27906:14;27899:36;27782:160;:::o;27948:366::-;28090:3;28111:67;28175:2;28170:3;28111:67;:::i;:::-;28104:74;;28187:93;28276:3;28187:93;:::i;:::-;28305:2;28300:3;28296:12;28289:19;;27948:366;;;:::o;28320:419::-;28486:4;28524:2;28513:9;28509:18;28501:26;;28573:9;28567:4;28563:20;28559:1;28548:9;28544:17;28537:47;28601:131;28727:4;28601:131;:::i;:::-;28593:139;;28320:419;;;:::o;28745:225::-;28885:34;28881:1;28873:6;28869:14;28862:58;28954:8;28949:2;28941:6;28937:15;28930:33;28745:225;:::o;28976:366::-;29118:3;29139:67;29203:2;29198:3;29139:67;:::i;:::-;29132:74;;29215:93;29304:3;29215:93;:::i;:::-;29333:2;29328:3;29324:12;29317:19;;28976:366;;;:::o;29348:419::-;29514:4;29552:2;29541:9;29537:18;29529:26;;29601:9;29595:4;29591:20;29587:1;29576:9;29572:17;29565:47;29629:131;29755:4;29629:131;:::i;:::-;29621:139;;29348:419;;;:::o;29773:182::-;29913:34;29909:1;29901:6;29897:14;29890:58;29773:182;:::o;29961:366::-;30103:3;30124:67;30188:2;30183:3;30124:67;:::i;:::-;30117:74;;30200:93;30289:3;30200:93;:::i;:::-;30318:2;30313:3;30309:12;30302:19;;29961:366;;;:::o;30333:419::-;30499:4;30537:2;30526:9;30522:18;30514:26;;30586:9;30580:4;30576:20;30572:1;30561:9;30557:17;30550:47;30614:131;30740:4;30614:131;:::i;:::-;30606:139;;30333:419;;;:::o;30758:98::-;30809:6;30843:5;30837:12;30827:22;;30758:98;;;:::o;30862:168::-;30945:11;30979:6;30974:3;30967:19;31019:4;31014:3;31010:14;30995:29;;30862:168;;;;:::o;31036:360::-;31122:3;31150:38;31182:5;31150:38;:::i;:::-;31204:70;31267:6;31262:3;31204:70;:::i;:::-;31197:77;;31283:52;31328:6;31323:3;31316:4;31309:5;31305:16;31283:52;:::i;:::-;31360:29;31382:6;31360:29;:::i;:::-;31355:3;31351:39;31344:46;;31126:270;31036:360;;;;:::o;31402:640::-;31597:4;31635:3;31624:9;31620:19;31612:27;;31649:71;31717:1;31706:9;31702:17;31693:6;31649:71;:::i;:::-;31730:72;31798:2;31787:9;31783:18;31774:6;31730:72;:::i;:::-;31812;31880:2;31869:9;31865:18;31856:6;31812:72;:::i;:::-;31931:9;31925:4;31921:20;31916:2;31905:9;31901:18;31894:48;31959:76;32030:4;32021:6;31959:76;:::i;:::-;31951:84;;31402:640;;;;;;;:::o;32048:141::-;32104:5;32135:6;32129:13;32120:22;;32151:32;32177:5;32151:32;:::i;:::-;32048:141;;;;:::o;32195:349::-;32264:6;32313:2;32301:9;32292:7;32288:23;32284:32;32281:119;;;32319:79;;:::i;:::-;32281:119;32439:1;32464:63;32519:7;32510:6;32499:9;32495:22;32464:63;:::i;:::-;32454:73;;32410:127;32195:349;;;;:::o

Swarm Source

ipfs://65ce64c3b3747b9109eee4f6986ad817c57154b22b956028a5a44d6b27158adb
Loading...
Loading
Loading...
Loading
[ 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.