ETH Price: $3,376.71 (-1.96%)
Gas: 2 Gwei

Token

KillerChicks (KC)
 

Overview

Max Total Supply

1,322 KC

Holders

707

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
4 KC
0x41c9152a713ac2c48d650862b418a2cc767cebe2
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:
KillerChicks

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT
// File: operator-filter-registry/src/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

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

// File: operator-filter-registry/src/OperatorFilterer.sol


pragma solidity ^0.8.13;


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

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

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

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

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

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

// File: operator-filter-registry/src/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


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

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

// File: contracts/chicks.sol

//7599910339349013


// 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: contracts/witch.sol

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: contracts/witch.sol

pragma solidity ^0.8.4;

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

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

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

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

    /**
     * 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();

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol

// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * Returns the auxillary 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 auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        assembly {
            // Cast aux without masking.
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

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

    /**
     * @dev Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value)
        private
        pure
        returns (uint256 result)
    {
        assembly {
            result := value
        }
    }

    /**
     * @dev Casts the boolean to uint256 without branching.
     */
    function _boolToUint256(bool value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) virtual public override {
        address owner = address(uint160(_packedOwnershipOf(tokenId)));
        if (to == owner) revert ApprovalToCurrentOwner();

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

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

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

        return _tokenApprovals[tokenId];
    }

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

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator)
        public
        view
        virtual
        override
        returns (bool)
    {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

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

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

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

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _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] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.code.length != 0) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (
                        !_checkContractOnERC721Received(
                            address(0),
                            to,
                            updatedIndex++,
                            _data
                        )
                    ) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @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.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _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] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            getApproved(tokenId) == _msgSenderERC721A());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        delete _tokenApprovals[tokenId];

        // 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] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_NEXT_INITIALIZED;

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                getApproved(tokenId) == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        delete _tokenApprovals[tokenId];

        // 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] =
                _addressToUint256(from) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_BURNED |
                BITMASK_NEXT_INITIALIZED;

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

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

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

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

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

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

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

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol

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

pragma solidity ^0.8.0;

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol

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

pragma solidity ^0.8.0;

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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol

// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(
            address(this).balance >= amount,
            "Address: insufficient balance"
        );

        (bool success, ) = recipient.call{value: amount}("");
        require(
            success,
            "Address: unable to send value, recipient may have reverted"
        );
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data)
        internal
        returns (bytes memory)
    {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(
                target,
                data,
                value,
                "Address: low-level call with value failed"
            );
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(
            address(this).balance >= value,
            "Address: insufficient balance for call"
        );
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(
            data
        );
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data)
        internal
        view
        returns (bytes memory)
    {
        return
            functionStaticCall(
                target,
                data,
                "Address: low-level static call failed"
            );
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data)
        internal
        returns (bytes memory)
    {
        return
            functionDelegateCall(
                target,
                data,
                "Address: low-level delegate call failed"
            );
    }

    //1b0014041a0a15
    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol

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

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol

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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol

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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol

// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol

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

pragma solidity ^0.8.0;

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner)
        public
        view
        virtual
        override
        returns (uint256)
    {
        require(
            owner != address(0),
            "ERC721: address zero is not a valid owner"
        );
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        address owner = _owners[tokenId];
        require(
            owner != address(0),
            "ERC721: owner query for nonexistent token"
        );
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        string memory baseURI = _baseURI();
        return
            bytes(baseURI).length > 0
                ? string(abi.encodePacked(baseURI, tokenId.toString()))
                : "";
    }

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        require(
            _exists(tokenId),
            "ERC721: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator)
        public
        view
        virtual
        override
        returns (bool)
    {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public virtual override {
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(
            _checkOnERC721Received(from, to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId)
        internal
        view
        virtual
        returns (bool)
    {
        require(
            _exists(tokenId),
            "ERC721: operator query for nonexistent token"
        );
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner ||
            isApprovedForAll(owner, spender) ||
            getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId);
    }

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

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(
            ERC721.ownerOf(tokenId) == from,
            "ERC721: transfer from incorrect owner"
        );
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try
                IERC721Receiver(to).onERC721Received(
                    _msgSender(),
                    from,
                    tokenId,
                    data
                )
            returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert(
                        "ERC721: transfer to non ERC721Receiver implementer"
                    );
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}


pragma solidity ^0.8.0;

contract KillerChicks is ERC721A, Ownable, ReentrancyGuard ,DefaultOperatorFilterer{
    using Strings for uint256;

    string private baseURI;

    uint256 public maxPerWallet = 4;
    uint256 public price = 0.0068 ether;

    uint256 public maxFreePerWallet = 1;

    uint256 public maxSupply = 2222; 
    bool public mintEnabled = false;
    bool public publicEnabled = false;

    bytes32 ogRoot;
    bytes32 whitelistRoot;

    string public hiddenURI = "ipfs://bafybeihgbi72njlfhnzpaoqjjfj4agcd7bkfnfb5mab2bz7dyklso7efte/hidden.json";

    bool public revealed = false;

    mapping(address => bool) private _mintedFree;

    constructor() ERC721A("KillerChicks", "KC") {}

    function ogMint(bytes32[] calldata _merkleProof, uint256 count)
        external
        payable
        nonReentrant
    {
        bool isFreeLeft = !(_mintedFree[msg.sender]);
        bool isEqual = count == maxFreePerWallet;

        uint256 cost = price;

        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));

        if (isFreeLeft && isEqual) {
            cost = 0;
        }

        if (isFreeLeft && !isEqual) {
            require(
                msg.value >= (count - maxFreePerWallet) * cost,
                "Please send the exact amount."
            );
        } else {
            require(msg.value >= count * cost, "Please send the exact amount.");
        }
        require(
            MerkleProof.verify(_merkleProof, ogRoot, leaf),
            "Incorrect Whitelist Proof"
        );
        require(totalSupply() + count <= maxSupply, "No more");
        require(count > 0, "Please enter a number");
        require(mintEnabled, "Minting is not live yet");
        require(
            _numberMinted(msg.sender) + count <= maxPerWallet,
            "Can not mint more than 4"
        );

        _mintedFree[msg.sender] = true;

        _safeMint(msg.sender, count);
    }

    function whitelistMint(bytes32[] calldata _merkleProof, uint256 count)
        external
        payable
    {
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));

        require(
            MerkleProof.verify(_merkleProof, whitelistRoot, leaf),
            "Incorrect Whitelist Proof"
        );
        require(msg.value >= price * count, "Please send the exact amount.");
        require(
            _numberMinted(msg.sender) + count <= maxPerWallet,
            "You cant mint anymore"
        );
        require(totalSupply() + count <= maxSupply, "No more");
        require(mintEnabled, "Minting is not live yet");

        _safeMint(msg.sender, count);
    }

    function publicMint(uint256 count) external payable {
        require(msg.value >= count * price, "Please send the exact amount.");
        require(totalSupply() + count <= maxSupply, "No more NFT left");
        require(
            _numberMinted(msg.sender) + count <= maxPerWallet,
            "Can not mint more than 4"
        );
        require(count > 0, "Please enter a number");
        require(publicEnabled, "Minting is not live yet");

        _safeMint(msg.sender, count);
    }

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

    function _isMintedFree(address minter) external view returns (bool) {
        return _mintedFree[minter];
    }

    function _mintedAmount(address account) external view returns (uint256) {
        return _numberMinted(account);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721AMetadata: URI query for nonexistent token"
        );
        if (revealed == false) {
            return hiddenURI;
        }

        string memory currentBaseURI = _baseURI();
        return
            bytes(currentBaseURI).length > 0
                ? string(
                    abi.encodePacked(
                        currentBaseURI,
                        tokenId.toString(),
                        ".json"
                    )
                )
                : "";
    }

    function setPreSaleRoot(bytes32 _presaleRoot_1, bytes32 _presaleRoot_2)
        external
        onlyOwner
    {
        ogRoot = _presaleRoot_1;
        whitelistRoot = _presaleRoot_2;
    }

    // Only Owner Functions-----------
    function setBaseURI(string memory uri) public onlyOwner {
        baseURI = uri;
    }

    function setMaxPerWallet(uint256 amount) external onlyOwner {
        maxPerWallet = amount;
    }

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

    function setMaxSupply(uint256 _newSupply) external onlyOwner {
        maxSupply = _newSupply;
    }

    function flipWhitelist(bool status) external onlyOwner {
        mintEnabled = status;
    }

    function flipPublic(bool status) external onlyOwner {
        publicEnabled = status;
    }

    function reveal() external onlyOwner {
        revealed = !revealed;
    }

    function batchMint(uint256 _mintAmount, address destination)
        public
        onlyOwner
    {
        require(_mintAmount > 0, "need to mint at least 1 NFT");
        uint256 supply = totalSupply();
        require(supply + _mintAmount <= maxSupply, "max NFT limit exceeded");

        _safeMint(destination, _mintAmount);
    }

    function withdraw() external onlyOwner {
        (bool success, ) = payable(msg.sender).call{
            value: address(this).balance
        }("");
        require(success, "Transfer failed.");
    }
      function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"_isMintedFree","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"_mintedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"destination","type":"address"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"flipPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"flipWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hiddenURI","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":"maxFreePerWallet","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":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"ogMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","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":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_presaleRoot_1","type":"bytes32"},{"internalType":"bytes32","name":"_presaleRoot_2","type":"bytes32"}],"name":"setPreSaleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526004600b556618289060790000600c556001600d556108ae600e556000600f60006101000a81548160ff0219169083151502179055506000600f60016101000a81548160ff0219169083151502179055506040518060800160405280604e815260200162004e16604e9139601290805190602001906200008692919062000475565b506000601360006101000a81548160ff021916908315150217905550348015620000af57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600c81526020017f4b696c6c6572436869636b7300000000000000000000000000000000000000008152506040518060400160405280600281526020017f4b4300000000000000000000000000000000000000000000000000000000000081525081600290805190602001906200014b92919062000475565b5080600390805190602001906200016492919062000475565b5062000175620003a260201b60201c565b60008190555050506200019d62000191620003a760201b60201c565b620003af60201b60201c565b600160098190555060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200039a57801562000260576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620002269291906200056a565b600060405180830381600087803b1580156200024157600080fd5b505af115801562000256573d6000803e3d6000fd5b5050505062000399565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200031a576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620002e09291906200056a565b600060405180830381600087803b158015620002fb57600080fd5b505af115801562000310573d6000803e3d6000fd5b5050505062000398565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b815260040162000363919062000597565b600060405180830381600087803b1580156200037e57600080fd5b505af115801562000393573d6000803e3d6000fd5b505050505b5b5b505062000618565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8280546200048390620005e3565b90600052602060002090601f016020900481019282620004a75760008555620004f3565b82601f10620004c257805160ff1916838001178555620004f3565b82800160010185558215620004f3579182015b82811115620004f2578251825591602001919060010190620004d5565b5b50905062000502919062000506565b5090565b5b808211156200052157600081600090555060010162000507565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620005528262000525565b9050919050565b620005648162000545565b82525050565b600060408201905062000581600083018562000559565b62000590602083018462000559565b9392505050565b6000602082019050620005ae600083018462000559565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620005fc57607f821691505b602082108103620006125762000611620005b4565b5b50919050565b6147ee80620006286000396000f3fe6080604052600436106102465760003560e01c806377aeead911610139578063b88d4fde116100b6578063d5abeb011161007a578063d5abeb0114610819578063e268e4d314610844578063e985e9c51461086d578063ed64892b146108aa578063f2fde38b146108e7578063f55e7fc71461091057610246565b8063b88d4fde14610736578063bbb812791461075f578063c2f637dc14610788578063c87b56dd146107b1578063d1239730146107ee57610246565b80639b001f45116100fd5780639b001f4514610675578063a035b1fe146106a0578063a22cb465146106cb578063a475b5dd146106f4578063a70273571461070b57610246565b806377aeead9146105a25780638cc54e7f146105cb5780638da5cb5b146105f657806391b7f5ed1461062157806395d89b411461064a57610246565b806341f43434116101c75780636352211e1161018b5780636352211e146104cc5780636f8b44b01461050957806370a08231146105325780637116abf91461056f578063715018a61461058b57610246565b806341f43434146103f957806342842e0e14610424578063453c23101461044d578063518302271461047857806355f804b3146104a357610246565b806323b872dd1161020e57806323b872dd146103445780632810570f1461036d5780632904e6d9146103aa5780632db11544146103c65780633ccfd60b146103e257610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806318160ddd14610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613391565b610939565b60405161027f91906133d9565b60405180910390f35b34801561029457600080fd5b5061029d6109cb565b6040516102aa919061348d565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d591906134e5565b610a5d565b6040516102e79190613553565b60405180910390f35b3480156102fc57600080fd5b506103176004803603810190610312919061359a565b610ad9565b005b34801561032557600080fd5b5061032e610af2565b60405161033b91906135e9565b60405180910390f35b34801561035057600080fd5b5061036b60048036038101906103669190613604565b610b09565b005b34801561037957600080fd5b50610394600480360381019061038f9190613657565b610b58565b6040516103a191906133d9565b60405180910390f35b6103c460048036038101906103bf91906136e9565b610bae565b005b6103e060048036038101906103db91906134e5565b610dc4565b005b3480156103ee57600080fd5b506103f7610f62565b005b34801561040557600080fd5b5061040e61108d565b60405161041b91906137a8565b60405180910390f35b34801561043057600080fd5b5061044b60048036038101906104469190613604565b61109f565b005b34801561045957600080fd5b506104626110ee565b60405161046f91906135e9565b60405180910390f35b34801561048457600080fd5b5061048d6110f4565b60405161049a91906133d9565b60405180910390f35b3480156104af57600080fd5b506104ca60048036038101906104c591906138f3565b611107565b005b3480156104d857600080fd5b506104f360048036038101906104ee91906134e5565b61119d565b6040516105009190613553565b60405180910390f35b34801561051557600080fd5b50610530600480360381019061052b91906134e5565b6111af565b005b34801561053e57600080fd5b5061055960048036038101906105549190613657565b611235565b60405161056691906135e9565b60405180910390f35b610589600480360381019061058491906136e9565b6112ed565b005b34801561059757600080fd5b506105a06116db565b005b3480156105ae57600080fd5b506105c960048036038101906105c49190613972565b611763565b005b3480156105d757600080fd5b506105e06117f1565b6040516105ed919061348d565b60405180910390f35b34801561060257600080fd5b5061060b61187f565b6040516106189190613553565b60405180910390f35b34801561062d57600080fd5b50610648600480360381019061064391906134e5565b6118a9565b005b34801561065657600080fd5b5061065f61192f565b60405161066c919061348d565b60405180910390f35b34801561068157600080fd5b5061068a6119c1565b60405161069791906133d9565b60405180910390f35b3480156106ac57600080fd5b506106b56119d4565b6040516106c291906135e9565b60405180910390f35b3480156106d757600080fd5b506106f260048036038101906106ed91906139de565b6119da565b005b34801561070057600080fd5b506107096119f3565b005b34801561071757600080fd5b50610720611a9b565b60405161072d91906135e9565b60405180910390f35b34801561074257600080fd5b5061075d60048036038101906107589190613abf565b611aa1565b005b34801561076b57600080fd5b5061078660048036038101906107819190613b42565b611af2565b005b34801561079457600080fd5b506107af60048036038101906107aa9190613b6f565b611b8b565b005b3480156107bd57600080fd5b506107d860048036038101906107d391906134e5565b611cb5565b6040516107e5919061348d565b60405180910390f35b3480156107fa57600080fd5b50610803611e0a565b60405161081091906133d9565b60405180910390f35b34801561082557600080fd5b5061082e611e1d565b60405161083b91906135e9565b60405180910390f35b34801561085057600080fd5b5061086b600480360381019061086691906134e5565b611e23565b005b34801561087957600080fd5b50610894600480360381019061088f9190613baf565b611ea9565b6040516108a191906133d9565b60405180910390f35b3480156108b657600080fd5b506108d160048036038101906108cc9190613657565b611f3d565b6040516108de91906135e9565b60405180910390f35b3480156108f357600080fd5b5061090e60048036038101906109099190613657565b611f4f565b005b34801561091c57600080fd5b5061093760048036038101906109329190613b42565b612046565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061099457506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109c45750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546109da90613c1e565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0690613c1e565b8015610a535780601f10610a2857610100808354040283529160200191610a53565b820191906000526020600020905b815481529060010190602001808311610a3657829003601f168201915b5050505050905090565b6000610a68826120df565b610a9e576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610ae38161213e565b610aed838361223b565b505050565b6000610afc6123e1565b6001546000540303905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b4757610b463361213e565b5b610b528484846123e6565b50505050565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600033604051602001610bc19190613c97565b604051602081830303815290604052805190602001209050610c27848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601154836123f6565b610c66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5d90613cfe565b60405180910390fd5b81600c54610c749190613d4d565b341015610cb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cad90613df3565b60405180910390fd5b600b5482610cc33361240d565b610ccd9190613e13565b1115610d0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0590613eb5565b60405180910390fd5b600e5482610d1a610af2565b610d249190613e13565b1115610d65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5c90613f21565b60405180910390fd5b600f60009054906101000a900460ff16610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab90613f8d565b60405180910390fd5b610dbe3383612464565b50505050565b600c5481610dd29190613d4d565b341015610e14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0b90613df3565b60405180910390fd5b600e5481610e20610af2565b610e2a9190613e13565b1115610e6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6290613ff9565b60405180910390fd5b600b5481610e783361240d565b610e829190613e13565b1115610ec3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eba90614065565b60405180910390fd5b60008111610f06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efd906140d1565b60405180910390fd5b600f60019054906101000a900460ff16610f55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4c90613f8d565b60405180910390fd5b610f5f3382612464565b50565b610f6a612482565b73ffffffffffffffffffffffffffffffffffffffff16610f8861187f565b73ffffffffffffffffffffffffffffffffffffffff1614610fde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd59061413d565b60405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff16476040516110049061418e565b60006040518083038185875af1925050503d8060008114611041576040519150601f19603f3d011682016040523d82523d6000602084013e611046565b606091505b505090508061108a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611081906141ef565b60405180910390fd5b50565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146110dd576110dc3361213e565b5b6110e884848461248a565b50505050565b600b5481565b601360009054906101000a900460ff1681565b61110f612482565b73ffffffffffffffffffffffffffffffffffffffff1661112d61187f565b73ffffffffffffffffffffffffffffffffffffffff1614611183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117a9061413d565b60405180910390fd5b80600a9080519060200190611199929190613282565b5050565b60006111a8826124aa565b9050919050565b6111b7612482565b73ffffffffffffffffffffffffffffffffffffffff166111d561187f565b73ffffffffffffffffffffffffffffffffffffffff161461122b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112229061413d565b60405180910390fd5b80600e8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361129c576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b600260095403611332576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113299061425b565b60405180910390fd5b60026009819055506000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161590506000600d54831490506000600c5490506000336040516020016113af9190613c97565b6040516020818303038152906040528051906020012090508380156113d15750825b156113db57600091505b8380156113e6575082155b1561144b5781600d54866113fa919061427b565b6114049190613d4d565b341015611446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143d90613df3565b60405180910390fd5b61149a565b81856114579190613d4d565b341015611499576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149090613df3565b60405180910390fd5b5b6114e8878780806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601054836123f6565b611527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151e90613cfe565b60405180910390fd5b600e5485611533610af2565b61153d9190613e13565b111561157e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157590613f21565b60405180910390fd5b600085116115c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b8906140d1565b60405180910390fd5b600f60009054906101000a900460ff16611610576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160790613f8d565b60405180910390fd5b600b548561161d3361240d565b6116279190613e13565b1115611668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165f90614065565b60405180910390fd5b6001601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506116ca3386612464565b505050506001600981905550505050565b6116e3612482565b73ffffffffffffffffffffffffffffffffffffffff1661170161187f565b73ffffffffffffffffffffffffffffffffffffffff1614611757576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174e9061413d565b60405180910390fd5b6117616000612576565b565b61176b612482565b73ffffffffffffffffffffffffffffffffffffffff1661178961187f565b73ffffffffffffffffffffffffffffffffffffffff16146117df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d69061413d565b60405180910390fd5b81601081905550806011819055505050565b601280546117fe90613c1e565b80601f016020809104026020016040519081016040528092919081815260200182805461182a90613c1e565b80156118775780601f1061184c57610100808354040283529160200191611877565b820191906000526020600020905b81548152906001019060200180831161185a57829003601f168201915b505050505081565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6118b1612482565b73ffffffffffffffffffffffffffffffffffffffff166118cf61187f565b73ffffffffffffffffffffffffffffffffffffffff1614611925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191c9061413d565b60405180910390fd5b80600c8190555050565b60606003805461193e90613c1e565b80601f016020809104026020016040519081016040528092919081815260200182805461196a90613c1e565b80156119b75780601f1061198c576101008083540402835291602001916119b7565b820191906000526020600020905b81548152906001019060200180831161199a57829003601f168201915b5050505050905090565b600f60019054906101000a900460ff1681565b600c5481565b816119e48161213e565b6119ee838361263c565b505050565b6119fb612482565b73ffffffffffffffffffffffffffffffffffffffff16611a1961187f565b73ffffffffffffffffffffffffffffffffffffffff1614611a6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a669061413d565b60405180910390fd5b601360009054906101000a900460ff1615601360006101000a81548160ff021916908315150217905550565b600d5481565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611adf57611ade3361213e565b5b611aeb858585856127b3565b5050505050565b611afa612482565b73ffffffffffffffffffffffffffffffffffffffff16611b1861187f565b73ffffffffffffffffffffffffffffffffffffffff1614611b6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b659061413d565b60405180910390fd5b80600f60006101000a81548160ff02191690831515021790555050565b611b93612482565b73ffffffffffffffffffffffffffffffffffffffff16611bb161187f565b73ffffffffffffffffffffffffffffffffffffffff1614611c07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfe9061413d565b60405180910390fd5b60008211611c4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c41906142fb565b60405180910390fd5b6000611c54610af2565b9050600e548382611c659190613e13565b1115611ca6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9d90614367565b60405180910390fd5b611cb08284612464565b505050565b6060611cc0826120df565b611cff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf6906143f9565b60405180910390fd5b60001515601360009054906101000a900460ff16151503611dac5760128054611d2790613c1e565b80601f0160208091040260200160405190810160405280929190818152602001828054611d5390613c1e565b8015611da05780601f10611d7557610100808354040283529160200191611da0565b820191906000526020600020905b815481529060010190602001808311611d8357829003601f168201915b50505050509050611e05565b6000611db6612826565b90506000815111611dd65760405180602001604052806000815250611e01565b80611de0846128b8565b604051602001611df19291906144a1565b6040516020818303038152906040525b9150505b919050565b600f60009054906101000a900460ff1681565b600e5481565b611e2b612482565b73ffffffffffffffffffffffffffffffffffffffff16611e4961187f565b73ffffffffffffffffffffffffffffffffffffffff1614611e9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e969061413d565b60405180910390fd5b80600b8190555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000611f488261240d565b9050919050565b611f57612482565b73ffffffffffffffffffffffffffffffffffffffff16611f7561187f565b73ffffffffffffffffffffffffffffffffffffffff1614611fcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc29061413d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361203a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203190614542565b60405180910390fd5b61204381612576565b50565b61204e612482565b73ffffffffffffffffffffffffffffffffffffffff1661206c61187f565b73ffffffffffffffffffffffffffffffffffffffff16146120c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b99061413d565b60405180910390fd5b80600f60016101000a81548160ff02191690831515021790555050565b6000816120ea6123e1565b111580156120f9575060005482105b8015612137575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612238576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016121b5929190614562565b602060405180830381865afa1580156121d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f691906145a0565b61223757806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161222e9190613553565b60405180910390fd5b5b50565b6000612246826124aa565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122ad576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166122cc612a18565b73ffffffffffffffffffffffffffffffffffffffff161461232f576122f8816122f3612a18565b611ea9565b61232e576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b6123f1838383612a20565b505050565b6000826124038584612dc7565b1490509392505050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b61247e828260405180602001604052806000815250612e1d565b5050565b600033905090565b6124a583838360405180602001604052806000815250611aa1565b505050565b600080829050806124b96123e1565b1161253f5760005481101561253e5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361253c575b60008103612532576004600083600190039350838152602001908152602001600020549050612508565b8092505050612571565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612644612a18565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126a8576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006126b5612a18565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612762612a18565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516127a791906133d9565b60405180910390a35050565b6127be848484612a20565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612820576127e9848484846130d0565b61281f576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060600a805461283590613c1e565b80601f016020809104026020016040519081016040528092919081815260200182805461286190613c1e565b80156128ae5780601f10612883576101008083540402835291602001916128ae565b820191906000526020600020905b81548152906001019060200180831161289157829003601f168201915b5050505050905090565b6060600082036128ff576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612a13565b600082905060005b6000821461293157808061291a906145cd565b915050600a8261292a9190614644565b9150612907565b60008167ffffffffffffffff81111561294d5761294c6137c8565b5b6040519080825280601f01601f19166020018201604052801561297f5781602001600182028036833780820191505090505b5090505b60008514612a0c57600182612998919061427b565b9150600a856129a79190614675565b60306129b39190613e13565b60f81b8183815181106129c9576129c86146a6565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612a059190614644565b9450612983565b8093505050505b919050565b600033905090565b6000612a2b826124aa565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612a92576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16612ab3612a18565b73ffffffffffffffffffffffffffffffffffffffff161480612ae25750612ae185612adc612a18565b611ea9565b5b80612b275750612af0612a18565b73ffffffffffffffffffffffffffffffffffffffff16612b0f84610a5d565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612b60576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612bc6576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612bd38585856001613220565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b612cd086613226565b1717600460008581526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000831603612d585760006001840190506000600460008381526020019081526020016000205403612d56576000548114612d55578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612dc08585856001613230565b5050505050565b60008082905060005b8451811015612e1257612dfd82868381518110612df057612def6146a6565b5b6020026020010151613236565b91508080612e0a906145cd565b915050612dd0565b508091505092915050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612e89576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303612ec3576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ed06000858386613220565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e1612f3560018514613261565b901b60a042901b612f4586613226565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14613049575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ff960008784806001019550876130d0565b61302f576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808210612f8a57826000541461304457600080fd5b6130b4565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821061304a575b8160008190555050506130ca6000858386613230565b50505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026130f6612a18565b8786866040518563ffffffff1660e01b8152600401613118949392919061472a565b6020604051808303816000875af192505050801561315457506040513d601f19601f82011682018060405250810190613151919061478b565b60015b6131cd573d8060008114613184576040519150601f19603f3d011682016040523d82523d6000602084013e613189565b606091505b5060008151036131c5576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b50505050565b6000819050919050565b50505050565b600081831061324e57613249828461326b565b613259565b613258838361326b565b5b905092915050565b6000819050919050565b600082600052816020526040600020905092915050565b82805461328e90613c1e565b90600052602060002090601f0160209004810192826132b057600085556132f7565b82601f106132c957805160ff19168380011785556132f7565b828001600101855582156132f7579182015b828111156132f65782518255916020019190600101906132db565b5b5090506133049190613308565b5090565b5b80821115613321576000816000905550600101613309565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61336e81613339565b811461337957600080fd5b50565b60008135905061338b81613365565b92915050565b6000602082840312156133a7576133a661332f565b5b60006133b58482850161337c565b91505092915050565b60008115159050919050565b6133d3816133be565b82525050565b60006020820190506133ee60008301846133ca565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561342e578082015181840152602081019050613413565b8381111561343d576000848401525b50505050565b6000601f19601f8301169050919050565b600061345f826133f4565b61346981856133ff565b9350613479818560208601613410565b61348281613443565b840191505092915050565b600060208201905081810360008301526134a78184613454565b905092915050565b6000819050919050565b6134c2816134af565b81146134cd57600080fd5b50565b6000813590506134df816134b9565b92915050565b6000602082840312156134fb576134fa61332f565b5b6000613509848285016134d0565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061353d82613512565b9050919050565b61354d81613532565b82525050565b60006020820190506135686000830184613544565b92915050565b61357781613532565b811461358257600080fd5b50565b6000813590506135948161356e565b92915050565b600080604083850312156135b1576135b061332f565b5b60006135bf85828601613585565b92505060206135d0858286016134d0565b9150509250929050565b6135e3816134af565b82525050565b60006020820190506135fe60008301846135da565b92915050565b60008060006060848603121561361d5761361c61332f565b5b600061362b86828701613585565b935050602061363c86828701613585565b925050604061364d868287016134d0565b9150509250925092565b60006020828403121561366d5761366c61332f565b5b600061367b84828501613585565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126136a9576136a8613684565b5b8235905067ffffffffffffffff8111156136c6576136c5613689565b5b6020830191508360208202830111156136e2576136e161368e565b5b9250929050565b6000806000604084860312156137025761370161332f565b5b600084013567ffffffffffffffff8111156137205761371f613334565b5b61372c86828701613693565b9350935050602061373f868287016134d0565b9150509250925092565b6000819050919050565b600061376e61376961376484613512565b613749565b613512565b9050919050565b600061378082613753565b9050919050565b600061379282613775565b9050919050565b6137a281613787565b82525050565b60006020820190506137bd6000830184613799565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61380082613443565b810181811067ffffffffffffffff8211171561381f5761381e6137c8565b5b80604052505050565b6000613832613325565b905061383e82826137f7565b919050565b600067ffffffffffffffff82111561385e5761385d6137c8565b5b61386782613443565b9050602081019050919050565b82818337600083830152505050565b600061389661389184613843565b613828565b9050828152602081018484840111156138b2576138b16137c3565b5b6138bd848285613874565b509392505050565b600082601f8301126138da576138d9613684565b5b81356138ea848260208601613883565b91505092915050565b6000602082840312156139095761390861332f565b5b600082013567ffffffffffffffff81111561392757613926613334565b5b613933848285016138c5565b91505092915050565b6000819050919050565b61394f8161393c565b811461395a57600080fd5b50565b60008135905061396c81613946565b92915050565b600080604083850312156139895761398861332f565b5b60006139978582860161395d565b92505060206139a88582860161395d565b9150509250929050565b6139bb816133be565b81146139c657600080fd5b50565b6000813590506139d8816139b2565b92915050565b600080604083850312156139f5576139f461332f565b5b6000613a0385828601613585565b9250506020613a14858286016139c9565b9150509250929050565b600067ffffffffffffffff821115613a3957613a386137c8565b5b613a4282613443565b9050602081019050919050565b6000613a62613a5d84613a1e565b613828565b905082815260208101848484011115613a7e57613a7d6137c3565b5b613a89848285613874565b509392505050565b600082601f830112613aa657613aa5613684565b5b8135613ab6848260208601613a4f565b91505092915050565b60008060008060808587031215613ad957613ad861332f565b5b6000613ae787828801613585565b9450506020613af887828801613585565b9350506040613b09878288016134d0565b925050606085013567ffffffffffffffff811115613b2a57613b29613334565b5b613b3687828801613a91565b91505092959194509250565b600060208284031215613b5857613b5761332f565b5b6000613b66848285016139c9565b91505092915050565b60008060408385031215613b8657613b8561332f565b5b6000613b94858286016134d0565b9250506020613ba585828601613585565b9150509250929050565b60008060408385031215613bc657613bc561332f565b5b6000613bd485828601613585565b9250506020613be585828601613585565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613c3657607f821691505b602082108103613c4957613c48613bef565b5b50919050565b60008160601b9050919050565b6000613c6782613c4f565b9050919050565b6000613c7982613c5c565b9050919050565b613c91613c8c82613532565b613c6e565b82525050565b6000613ca38284613c80565b60148201915081905092915050565b7f496e636f72726563742057686974656c6973742050726f6f6600000000000000600082015250565b6000613ce86019836133ff565b9150613cf382613cb2565b602082019050919050565b60006020820190508181036000830152613d1781613cdb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613d58826134af565b9150613d63836134af565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613d9c57613d9b613d1e565b5b828202905092915050565b7f506c656173652073656e642074686520657861637420616d6f756e742e000000600082015250565b6000613ddd601d836133ff565b9150613de882613da7565b602082019050919050565b60006020820190508181036000830152613e0c81613dd0565b9050919050565b6000613e1e826134af565b9150613e29836134af565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613e5e57613e5d613d1e565b5b828201905092915050565b7f596f752063616e74206d696e7420616e796d6f72650000000000000000000000600082015250565b6000613e9f6015836133ff565b9150613eaa82613e69565b602082019050919050565b60006020820190508181036000830152613ece81613e92565b9050919050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000613f0b6007836133ff565b9150613f1682613ed5565b602082019050919050565b60006020820190508181036000830152613f3a81613efe565b9050919050565b7f4d696e74696e67206973206e6f74206c69766520796574000000000000000000600082015250565b6000613f776017836133ff565b9150613f8282613f41565b602082019050919050565b60006020820190508181036000830152613fa681613f6a565b9050919050565b7f4e6f206d6f7265204e4654206c65667400000000000000000000000000000000600082015250565b6000613fe36010836133ff565b9150613fee82613fad565b602082019050919050565b6000602082019050818103600083015261401281613fd6565b9050919050565b7f43616e206e6f74206d696e74206d6f7265207468616e20340000000000000000600082015250565b600061404f6018836133ff565b915061405a82614019565b602082019050919050565b6000602082019050818103600083015261407e81614042565b9050919050565b7f506c6561736520656e7465722061206e756d6265720000000000000000000000600082015250565b60006140bb6015836133ff565b91506140c682614085565b602082019050919050565b600060208201905081810360008301526140ea816140ae565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006141276020836133ff565b9150614132826140f1565b602082019050919050565b600060208201905081810360008301526141568161411a565b9050919050565b600081905092915050565b50565b600061417860008361415d565b915061418382614168565b600082019050919050565b60006141998261416b565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006141d96010836133ff565b91506141e4826141a3565b602082019050919050565b60006020820190508181036000830152614208816141cc565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614245601f836133ff565b91506142508261420f565b602082019050919050565b6000602082019050818103600083015261427481614238565b9050919050565b6000614286826134af565b9150614291836134af565b9250828210156142a4576142a3613d1e565b5b828203905092915050565b7f6e65656420746f206d696e74206174206c656173742031204e46540000000000600082015250565b60006142e5601b836133ff565b91506142f0826142af565b602082019050919050565b60006020820190508181036000830152614314816142d8565b9050919050565b7f6d6178204e4654206c696d697420657863656564656400000000000000000000600082015250565b60006143516016836133ff565b915061435c8261431b565b602082019050919050565b6000602082019050818103600083015261438081614344565b9050919050565b7f455243373231414d657461646174613a2055524920717565727920666f72206e60008201527f6f6e6578697374656e7420746f6b656e00000000000000000000000000000000602082015250565b60006143e36030836133ff565b91506143ee82614387565b604082019050919050565b60006020820190508181036000830152614412816143d6565b9050919050565b600081905092915050565b600061442f826133f4565b6144398185614419565b9350614449818560208601613410565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061448b600583614419565b915061449682614455565b600582019050919050565b60006144ad8285614424565b91506144b98284614424565b91506144c48261447e565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061452c6026836133ff565b9150614537826144d0565b604082019050919050565b6000602082019050818103600083015261455b8161451f565b9050919050565b60006040820190506145776000830185613544565b6145846020830184613544565b9392505050565b60008151905061459a816139b2565b92915050565b6000602082840312156145b6576145b561332f565b5b60006145c48482850161458b565b91505092915050565b60006145d8826134af565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361460a57614609613d1e565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061464f826134af565b915061465a836134af565b92508261466a57614669614615565b5b828204905092915050565b6000614680826134af565b915061468b836134af565b92508261469b5761469a614615565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60006146fc826146d5565b61470681856146e0565b9350614716818560208601613410565b61471f81613443565b840191505092915050565b600060808201905061473f6000830187613544565b61474c6020830186613544565b61475960408301856135da565b818103606083015261476b81846146f1565b905095945050505050565b60008151905061478581613365565b92915050565b6000602082840312156147a1576147a061332f565b5b60006147af84828501614776565b9150509291505056fea26469706673582212203aad9c0ef44c3c504cef82023070aef85de9848021d061acf73ddcde1a8163b564736f6c634300080d0033697066733a2f2f626166796265696867626937326e6a6c66686e7a70616f716a6a666a346167636437626b666e6662356d616232627a3764796b6c736f37656674652f68696464656e2e6a736f6e

Deployed Bytecode

0x6080604052600436106102465760003560e01c806377aeead911610139578063b88d4fde116100b6578063d5abeb011161007a578063d5abeb0114610819578063e268e4d314610844578063e985e9c51461086d578063ed64892b146108aa578063f2fde38b146108e7578063f55e7fc71461091057610246565b8063b88d4fde14610736578063bbb812791461075f578063c2f637dc14610788578063c87b56dd146107b1578063d1239730146107ee57610246565b80639b001f45116100fd5780639b001f4514610675578063a035b1fe146106a0578063a22cb465146106cb578063a475b5dd146106f4578063a70273571461070b57610246565b806377aeead9146105a25780638cc54e7f146105cb5780638da5cb5b146105f657806391b7f5ed1461062157806395d89b411461064a57610246565b806341f43434116101c75780636352211e1161018b5780636352211e146104cc5780636f8b44b01461050957806370a08231146105325780637116abf91461056f578063715018a61461058b57610246565b806341f43434146103f957806342842e0e14610424578063453c23101461044d578063518302271461047857806355f804b3146104a357610246565b806323b872dd1161020e57806323b872dd146103445780632810570f1461036d5780632904e6d9146103aa5780632db11544146103c65780633ccfd60b146103e257610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806318160ddd14610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613391565b610939565b60405161027f91906133d9565b60405180910390f35b34801561029457600080fd5b5061029d6109cb565b6040516102aa919061348d565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d591906134e5565b610a5d565b6040516102e79190613553565b60405180910390f35b3480156102fc57600080fd5b506103176004803603810190610312919061359a565b610ad9565b005b34801561032557600080fd5b5061032e610af2565b60405161033b91906135e9565b60405180910390f35b34801561035057600080fd5b5061036b60048036038101906103669190613604565b610b09565b005b34801561037957600080fd5b50610394600480360381019061038f9190613657565b610b58565b6040516103a191906133d9565b60405180910390f35b6103c460048036038101906103bf91906136e9565b610bae565b005b6103e060048036038101906103db91906134e5565b610dc4565b005b3480156103ee57600080fd5b506103f7610f62565b005b34801561040557600080fd5b5061040e61108d565b60405161041b91906137a8565b60405180910390f35b34801561043057600080fd5b5061044b60048036038101906104469190613604565b61109f565b005b34801561045957600080fd5b506104626110ee565b60405161046f91906135e9565b60405180910390f35b34801561048457600080fd5b5061048d6110f4565b60405161049a91906133d9565b60405180910390f35b3480156104af57600080fd5b506104ca60048036038101906104c591906138f3565b611107565b005b3480156104d857600080fd5b506104f360048036038101906104ee91906134e5565b61119d565b6040516105009190613553565b60405180910390f35b34801561051557600080fd5b50610530600480360381019061052b91906134e5565b6111af565b005b34801561053e57600080fd5b5061055960048036038101906105549190613657565b611235565b60405161056691906135e9565b60405180910390f35b610589600480360381019061058491906136e9565b6112ed565b005b34801561059757600080fd5b506105a06116db565b005b3480156105ae57600080fd5b506105c960048036038101906105c49190613972565b611763565b005b3480156105d757600080fd5b506105e06117f1565b6040516105ed919061348d565b60405180910390f35b34801561060257600080fd5b5061060b61187f565b6040516106189190613553565b60405180910390f35b34801561062d57600080fd5b50610648600480360381019061064391906134e5565b6118a9565b005b34801561065657600080fd5b5061065f61192f565b60405161066c919061348d565b60405180910390f35b34801561068157600080fd5b5061068a6119c1565b60405161069791906133d9565b60405180910390f35b3480156106ac57600080fd5b506106b56119d4565b6040516106c291906135e9565b60405180910390f35b3480156106d757600080fd5b506106f260048036038101906106ed91906139de565b6119da565b005b34801561070057600080fd5b506107096119f3565b005b34801561071757600080fd5b50610720611a9b565b60405161072d91906135e9565b60405180910390f35b34801561074257600080fd5b5061075d60048036038101906107589190613abf565b611aa1565b005b34801561076b57600080fd5b5061078660048036038101906107819190613b42565b611af2565b005b34801561079457600080fd5b506107af60048036038101906107aa9190613b6f565b611b8b565b005b3480156107bd57600080fd5b506107d860048036038101906107d391906134e5565b611cb5565b6040516107e5919061348d565b60405180910390f35b3480156107fa57600080fd5b50610803611e0a565b60405161081091906133d9565b60405180910390f35b34801561082557600080fd5b5061082e611e1d565b60405161083b91906135e9565b60405180910390f35b34801561085057600080fd5b5061086b600480360381019061086691906134e5565b611e23565b005b34801561087957600080fd5b50610894600480360381019061088f9190613baf565b611ea9565b6040516108a191906133d9565b60405180910390f35b3480156108b657600080fd5b506108d160048036038101906108cc9190613657565b611f3d565b6040516108de91906135e9565b60405180910390f35b3480156108f357600080fd5b5061090e60048036038101906109099190613657565b611f4f565b005b34801561091c57600080fd5b5061093760048036038101906109329190613b42565b612046565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061099457506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109c45750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546109da90613c1e565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0690613c1e565b8015610a535780601f10610a2857610100808354040283529160200191610a53565b820191906000526020600020905b815481529060010190602001808311610a3657829003601f168201915b5050505050905090565b6000610a68826120df565b610a9e576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610ae38161213e565b610aed838361223b565b505050565b6000610afc6123e1565b6001546000540303905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b4757610b463361213e565b5b610b528484846123e6565b50505050565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600033604051602001610bc19190613c97565b604051602081830303815290604052805190602001209050610c27848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601154836123f6565b610c66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5d90613cfe565b60405180910390fd5b81600c54610c749190613d4d565b341015610cb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cad90613df3565b60405180910390fd5b600b5482610cc33361240d565b610ccd9190613e13565b1115610d0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0590613eb5565b60405180910390fd5b600e5482610d1a610af2565b610d249190613e13565b1115610d65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5c90613f21565b60405180910390fd5b600f60009054906101000a900460ff16610db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dab90613f8d565b60405180910390fd5b610dbe3383612464565b50505050565b600c5481610dd29190613d4d565b341015610e14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0b90613df3565b60405180910390fd5b600e5481610e20610af2565b610e2a9190613e13565b1115610e6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6290613ff9565b60405180910390fd5b600b5481610e783361240d565b610e829190613e13565b1115610ec3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eba90614065565b60405180910390fd5b60008111610f06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efd906140d1565b60405180910390fd5b600f60019054906101000a900460ff16610f55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4c90613f8d565b60405180910390fd5b610f5f3382612464565b50565b610f6a612482565b73ffffffffffffffffffffffffffffffffffffffff16610f8861187f565b73ffffffffffffffffffffffffffffffffffffffff1614610fde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd59061413d565b60405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff16476040516110049061418e565b60006040518083038185875af1925050503d8060008114611041576040519150601f19603f3d011682016040523d82523d6000602084013e611046565b606091505b505090508061108a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611081906141ef565b60405180910390fd5b50565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146110dd576110dc3361213e565b5b6110e884848461248a565b50505050565b600b5481565b601360009054906101000a900460ff1681565b61110f612482565b73ffffffffffffffffffffffffffffffffffffffff1661112d61187f565b73ffffffffffffffffffffffffffffffffffffffff1614611183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117a9061413d565b60405180910390fd5b80600a9080519060200190611199929190613282565b5050565b60006111a8826124aa565b9050919050565b6111b7612482565b73ffffffffffffffffffffffffffffffffffffffff166111d561187f565b73ffffffffffffffffffffffffffffffffffffffff161461122b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112229061413d565b60405180910390fd5b80600e8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361129c576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b600260095403611332576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113299061425b565b60405180910390fd5b60026009819055506000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161590506000600d54831490506000600c5490506000336040516020016113af9190613c97565b6040516020818303038152906040528051906020012090508380156113d15750825b156113db57600091505b8380156113e6575082155b1561144b5781600d54866113fa919061427b565b6114049190613d4d565b341015611446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143d90613df3565b60405180910390fd5b61149a565b81856114579190613d4d565b341015611499576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149090613df3565b60405180910390fd5b5b6114e8878780806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601054836123f6565b611527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151e90613cfe565b60405180910390fd5b600e5485611533610af2565b61153d9190613e13565b111561157e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157590613f21565b60405180910390fd5b600085116115c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b8906140d1565b60405180910390fd5b600f60009054906101000a900460ff16611610576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160790613f8d565b60405180910390fd5b600b548561161d3361240d565b6116279190613e13565b1115611668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165f90614065565b60405180910390fd5b6001601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506116ca3386612464565b505050506001600981905550505050565b6116e3612482565b73ffffffffffffffffffffffffffffffffffffffff1661170161187f565b73ffffffffffffffffffffffffffffffffffffffff1614611757576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174e9061413d565b60405180910390fd5b6117616000612576565b565b61176b612482565b73ffffffffffffffffffffffffffffffffffffffff1661178961187f565b73ffffffffffffffffffffffffffffffffffffffff16146117df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d69061413d565b60405180910390fd5b81601081905550806011819055505050565b601280546117fe90613c1e565b80601f016020809104026020016040519081016040528092919081815260200182805461182a90613c1e565b80156118775780601f1061184c57610100808354040283529160200191611877565b820191906000526020600020905b81548152906001019060200180831161185a57829003601f168201915b505050505081565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6118b1612482565b73ffffffffffffffffffffffffffffffffffffffff166118cf61187f565b73ffffffffffffffffffffffffffffffffffffffff1614611925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191c9061413d565b60405180910390fd5b80600c8190555050565b60606003805461193e90613c1e565b80601f016020809104026020016040519081016040528092919081815260200182805461196a90613c1e565b80156119b75780601f1061198c576101008083540402835291602001916119b7565b820191906000526020600020905b81548152906001019060200180831161199a57829003601f168201915b5050505050905090565b600f60019054906101000a900460ff1681565b600c5481565b816119e48161213e565b6119ee838361263c565b505050565b6119fb612482565b73ffffffffffffffffffffffffffffffffffffffff16611a1961187f565b73ffffffffffffffffffffffffffffffffffffffff1614611a6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a669061413d565b60405180910390fd5b601360009054906101000a900460ff1615601360006101000a81548160ff021916908315150217905550565b600d5481565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611adf57611ade3361213e565b5b611aeb858585856127b3565b5050505050565b611afa612482565b73ffffffffffffffffffffffffffffffffffffffff16611b1861187f565b73ffffffffffffffffffffffffffffffffffffffff1614611b6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b659061413d565b60405180910390fd5b80600f60006101000a81548160ff02191690831515021790555050565b611b93612482565b73ffffffffffffffffffffffffffffffffffffffff16611bb161187f565b73ffffffffffffffffffffffffffffffffffffffff1614611c07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfe9061413d565b60405180910390fd5b60008211611c4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c41906142fb565b60405180910390fd5b6000611c54610af2565b9050600e548382611c659190613e13565b1115611ca6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9d90614367565b60405180910390fd5b611cb08284612464565b505050565b6060611cc0826120df565b611cff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf6906143f9565b60405180910390fd5b60001515601360009054906101000a900460ff16151503611dac5760128054611d2790613c1e565b80601f0160208091040260200160405190810160405280929190818152602001828054611d5390613c1e565b8015611da05780601f10611d7557610100808354040283529160200191611da0565b820191906000526020600020905b815481529060010190602001808311611d8357829003601f168201915b50505050509050611e05565b6000611db6612826565b90506000815111611dd65760405180602001604052806000815250611e01565b80611de0846128b8565b604051602001611df19291906144a1565b6040516020818303038152906040525b9150505b919050565b600f60009054906101000a900460ff1681565b600e5481565b611e2b612482565b73ffffffffffffffffffffffffffffffffffffffff16611e4961187f565b73ffffffffffffffffffffffffffffffffffffffff1614611e9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e969061413d565b60405180910390fd5b80600b8190555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000611f488261240d565b9050919050565b611f57612482565b73ffffffffffffffffffffffffffffffffffffffff16611f7561187f565b73ffffffffffffffffffffffffffffffffffffffff1614611fcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc29061413d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361203a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203190614542565b60405180910390fd5b61204381612576565b50565b61204e612482565b73ffffffffffffffffffffffffffffffffffffffff1661206c61187f565b73ffffffffffffffffffffffffffffffffffffffff16146120c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b99061413d565b60405180910390fd5b80600f60016101000a81548160ff02191690831515021790555050565b6000816120ea6123e1565b111580156120f9575060005482105b8015612137575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612238576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016121b5929190614562565b602060405180830381865afa1580156121d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f691906145a0565b61223757806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161222e9190613553565b60405180910390fd5b5b50565b6000612246826124aa565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122ad576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166122cc612a18565b73ffffffffffffffffffffffffffffffffffffffff161461232f576122f8816122f3612a18565b611ea9565b61232e576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b6123f1838383612a20565b505050565b6000826124038584612dc7565b1490509392505050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b61247e828260405180602001604052806000815250612e1d565b5050565b600033905090565b6124a583838360405180602001604052806000815250611aa1565b505050565b600080829050806124b96123e1565b1161253f5760005481101561253e5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361253c575b60008103612532576004600083600190039350838152602001908152602001600020549050612508565b8092505050612571565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612644612a18565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126a8576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006126b5612a18565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612762612a18565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516127a791906133d9565b60405180910390a35050565b6127be848484612a20565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612820576127e9848484846130d0565b61281f576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060600a805461283590613c1e565b80601f016020809104026020016040519081016040528092919081815260200182805461286190613c1e565b80156128ae5780601f10612883576101008083540402835291602001916128ae565b820191906000526020600020905b81548152906001019060200180831161289157829003601f168201915b5050505050905090565b6060600082036128ff576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612a13565b600082905060005b6000821461293157808061291a906145cd565b915050600a8261292a9190614644565b9150612907565b60008167ffffffffffffffff81111561294d5761294c6137c8565b5b6040519080825280601f01601f19166020018201604052801561297f5781602001600182028036833780820191505090505b5090505b60008514612a0c57600182612998919061427b565b9150600a856129a79190614675565b60306129b39190613e13565b60f81b8183815181106129c9576129c86146a6565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612a059190614644565b9450612983565b8093505050505b919050565b600033905090565b6000612a2b826124aa565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612a92576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16612ab3612a18565b73ffffffffffffffffffffffffffffffffffffffff161480612ae25750612ae185612adc612a18565b611ea9565b5b80612b275750612af0612a18565b73ffffffffffffffffffffffffffffffffffffffff16612b0f84610a5d565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612b60576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612bc6576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612bd38585856001613220565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b612cd086613226565b1717600460008581526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000831603612d585760006001840190506000600460008381526020019081526020016000205403612d56576000548114612d55578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612dc08585856001613230565b5050505050565b60008082905060005b8451811015612e1257612dfd82868381518110612df057612def6146a6565b5b6020026020010151613236565b91508080612e0a906145cd565b915050612dd0565b508091505092915050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612e89576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303612ec3576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ed06000858386613220565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e1612f3560018514613261565b901b60a042901b612f4586613226565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14613049575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ff960008784806001019550876130d0565b61302f576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808210612f8a57826000541461304457600080fd5b6130b4565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821061304a575b8160008190555050506130ca6000858386613230565b50505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026130f6612a18565b8786866040518563ffffffff1660e01b8152600401613118949392919061472a565b6020604051808303816000875af192505050801561315457506040513d601f19601f82011682018060405250810190613151919061478b565b60015b6131cd573d8060008114613184576040519150601f19603f3d011682016040523d82523d6000602084013e613189565b606091505b5060008151036131c5576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b50505050565b6000819050919050565b50505050565b600081831061324e57613249828461326b565b613259565b613258838361326b565b5b905092915050565b6000819050919050565b600082600052816020526040600020905092915050565b82805461328e90613c1e565b90600052602060002090601f0160209004810192826132b057600085556132f7565b82601f106132c957805160ff19168380011785556132f7565b828001600101855582156132f7579182015b828111156132f65782518255916020019190600101906132db565b5b5090506133049190613308565b5090565b5b80821115613321576000816000905550600101613309565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61336e81613339565b811461337957600080fd5b50565b60008135905061338b81613365565b92915050565b6000602082840312156133a7576133a661332f565b5b60006133b58482850161337c565b91505092915050565b60008115159050919050565b6133d3816133be565b82525050565b60006020820190506133ee60008301846133ca565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561342e578082015181840152602081019050613413565b8381111561343d576000848401525b50505050565b6000601f19601f8301169050919050565b600061345f826133f4565b61346981856133ff565b9350613479818560208601613410565b61348281613443565b840191505092915050565b600060208201905081810360008301526134a78184613454565b905092915050565b6000819050919050565b6134c2816134af565b81146134cd57600080fd5b50565b6000813590506134df816134b9565b92915050565b6000602082840312156134fb576134fa61332f565b5b6000613509848285016134d0565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061353d82613512565b9050919050565b61354d81613532565b82525050565b60006020820190506135686000830184613544565b92915050565b61357781613532565b811461358257600080fd5b50565b6000813590506135948161356e565b92915050565b600080604083850312156135b1576135b061332f565b5b60006135bf85828601613585565b92505060206135d0858286016134d0565b9150509250929050565b6135e3816134af565b82525050565b60006020820190506135fe60008301846135da565b92915050565b60008060006060848603121561361d5761361c61332f565b5b600061362b86828701613585565b935050602061363c86828701613585565b925050604061364d868287016134d0565b9150509250925092565b60006020828403121561366d5761366c61332f565b5b600061367b84828501613585565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126136a9576136a8613684565b5b8235905067ffffffffffffffff8111156136c6576136c5613689565b5b6020830191508360208202830111156136e2576136e161368e565b5b9250929050565b6000806000604084860312156137025761370161332f565b5b600084013567ffffffffffffffff8111156137205761371f613334565b5b61372c86828701613693565b9350935050602061373f868287016134d0565b9150509250925092565b6000819050919050565b600061376e61376961376484613512565b613749565b613512565b9050919050565b600061378082613753565b9050919050565b600061379282613775565b9050919050565b6137a281613787565b82525050565b60006020820190506137bd6000830184613799565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61380082613443565b810181811067ffffffffffffffff8211171561381f5761381e6137c8565b5b80604052505050565b6000613832613325565b905061383e82826137f7565b919050565b600067ffffffffffffffff82111561385e5761385d6137c8565b5b61386782613443565b9050602081019050919050565b82818337600083830152505050565b600061389661389184613843565b613828565b9050828152602081018484840111156138b2576138b16137c3565b5b6138bd848285613874565b509392505050565b600082601f8301126138da576138d9613684565b5b81356138ea848260208601613883565b91505092915050565b6000602082840312156139095761390861332f565b5b600082013567ffffffffffffffff81111561392757613926613334565b5b613933848285016138c5565b91505092915050565b6000819050919050565b61394f8161393c565b811461395a57600080fd5b50565b60008135905061396c81613946565b92915050565b600080604083850312156139895761398861332f565b5b60006139978582860161395d565b92505060206139a88582860161395d565b9150509250929050565b6139bb816133be565b81146139c657600080fd5b50565b6000813590506139d8816139b2565b92915050565b600080604083850312156139f5576139f461332f565b5b6000613a0385828601613585565b9250506020613a14858286016139c9565b9150509250929050565b600067ffffffffffffffff821115613a3957613a386137c8565b5b613a4282613443565b9050602081019050919050565b6000613a62613a5d84613a1e565b613828565b905082815260208101848484011115613a7e57613a7d6137c3565b5b613a89848285613874565b509392505050565b600082601f830112613aa657613aa5613684565b5b8135613ab6848260208601613a4f565b91505092915050565b60008060008060808587031215613ad957613ad861332f565b5b6000613ae787828801613585565b9450506020613af887828801613585565b9350506040613b09878288016134d0565b925050606085013567ffffffffffffffff811115613b2a57613b29613334565b5b613b3687828801613a91565b91505092959194509250565b600060208284031215613b5857613b5761332f565b5b6000613b66848285016139c9565b91505092915050565b60008060408385031215613b8657613b8561332f565b5b6000613b94858286016134d0565b9250506020613ba585828601613585565b9150509250929050565b60008060408385031215613bc657613bc561332f565b5b6000613bd485828601613585565b9250506020613be585828601613585565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613c3657607f821691505b602082108103613c4957613c48613bef565b5b50919050565b60008160601b9050919050565b6000613c6782613c4f565b9050919050565b6000613c7982613c5c565b9050919050565b613c91613c8c82613532565b613c6e565b82525050565b6000613ca38284613c80565b60148201915081905092915050565b7f496e636f72726563742057686974656c6973742050726f6f6600000000000000600082015250565b6000613ce86019836133ff565b9150613cf382613cb2565b602082019050919050565b60006020820190508181036000830152613d1781613cdb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613d58826134af565b9150613d63836134af565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613d9c57613d9b613d1e565b5b828202905092915050565b7f506c656173652073656e642074686520657861637420616d6f756e742e000000600082015250565b6000613ddd601d836133ff565b9150613de882613da7565b602082019050919050565b60006020820190508181036000830152613e0c81613dd0565b9050919050565b6000613e1e826134af565b9150613e29836134af565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613e5e57613e5d613d1e565b5b828201905092915050565b7f596f752063616e74206d696e7420616e796d6f72650000000000000000000000600082015250565b6000613e9f6015836133ff565b9150613eaa82613e69565b602082019050919050565b60006020820190508181036000830152613ece81613e92565b9050919050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000613f0b6007836133ff565b9150613f1682613ed5565b602082019050919050565b60006020820190508181036000830152613f3a81613efe565b9050919050565b7f4d696e74696e67206973206e6f74206c69766520796574000000000000000000600082015250565b6000613f776017836133ff565b9150613f8282613f41565b602082019050919050565b60006020820190508181036000830152613fa681613f6a565b9050919050565b7f4e6f206d6f7265204e4654206c65667400000000000000000000000000000000600082015250565b6000613fe36010836133ff565b9150613fee82613fad565b602082019050919050565b6000602082019050818103600083015261401281613fd6565b9050919050565b7f43616e206e6f74206d696e74206d6f7265207468616e20340000000000000000600082015250565b600061404f6018836133ff565b915061405a82614019565b602082019050919050565b6000602082019050818103600083015261407e81614042565b9050919050565b7f506c6561736520656e7465722061206e756d6265720000000000000000000000600082015250565b60006140bb6015836133ff565b91506140c682614085565b602082019050919050565b600060208201905081810360008301526140ea816140ae565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006141276020836133ff565b9150614132826140f1565b602082019050919050565b600060208201905081810360008301526141568161411a565b9050919050565b600081905092915050565b50565b600061417860008361415d565b915061418382614168565b600082019050919050565b60006141998261416b565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006141d96010836133ff565b91506141e4826141a3565b602082019050919050565b60006020820190508181036000830152614208816141cc565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614245601f836133ff565b91506142508261420f565b602082019050919050565b6000602082019050818103600083015261427481614238565b9050919050565b6000614286826134af565b9150614291836134af565b9250828210156142a4576142a3613d1e565b5b828203905092915050565b7f6e65656420746f206d696e74206174206c656173742031204e46540000000000600082015250565b60006142e5601b836133ff565b91506142f0826142af565b602082019050919050565b60006020820190508181036000830152614314816142d8565b9050919050565b7f6d6178204e4654206c696d697420657863656564656400000000000000000000600082015250565b60006143516016836133ff565b915061435c8261431b565b602082019050919050565b6000602082019050818103600083015261438081614344565b9050919050565b7f455243373231414d657461646174613a2055524920717565727920666f72206e60008201527f6f6e6578697374656e7420746f6b656e00000000000000000000000000000000602082015250565b60006143e36030836133ff565b91506143ee82614387565b604082019050919050565b60006020820190508181036000830152614412816143d6565b9050919050565b600081905092915050565b600061442f826133f4565b6144398185614419565b9350614449818560208601613410565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061448b600583614419565b915061449682614455565b600582019050919050565b60006144ad8285614424565b91506144b98284614424565b91506144c48261447e565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061452c6026836133ff565b9150614537826144d0565b604082019050919050565b6000602082019050818103600083015261455b8161451f565b9050919050565b60006040820190506145776000830185613544565b6145846020830184613544565b9392505050565b60008151905061459a816139b2565b92915050565b6000602082840312156145b6576145b561332f565b5b60006145c48482850161458b565b91505092915050565b60006145d8826134af565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361460a57614609613d1e565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061464f826134af565b915061465a836134af565b92508261466a57614669614615565b5b828204905092915050565b6000614680826134af565b915061468b836134af565b92508261469b5761469a614615565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60006146fc826146d5565b61470681856146e0565b9350614716818560208601613410565b61471f81613443565b840191505092915050565b600060808201905061473f6000830187613544565b61474c6020830186613544565b61475960408301856135da565b818103606083015261476b81846146f1565b905095945050505050565b60008151905061478581613365565b92915050565b6000602082840312156147a1576147a061332f565b5b60006147af84828501614776565b9150509291505056fea26469706673582212203aad9c0ef44c3c504cef82023070aef85de9848021d061acf73ddcde1a8163b564736f6c634300080d0033

Deployed Bytecode Sourcemap

96594:6707:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30524:665;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35780:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37985:245;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102555:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;29578:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102720:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99890:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98557:699;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99264:502;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;102157:206;;;;;;;;;;;;;:::i;:::-;;2960:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102891:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96749:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97160:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101105:88;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35569:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101409:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31253:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97304:1245;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62016:103;;;;;;;;;;;;;:::i;:::-;;100860:197;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97045:106;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61365:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101309:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35949:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96952:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96787:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102371:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101722:76;;;;;;;;;;;;;:::i;:::-;;96831:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103070:228;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101519:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101806:343;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100139:713;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96914:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96875;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101201:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38713:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100011:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62274:238;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101621:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30524:665;30654:4;30974:10;30959:25;;:11;:25;;;;:102;;;;31051:10;31036:25;;:11;:25;;;;30959:102;:179;;;;31128:10;31113:25;;:11;:25;;;;30959:179;30939:199;;30524:665;;;:::o;35780:100::-;35834:13;35867:5;35860:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35780:100;:::o;37985:245::-;38089:7;38119:16;38127:7;38119;:16::i;:::-;38114:64;;38144:34;;;;;;;;;;;;;;38114:64;38198:15;:24;38214:7;38198:24;;;;;;;;;;;;;;;;;;;;;38191:31;;37985:245;;;:::o;102555:157::-;102651:8;4481:30;4502:8;4481:20;:30::i;:::-;102672:32:::1;102686:8;102696:7;102672:13;:32::i;:::-;102555:157:::0;;;:::o;29578:315::-;29631:7;29859:15;:13;:15::i;:::-;29844:12;;29828:13;;:28;:46;29821:53;;29578:315;:::o;102720:163::-;102821:4;4309:10;4301:18;;:4;:18;;;4297:83;;4336:32;4357:10;4336:20;:32::i;:::-;4297:83;102838:37:::1;102857:4;102863:2;102867:7;102838:18;:37::i;:::-;102720:163:::0;;;;:::o;99890:113::-;99952:4;99976:11;:19;99988:6;99976:19;;;;;;;;;;;;;;;;;;;;;;;;;99969:26;;99890:113;;;:::o;98557:699::-;98679:12;98721:10;98704:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;98694:39;;;;;;98679:54;;98768:53;98787:12;;98768:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98801:13;;98816:4;98768:18;:53::i;:::-;98746:128;;;;;;;;;;;;:::i;:::-;;;;;;;;;98914:5;98906;;:13;;;;:::i;:::-;98893:9;:26;;98885:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99023:12;;99014:5;98986:25;99000:10;98986:13;:25::i;:::-;:33;;;;:::i;:::-;:49;;98964:120;;;;;;;;;;;;:::i;:::-;;;;;;;;;99128:9;;99119:5;99103:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;99095:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;99168:11;;;;;;;;;;;99160:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;99220:28;99230:10;99242:5;99220:9;:28::i;:::-;98668:588;98557:699;;;:::o;99264:502::-;99356:5;;99348;:13;;;;:::i;:::-;99335:9;:26;;99327:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99439:9;;99430:5;99414:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;99406:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;99539:12;;99530:5;99502:25;99516:10;99502:13;:25::i;:::-;:33;;;;:::i;:::-;:49;;99480:123;;;;;;;;;;;;:::i;:::-;;;;;;;;;99630:1;99622:5;:9;99614:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;99676:13;;;;;;;;;;;99668:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;99730:28;99740:10;99752:5;99730:9;:28::i;:::-;99264:502;:::o;102157:206::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;102208:12:::1;102234:10;102226:24;;102272:21;102226:82;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102207:101;;;102327:7;102319:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;102196:167;102157:206::o:0;2960:143::-;3060:42;2960:143;:::o;102891:171::-;102996:4;4309:10;4301:18;;:4;:18;;;4297:83;;4336:32;4357:10;4336:20;:32::i;:::-;4297:83;103013:41:::1;103036:4;103042:2;103046:7;103013:22;:41::i;:::-;102891:171:::0;;;;:::o;96749:31::-;;;;:::o;97160:28::-;;;;;;;;;;;;;:::o;101105:88::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101182:3:::1;101172:7;:13;;;;;;;;;;;;:::i;:::-;;101105:88:::0;:::o;35569:144::-;35633:7;35676:27;35695:7;35676:18;:27::i;:::-;35653:52;;35569:144;;;:::o;101409:102::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101493:10:::1;101481:9;:22;;;;101409:102:::0;:::o;31253:224::-;31317:7;31358:1;31341:19;;:5;:19;;;31337:60;;31369:28;;;;;;;;;;;;;;31337:60;26548:13;31415:18;:25;31434:5;31415:25;;;;;;;;;;;;;;;;:54;31408:61;;31253:224;;;:::o;97304:1245::-;7325:1;7923:7;;:19;7915:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7325:1;8056:7;:18;;;;97441:15:::1;97461:11;:23;97473:10;97461:23;;;;;;;;;;;;;;;;;;;;;;;;;97459:26;97441:44;;97496:12;97520:16;;97511:5;:25;97496:40;;97549:12;97564:5;;97549:20;;97582:12;97624:10;97607:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;97597:39;;;;;;97582:54;;97653:10;:21;;;;;97667:7;97653:21;97649:62;;;97698:1;97691:8;;97649:62;97727:10;:22;;;;;97742:7;97741:8;97727:22;97723:292;;;97834:4;97814:16;;97806:5;:24;;;;:::i;:::-;97805:33;;;;:::i;:::-;97792:9;:46;;97766:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;97723:292;;;97965:4;97957:5;:12;;;;:::i;:::-;97944:9;:25;;97936:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;97723:292;98047:46;98066:12;;98047:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98080:6;;98088:4;98047:18;:46::i;:::-;98025:121;;;;;;;;;;;;:::i;:::-;;;;;;;;;98190:9;;98181:5;98165:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;98157:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;98238:1;98230:5;:9;98222:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;98284:11;;;;;;;;;;;98276:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;98393:12;;98384:5;98356:25;98370:10;98356:13;:25::i;:::-;:33;;;;:::i;:::-;:49;;98334:123;;;;;;;;;;;;:::i;:::-;;;;;;;;;98496:4;98470:11;:23;98482:10;98470:23;;;;;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;98513:28;98523:10;98535:5;98513:9;:28::i;:::-;97430:1119;;;;7281:1:::0;8235:7;:22;;;;97304:1245;;;:::o;62016:103::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;62081:30:::1;62108:1;62081:18;:30::i;:::-;62016:103::o:0;100860:197::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100994:14:::1;100985:6;:23;;;;101035:14;101019:13;:30;;;;100860:197:::0;;:::o;97045:106::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;61365:87::-;61411:7;61438:6;;;;;;;;;;;61431:13;;61365:87;:::o;101309:92::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101384:9:::1;101376:5;:17;;;;101309:92:::0;:::o;35949:104::-;36005:13;36038:7;36031:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35949:104;:::o;96952:33::-;;;;;;;;;;;;;:::o;96787:35::-;;;;:::o;102371:176::-;102475:8;4481:30;4502:8;4481:20;:30::i;:::-;102496:43:::1;102520:8;102530;102496:23;:43::i;:::-;102371:176:::0;;;:::o;101722:76::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101782:8:::1;;;;;;;;;;;101781:9;101770:8;;:20;;;;;;;;;;;;;;;;;;101722:76::o:0;96831:35::-;;;;:::o;103070:228::-;103221:4;4309:10;4301:18;;:4;:18;;;4297:83;;4336:32;4357:10;4336:20;:32::i;:::-;4297:83;103243:47:::1;103266:4;103272:2;103276:7;103285:4;103243:22;:47::i;:::-;103070:228:::0;;;;;:::o;101519:94::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101599:6:::1;101585:11;;:20;;;;;;;;;;;;;;;;;;101519:94:::0;:::o;101806:343::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101940:1:::1;101926:11;:15;101918:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;101984:14;102001:13;:11;:13::i;:::-;101984:30;;102057:9;;102042:11;102033:6;:20;;;;:::i;:::-;:33;;102025:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;102106:35;102116:11;102129;102106:9;:35::i;:::-;101907:242;101806:343:::0;;:::o;100139:713::-;100257:13;100310:16;100318:7;100310;:16::i;:::-;100288:114;;;;;;;;;;;;:::i;:::-;;;;;;;;;100429:5;100417:17;;:8;;;;;;;;;;;:17;;;100413:66;;100458:9;100451:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100413:66;100491:28;100522:10;:8;:10::i;:::-;100491:41;;100594:1;100569:14;100563:28;:32;:281;;;;;;;;;;;;;;;;;100687:14;100728:18;:7;:16;:18::i;:::-;100644:159;;;;;;;;;:::i;:::-;;;;;;;;;;;;;100563:281;100543:301;;;100139:713;;;;:::o;96914:31::-;;;;;;;;;;;;;:::o;96875:::-;;;;:::o;101201:100::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101287:6:::1;101272:12;:21;;;;101201:100:::0;:::o;38713:214::-;38855:4;38884:18;:25;38903:5;38884:25;;;;;;;;;;;;;;;:35;38910:8;38884:35;;;;;;;;;;;;;;;;;;;;;;;;;38877:42;;38713:214;;;;:::o;100011:120::-;100074:7;100101:22;100115:7;100101:13;:22::i;:::-;100094:29;;100011:120;;;:::o;62274:238::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;62397:1:::1;62377:22;;:8;:22;;::::0;62355:110:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;62476:28;62495:8;62476:18;:28::i;:::-;62274:238:::0;:::o;101621:93::-;61596:12;:10;:12::i;:::-;61585:23;;:7;:5;:7::i;:::-;:23;;;61577:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101700:6:::1;101684:13;;:22;;;;;;;;;;;;;;;;;;101621:93:::0;:::o;40142:273::-;40199:4;40255:7;40236:15;:13;:15::i;:::-;:26;;:66;;;;;40289:13;;40279:7;:23;40236:66;:152;;;;;40387:1;27318:8;40340:17;:26;40358:7;40340:26;;;;;;;;;;;;:43;:48;40236:152;40216:172;;40142:273;;;:::o;4539:419::-;4778:1;3060:42;4730:45;;;:49;4726:225;;;3060:42;4801;;;4852:4;4859:8;4801:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4796:144;;4915:8;4896:28;;;;;;;;;;;:::i;:::-;;;;;;;;4796:144;4726:225;4539:419;:::o;37437:482::-;37518:13;37550:27;37569:7;37550:18;:27::i;:::-;37518:61;;37600:5;37594:11;;:2;:11;;;37590:48;;37614:24;;;;;;;;;;;;;;37590:48;37678:5;37655:28;;:19;:17;:19::i;:::-;:28;;;37651:175;;37703:44;37720:5;37727:19;:17;:19::i;:::-;37703:16;:44::i;:::-;37698:128;;37775:35;;;;;;;;;;;;;;37698:128;37651:175;37865:2;37838:15;:24;37854:7;37838:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;37903:7;37899:2;37883:28;;37892:5;37883:28;;;;;;;;;;;;37507:412;37437:482;;:::o;29102:92::-;29158:7;29102:92;:::o;38994:170::-;39128:28;39138:4;39144:2;39148:7;39128:9;:28::i;:::-;38994:170;;;:::o;9521:190::-;9646:4;9699;9670:25;9683:5;9690:4;9670:12;:25::i;:::-;:33;9663:40;;9521:190;;;;;:::o;31559:202::-;31620:7;26548:13;26685:2;31661:18;:25;31680:5;31661:25;;;;;;;;;;;;;;;;:49;;31660:93;31640:113;;31559:202;;;:::o;40499:104::-;40568:27;40578:2;40582:8;40568:27;;;;;;;;;;;;:9;:27::i;:::-;40499:104;;:::o;60015:98::-;60068:7;60095:10;60088:17;;60015:98;:::o;39235:185::-;39373:39;39390:4;39396:2;39400:7;39373:39;;;;;;;;;;;;:16;:39::i;:::-;39235:185;;;:::o;32956:1161::-;33050:7;33075:12;33090:7;33075:22;;33158:4;33139:15;:13;:15::i;:::-;:23;33135:915;;33192:13;;33185:4;:20;33181:869;;;33230:14;33247:17;:23;33265:4;33247:23;;;;;;;;;;;;33230:40;;33363:1;27318:8;33336:6;:23;:28;33332:699;;33855:113;33872:1;33862:6;:11;33855:113;;33915:17;:25;33933:6;;;;;;;33915:25;;;;;;;;;;;;33906:34;;33855:113;;;34001:6;33994:13;;;;;;33332:699;33207:843;33181:869;33135:915;34078:31;;;;;;;;;;;;;;32956:1161;;;;:::o;62672:191::-;62746:16;62765:6;;;;;;;;;;;62746:25;;62791:8;62782:6;;:17;;;;;;;;;;;;;;;;;;62846:8;62815:40;;62836:8;62815:40;;;;;;;;;;;;62735:128;62672:191;:::o;38302:340::-;38445:19;:17;:19::i;:::-;38433:31;;:8;:31;;;38429:61;;38473:17;;;;;;;;;;;;;;38429:61;38555:8;38503:18;:39;38522:19;:17;:19::i;:::-;38503:39;;;;;;;;;;;;;;;:49;38543:8;38503:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;38615:8;38579:55;;38594:19;:17;:19::i;:::-;38579:55;;;38625:8;38579:55;;;;;;:::i;:::-;;;;;;;;38302:340;;:::o;39491:396::-;39658:28;39668:4;39674:2;39678:7;39658:9;:28::i;:::-;39719:1;39701:2;:14;;;:19;39697:183;;39740:56;39771:4;39777:2;39781:7;39790:5;39740:30;:56::i;:::-;39735:145;;39824:40;;;;;;;;;;;;;;39735:145;39697:183;39491:396;;;;:::o;99774:108::-;99834:13;99867:7;99860:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99774:108;:::o;57186:723::-;57242:13;57472:1;57463:5;:10;57459:53;;57490:10;;;;;;;;;;;;;;;;;;;;;57459:53;57522:12;57537:5;57522:20;;57553:14;57578:78;57593:1;57585:4;:9;57578:78;;57611:8;;;;;:::i;:::-;;;;57642:2;57634:10;;;;;:::i;:::-;;;57578:78;;;57666:19;57698:6;57688:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57666:39;;57716:154;57732:1;57723:5;:10;57716:154;;57760:1;57750:11;;;;;:::i;:::-;;;57827:2;57819:5;:10;;;;:::i;:::-;57806:2;:24;;;;:::i;:::-;57793:39;;57776:6;57783;57776:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;57856:2;57847:11;;;;;:::i;:::-;;;57716:154;;;57894:6;57880:21;;;;;57186:723;;;;:::o;54510:105::-;54570:7;54597:10;54590:17;;54510:105;:::o;45640:2528::-;45755:27;45785;45804:7;45785:18;:27::i;:::-;45755:57;;45870:4;45829:45;;45845:19;45829:45;;;45825:99;;45896:28;;;;;;;;;;;;;;45825:99;45937:22;45986:4;45963:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;46007:43;46024:4;46030:19;:17;:19::i;:::-;46007:16;:43::i;:::-;45963:87;:147;;;;46091:19;:17;:19::i;:::-;46067:43;;:20;46079:7;46067:11;:20::i;:::-;:43;;;45963:147;45937:174;;46129:17;46124:66;;46155:35;;;;;;;;;;;;;;46124:66;46219:1;46205:16;;:2;:16;;;46201:52;;46230:23;;;;;;;;;;;;;;46201:52;46266:43;46288:4;46294:2;46298:7;46307:1;46266:21;:43::i;:::-;46382:15;:24;46398:7;46382:24;;;;;;;;;;;;46375:31;;;;;;;;;;;46774:18;:24;46793:4;46774:24;;;;;;;;;;;;;;;;46772:26;;;;;;;;;;;;46843:18;:22;46862:2;46843:22;;;;;;;;;;;;;;;;46841:24;;;;;;;;;;;27596:8;27202:3;47224:15;:41;;47182:21;47200:2;47182:17;:21::i;:::-;:84;:128;47136:17;:26;47154:7;47136:26;;;;;;;;;;;:174;;;;47480:1;27596:8;47430:19;:46;:51;47426:626;;47502:19;47534:1;47524:7;:11;47502:33;;47691:1;47657:17;:30;47675:11;47657:30;;;;;;;;;;;;:35;47653:384;;47795:13;;47780:11;:28;47776:242;;47975:19;47942:17;:30;47960:11;47942:30;;;;;;;;;;;:52;;;;47776:242;47653:384;47483:569;47426:626;48099:7;48095:2;48080:27;;48089:4;48080:27;;;;;;;;;;;;48118:42;48139:4;48145:2;48149:7;48158:1;48118:20;:42::i;:::-;45744:2424;;45640:2528;;;:::o;10388:328::-;10498:7;10523:20;10546:4;10523:27;;10566:9;10561:118;10585:5;:12;10581:1;:16;10561:118;;;10634:33;10644:12;10658:5;10664:1;10658:8;;;;;;;;:::i;:::-;;;;;;;;10634:9;:33::i;:::-;10619:48;;10599:3;;;;;:::i;:::-;;;;10561:118;;;;10696:12;10689:19;;;10388:328;;;;:::o;40976:2461::-;41099:20;41122:13;;41099:36;;41164:1;41150:16;;:2;:16;;;41146:48;;41175:19;;;;;;;;;;;;;;41146:48;41221:1;41209:8;:13;41205:44;;41231:18;;;;;;;;;;;;;;41205:44;41262:61;41292:1;41296:2;41300:12;41314:8;41262:21;:61::i;:::-;41900:1;26685:2;41871:1;:25;;41870:31;41841:8;:61;41798:18;:22;41817:2;41798:22;;;;;;;;;;;;;;;;:104;;;;;;;;;;;27461:3;42301:29;42328:1;42316:8;:13;42301:14;:29::i;:::-;:56;;27202:3;42238:15;:41;;42196:21;42214:2;42196:17;:21::i;:::-;:84;:162;42145:17;:31;42163:12;42145:31;;;;;;;;;;;:213;;;;42375:20;42398:12;42375:35;;42425:11;42454:8;42439:12;:23;42425:37;;42501:1;42483:2;:14;;;:19;42479:826;;42523:504;42579:12;42575:2;42554:38;;42571:1;42554:38;;;;;;;;;;;;42646:212;42715:1;42748:2;42781:14;;;;;;42826:5;42646:30;:212::i;:::-;42615:365;;42916:40;;;;;;;;;;;;;;42615:365;43022:3;43007:12;:18;42523:504;;43108:12;43091:13;;:29;43087:43;;43122:8;;;43087:43;42479:826;;;43171:119;43227:14;;;;;;43223:2;43202:40;;43219:1;43202:40;;;;;;;;;;;;43285:3;43270:12;:18;43171:119;;42479:826;43335:12;43319:13;:28;;;;41575:1784;;43369:60;43398:1;43402:2;43406:12;43420:8;43369:20;:60::i;:::-;41088:2349;40976:2461;;;:::o;51864:831::-;52027:4;52086:2;52061:45;;;52125:19;:17;:19::i;:::-;52163:4;52186:7;52212:5;52061:171;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;52044:644;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52463:1;52446:6;:13;:18;52442:235;;52492:40;;;;;;;;;;;;;;52442:235;52635:6;52629:13;52620:6;52616:2;52612:15;52605:38;52044:644;52332:54;;;52305:81;;;:6;:81;;;;52281:105;;;51864:831;;;;;;:::o;53343:159::-;;;;;:::o;36966:180::-;37057:14;37123:5;37113:15;;36966:180;;;:::o;54161:158::-;;;;;:::o;16869:149::-;16932:7;16963:1;16959;:5;:51;;16990:20;17005:1;17008;16990:14;:20::i;:::-;16959:51;;;16967:20;16982:1;16985;16967:14;:20::i;:::-;16959:51;16952:58;;16869:149;;;;:::o;37233:142::-;37291:14;37352:5;37342:15;;37233:142;;;:::o;17026:300::-;17121:13;17233:1;17227:4;17220:15;17262:1;17256:4;17249:15;17303:4;17297;17287:21;17278:30;;17026:300;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518: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:329::-;5974:6;6023:2;6011:9;6002:7;5998:23;5994:32;5991:119;;;6029:79;;:::i;:::-;5991:119;6149:1;6174:53;6219:7;6210:6;6199:9;6195:22;6174:53;:::i;:::-;6164:63;;6120:117;5915:329;;;;:::o;6250:117::-;6359:1;6356;6349:12;6373:117;6482:1;6479;6472:12;6496:117;6605:1;6602;6595:12;6636:568;6709:8;6719:6;6769:3;6762:4;6754:6;6750:17;6746:27;6736:122;;6777:79;;:::i;:::-;6736:122;6890:6;6877:20;6867:30;;6920:18;6912:6;6909:30;6906:117;;;6942:79;;:::i;:::-;6906:117;7056:4;7048:6;7044:17;7032:29;;7110:3;7102:4;7094:6;7090:17;7080:8;7076:32;7073:41;7070:128;;;7117:79;;:::i;:::-;7070:128;6636:568;;;;;:::o;7210:704::-;7305:6;7313;7321;7370:2;7358:9;7349:7;7345:23;7341:32;7338:119;;;7376:79;;:::i;:::-;7338:119;7524:1;7513:9;7509:17;7496:31;7554:18;7546:6;7543:30;7540:117;;;7576:79;;:::i;:::-;7540:117;7689:80;7761:7;7752:6;7741:9;7737:22;7689:80;:::i;:::-;7671:98;;;;7467:312;7818:2;7844:53;7889:7;7880:6;7869:9;7865:22;7844:53;:::i;:::-;7834:63;;7789:118;7210:704;;;;;:::o;7920:60::-;7948:3;7969:5;7962:12;;7920:60;;;:::o;7986:142::-;8036:9;8069:53;8087:34;8096:24;8114:5;8096:24;:::i;:::-;8087:34;:::i;:::-;8069:53;:::i;:::-;8056:66;;7986:142;;;:::o;8134:126::-;8184:9;8217:37;8248:5;8217:37;:::i;:::-;8204:50;;8134:126;;;:::o;8266:157::-;8347:9;8380:37;8411:5;8380:37;:::i;:::-;8367:50;;8266:157;;;:::o;8429:193::-;8547:68;8609:5;8547:68;:::i;:::-;8542:3;8535:81;8429:193;;:::o;8628:284::-;8752:4;8790:2;8779:9;8775:18;8767:26;;8803:102;8902:1;8891:9;8887:17;8878:6;8803:102;:::i;:::-;8628:284;;;;:::o;8918:117::-;9027:1;9024;9017:12;9041:180;9089:77;9086:1;9079:88;9186:4;9183:1;9176:15;9210:4;9207:1;9200:15;9227:281;9310:27;9332:4;9310:27;:::i;:::-;9302:6;9298:40;9440:6;9428:10;9425:22;9404:18;9392:10;9389:34;9386:62;9383:88;;;9451:18;;:::i;:::-;9383:88;9491:10;9487:2;9480:22;9270:238;9227:281;;:::o;9514:129::-;9548:6;9575:20;;:::i;:::-;9565:30;;9604:33;9632:4;9624:6;9604:33;:::i;:::-;9514:129;;;:::o;9649:308::-;9711:4;9801:18;9793:6;9790:30;9787:56;;;9823:18;;:::i;:::-;9787:56;9861:29;9883:6;9861:29;:::i;:::-;9853:37;;9945:4;9939;9935:15;9927:23;;9649:308;;;:::o;9963:154::-;10047:6;10042:3;10037;10024:30;10109:1;10100:6;10095:3;10091:16;10084:27;9963:154;;;:::o;10123:412::-;10201:5;10226:66;10242:49;10284:6;10242:49;:::i;:::-;10226:66;:::i;:::-;10217:75;;10315:6;10308:5;10301:21;10353:4;10346:5;10342:16;10391:3;10382:6;10377:3;10373:16;10370:25;10367:112;;;10398:79;;:::i;:::-;10367:112;10488:41;10522:6;10517:3;10512;10488:41;:::i;:::-;10207:328;10123:412;;;;;:::o;10555:340::-;10611:5;10660:3;10653:4;10645:6;10641:17;10637:27;10627:122;;10668:79;;:::i;:::-;10627:122;10785:6;10772:20;10810:79;10885:3;10877:6;10870:4;10862:6;10858:17;10810:79;:::i;:::-;10801:88;;10617:278;10555:340;;;;:::o;10901:509::-;10970:6;11019:2;11007:9;10998:7;10994:23;10990:32;10987:119;;;11025:79;;:::i;:::-;10987:119;11173:1;11162:9;11158:17;11145:31;11203:18;11195:6;11192:30;11189:117;;;11225:79;;:::i;:::-;11189:117;11330:63;11385:7;11376:6;11365:9;11361:22;11330:63;:::i;:::-;11320:73;;11116:287;10901:509;;;;:::o;11416:77::-;11453:7;11482:5;11471:16;;11416:77;;;:::o;11499:122::-;11572:24;11590:5;11572:24;:::i;:::-;11565:5;11562:35;11552:63;;11611:1;11608;11601:12;11552:63;11499:122;:::o;11627:139::-;11673:5;11711:6;11698:20;11689:29;;11727:33;11754:5;11727:33;:::i;:::-;11627:139;;;;:::o;11772:474::-;11840:6;11848;11897:2;11885:9;11876:7;11872:23;11868:32;11865:119;;;11903:79;;:::i;:::-;11865:119;12023:1;12048:53;12093:7;12084:6;12073:9;12069:22;12048:53;:::i;:::-;12038:63;;11994:117;12150:2;12176:53;12221:7;12212:6;12201:9;12197:22;12176:53;:::i;:::-;12166:63;;12121:118;11772:474;;;;;:::o;12252:116::-;12322:21;12337:5;12322:21;:::i;:::-;12315:5;12312:32;12302:60;;12358:1;12355;12348:12;12302:60;12252:116;:::o;12374:133::-;12417:5;12455:6;12442:20;12433:29;;12471:30;12495:5;12471:30;:::i;:::-;12374:133;;;;:::o;12513:468::-;12578:6;12586;12635:2;12623:9;12614:7;12610:23;12606:32;12603:119;;;12641:79;;:::i;:::-;12603:119;12761:1;12786:53;12831:7;12822:6;12811:9;12807:22;12786:53;:::i;:::-;12776:63;;12732:117;12888:2;12914:50;12956:7;12947:6;12936:9;12932:22;12914:50;:::i;:::-;12904:60;;12859:115;12513:468;;;;;:::o;12987:307::-;13048:4;13138:18;13130:6;13127:30;13124:56;;;13160:18;;:::i;:::-;13124:56;13198:29;13220:6;13198:29;:::i;:::-;13190:37;;13282:4;13276;13272:15;13264:23;;12987:307;;;:::o;13300:410::-;13377:5;13402:65;13418:48;13459:6;13418:48;:::i;:::-;13402:65;:::i;:::-;13393:74;;13490:6;13483:5;13476:21;13528:4;13521:5;13517:16;13566:3;13557:6;13552:3;13548:16;13545:25;13542:112;;;13573:79;;:::i;:::-;13542:112;13663:41;13697:6;13692:3;13687;13663:41;:::i;:::-;13383:327;13300:410;;;;;:::o;13729:338::-;13784:5;13833:3;13826:4;13818:6;13814:17;13810:27;13800:122;;13841:79;;:::i;:::-;13800:122;13958:6;13945:20;13983:78;14057:3;14049:6;14042:4;14034:6;14030:17;13983:78;:::i;:::-;13974:87;;13790:277;13729:338;;;;:::o;14073:943::-;14168:6;14176;14184;14192;14241:3;14229:9;14220:7;14216:23;14212:33;14209:120;;;14248:79;;:::i;:::-;14209:120;14368:1;14393:53;14438:7;14429:6;14418:9;14414:22;14393:53;:::i;:::-;14383:63;;14339:117;14495:2;14521:53;14566:7;14557:6;14546:9;14542:22;14521:53;:::i;:::-;14511:63;;14466:118;14623:2;14649:53;14694:7;14685:6;14674:9;14670:22;14649:53;:::i;:::-;14639:63;;14594:118;14779:2;14768:9;14764:18;14751:32;14810:18;14802:6;14799:30;14796:117;;;14832:79;;:::i;:::-;14796:117;14937:62;14991:7;14982:6;14971:9;14967:22;14937:62;:::i;:::-;14927:72;;14722:287;14073:943;;;;;;;:::o;15022:323::-;15078:6;15127:2;15115:9;15106:7;15102:23;15098:32;15095:119;;;15133:79;;:::i;:::-;15095:119;15253:1;15278:50;15320:7;15311:6;15300:9;15296:22;15278:50;:::i;:::-;15268:60;;15224:114;15022:323;;;;:::o;15351:474::-;15419:6;15427;15476:2;15464:9;15455:7;15451:23;15447:32;15444:119;;;15482:79;;:::i;:::-;15444:119;15602:1;15627:53;15672:7;15663:6;15652:9;15648:22;15627:53;:::i;:::-;15617:63;;15573:117;15729:2;15755:53;15800:7;15791:6;15780:9;15776:22;15755:53;:::i;:::-;15745:63;;15700:118;15351:474;;;;;:::o;15831:::-;15899:6;15907;15956:2;15944:9;15935:7;15931:23;15927:32;15924:119;;;15962:79;;:::i;:::-;15924:119;16082:1;16107:53;16152:7;16143:6;16132:9;16128:22;16107:53;:::i;:::-;16097:63;;16053:117;16209:2;16235:53;16280:7;16271:6;16260:9;16256:22;16235:53;:::i;:::-;16225:63;;16180:118;15831:474;;;;;:::o;16311:180::-;16359:77;16356:1;16349:88;16456:4;16453:1;16446:15;16480:4;16477:1;16470:15;16497:320;16541:6;16578:1;16572:4;16568:12;16558:22;;16625:1;16619:4;16615:12;16646:18;16636:81;;16702:4;16694:6;16690:17;16680:27;;16636:81;16764:2;16756:6;16753:14;16733:18;16730:38;16727:84;;16783:18;;:::i;:::-;16727:84;16548:269;16497:320;;;:::o;16823:94::-;16856:8;16904:5;16900:2;16896:14;16875:35;;16823:94;;;:::o;16923:::-;16962:7;16991:20;17005:5;16991:20;:::i;:::-;16980:31;;16923:94;;;:::o;17023:100::-;17062:7;17091:26;17111:5;17091:26;:::i;:::-;17080:37;;17023:100;;;:::o;17129:157::-;17234:45;17254:24;17272:5;17254:24;:::i;:::-;17234:45;:::i;:::-;17229:3;17222:58;17129:157;;:::o;17292:256::-;17404:3;17419:75;17490:3;17481:6;17419:75;:::i;:::-;17519:2;17514:3;17510:12;17503:19;;17539:3;17532:10;;17292:256;;;;:::o;17554:175::-;17694:27;17690:1;17682:6;17678:14;17671:51;17554:175;:::o;17735:366::-;17877:3;17898:67;17962:2;17957:3;17898:67;:::i;:::-;17891:74;;17974:93;18063:3;17974:93;:::i;:::-;18092:2;18087:3;18083:12;18076:19;;17735:366;;;:::o;18107:419::-;18273:4;18311:2;18300:9;18296:18;18288:26;;18360:9;18354:4;18350:20;18346:1;18335:9;18331:17;18324:47;18388:131;18514:4;18388:131;:::i;:::-;18380:139;;18107:419;;;:::o;18532:180::-;18580:77;18577:1;18570:88;18677:4;18674:1;18667:15;18701:4;18698:1;18691:15;18718:348;18758:7;18781:20;18799:1;18781:20;:::i;:::-;18776:25;;18815:20;18833:1;18815:20;:::i;:::-;18810:25;;19003:1;18935:66;18931:74;18928:1;18925:81;18920:1;18913:9;18906:17;18902:105;18899:131;;;19010:18;;:::i;:::-;18899:131;19058:1;19055;19051:9;19040:20;;18718:348;;;;:::o;19072:179::-;19212:31;19208:1;19200:6;19196:14;19189:55;19072:179;:::o;19257:366::-;19399:3;19420:67;19484:2;19479:3;19420:67;:::i;:::-;19413:74;;19496:93;19585:3;19496:93;:::i;:::-;19614:2;19609:3;19605:12;19598:19;;19257:366;;;:::o;19629:419::-;19795:4;19833:2;19822:9;19818:18;19810:26;;19882:9;19876:4;19872:20;19868:1;19857:9;19853:17;19846:47;19910:131;20036:4;19910:131;:::i;:::-;19902:139;;19629:419;;;:::o;20054:305::-;20094:3;20113:20;20131:1;20113:20;:::i;:::-;20108:25;;20147:20;20165:1;20147:20;:::i;:::-;20142:25;;20301:1;20233:66;20229:74;20226:1;20223:81;20220:107;;;20307:18;;:::i;:::-;20220:107;20351:1;20348;20344:9;20337:16;;20054:305;;;;:::o;20365:171::-;20505:23;20501:1;20493:6;20489:14;20482:47;20365:171;:::o;20542:366::-;20684:3;20705:67;20769:2;20764:3;20705:67;:::i;:::-;20698:74;;20781:93;20870:3;20781:93;:::i;:::-;20899:2;20894:3;20890:12;20883:19;;20542:366;;;:::o;20914:419::-;21080:4;21118:2;21107:9;21103:18;21095:26;;21167:9;21161:4;21157:20;21153:1;21142:9;21138:17;21131:47;21195:131;21321:4;21195:131;:::i;:::-;21187:139;;20914:419;;;:::o;21339:157::-;21479:9;21475:1;21467:6;21463:14;21456:33;21339:157;:::o;21502:365::-;21644:3;21665:66;21729:1;21724:3;21665:66;:::i;:::-;21658:73;;21740:93;21829:3;21740:93;:::i;:::-;21858:2;21853:3;21849:12;21842:19;;21502:365;;;:::o;21873:419::-;22039:4;22077:2;22066:9;22062:18;22054:26;;22126:9;22120:4;22116:20;22112:1;22101:9;22097:17;22090:47;22154:131;22280:4;22154:131;:::i;:::-;22146:139;;21873:419;;;:::o;22298:173::-;22438:25;22434:1;22426:6;22422:14;22415:49;22298:173;:::o;22477:366::-;22619:3;22640:67;22704:2;22699:3;22640:67;:::i;:::-;22633:74;;22716:93;22805:3;22716:93;:::i;:::-;22834:2;22829:3;22825:12;22818:19;;22477:366;;;:::o;22849:419::-;23015:4;23053:2;23042:9;23038:18;23030:26;;23102:9;23096:4;23092:20;23088:1;23077:9;23073:17;23066:47;23130:131;23256:4;23130:131;:::i;:::-;23122:139;;22849:419;;;:::o;23274:166::-;23414:18;23410:1;23402:6;23398:14;23391:42;23274:166;:::o;23446:366::-;23588:3;23609:67;23673:2;23668:3;23609:67;:::i;:::-;23602:74;;23685:93;23774:3;23685:93;:::i;:::-;23803:2;23798:3;23794:12;23787:19;;23446:366;;;:::o;23818:419::-;23984:4;24022:2;24011:9;24007:18;23999:26;;24071:9;24065:4;24061:20;24057:1;24046:9;24042:17;24035:47;24099:131;24225:4;24099:131;:::i;:::-;24091:139;;23818:419;;;:::o;24243:174::-;24383:26;24379:1;24371:6;24367:14;24360:50;24243:174;:::o;24423:366::-;24565:3;24586:67;24650:2;24645:3;24586:67;:::i;:::-;24579:74;;24662:93;24751:3;24662:93;:::i;:::-;24780:2;24775:3;24771:12;24764:19;;24423:366;;;:::o;24795:419::-;24961:4;24999:2;24988:9;24984:18;24976:26;;25048:9;25042:4;25038:20;25034:1;25023:9;25019:17;25012:47;25076:131;25202:4;25076:131;:::i;:::-;25068:139;;24795:419;;;:::o;25220:171::-;25360:23;25356:1;25348:6;25344:14;25337:47;25220:171;:::o;25397:366::-;25539:3;25560:67;25624:2;25619:3;25560:67;:::i;:::-;25553:74;;25636:93;25725:3;25636:93;:::i;:::-;25754:2;25749:3;25745:12;25738:19;;25397:366;;;:::o;25769:419::-;25935:4;25973:2;25962:9;25958:18;25950:26;;26022:9;26016:4;26012:20;26008:1;25997:9;25993:17;25986:47;26050:131;26176:4;26050:131;:::i;:::-;26042:139;;25769:419;;;:::o;26194:182::-;26334:34;26330:1;26322:6;26318:14;26311:58;26194:182;:::o;26382:366::-;26524:3;26545:67;26609:2;26604:3;26545:67;:::i;:::-;26538:74;;26621:93;26710:3;26621:93;:::i;:::-;26739:2;26734:3;26730:12;26723:19;;26382:366;;;:::o;26754:419::-;26920:4;26958:2;26947:9;26943:18;26935:26;;27007:9;27001:4;26997:20;26993:1;26982:9;26978:17;26971:47;27035:131;27161:4;27035:131;:::i;:::-;27027:139;;26754:419;;;:::o;27179:147::-;27280:11;27317:3;27302:18;;27179:147;;;;:::o;27332:114::-;;:::o;27452:398::-;27611:3;27632:83;27713:1;27708:3;27632:83;:::i;:::-;27625:90;;27724:93;27813:3;27724:93;:::i;:::-;27842:1;27837:3;27833:11;27826:18;;27452:398;;;:::o;27856:379::-;28040:3;28062:147;28205:3;28062:147;:::i;:::-;28055:154;;28226:3;28219:10;;27856:379;;;:::o;28241:166::-;28381:18;28377:1;28369:6;28365:14;28358:42;28241:166;:::o;28413:366::-;28555:3;28576:67;28640:2;28635:3;28576:67;:::i;:::-;28569:74;;28652:93;28741:3;28652:93;:::i;:::-;28770:2;28765:3;28761:12;28754:19;;28413:366;;;:::o;28785:419::-;28951:4;28989:2;28978:9;28974:18;28966:26;;29038:9;29032:4;29028:20;29024:1;29013:9;29009:17;29002:47;29066:131;29192:4;29066:131;:::i;:::-;29058:139;;28785:419;;;:::o;29210:181::-;29350:33;29346:1;29338:6;29334:14;29327:57;29210:181;:::o;29397:366::-;29539:3;29560:67;29624:2;29619:3;29560:67;:::i;:::-;29553:74;;29636:93;29725:3;29636:93;:::i;:::-;29754:2;29749:3;29745:12;29738:19;;29397:366;;;:::o;29769:419::-;29935:4;29973:2;29962:9;29958:18;29950:26;;30022:9;30016:4;30012:20;30008:1;29997:9;29993:17;29986:47;30050:131;30176:4;30050:131;:::i;:::-;30042:139;;29769:419;;;:::o;30194:191::-;30234:4;30254:20;30272:1;30254:20;:::i;:::-;30249:25;;30288:20;30306:1;30288:20;:::i;:::-;30283:25;;30327:1;30324;30321:8;30318:34;;;30332:18;;:::i;:::-;30318:34;30377:1;30374;30370:9;30362:17;;30194:191;;;;:::o;30391:177::-;30531:29;30527:1;30519:6;30515:14;30508:53;30391:177;:::o;30574:366::-;30716:3;30737:67;30801:2;30796:3;30737:67;:::i;:::-;30730:74;;30813:93;30902:3;30813:93;:::i;:::-;30931:2;30926:3;30922:12;30915:19;;30574:366;;;:::o;30946:419::-;31112:4;31150:2;31139:9;31135:18;31127:26;;31199:9;31193:4;31189:20;31185:1;31174:9;31170:17;31163:47;31227:131;31353:4;31227:131;:::i;:::-;31219:139;;30946:419;;;:::o;31371:172::-;31511:24;31507:1;31499:6;31495:14;31488:48;31371:172;:::o;31549:366::-;31691:3;31712:67;31776:2;31771:3;31712:67;:::i;:::-;31705:74;;31788:93;31877:3;31788:93;:::i;:::-;31906:2;31901:3;31897:12;31890:19;;31549:366;;;:::o;31921:419::-;32087:4;32125:2;32114:9;32110:18;32102:26;;32174:9;32168:4;32164:20;32160:1;32149:9;32145:17;32138:47;32202:131;32328:4;32202:131;:::i;:::-;32194:139;;31921:419;;;:::o;32346:235::-;32486:34;32482:1;32474:6;32470:14;32463:58;32555:18;32550:2;32542:6;32538:15;32531:43;32346:235;:::o;32587:366::-;32729:3;32750:67;32814:2;32809:3;32750:67;:::i;:::-;32743:74;;32826:93;32915:3;32826:93;:::i;:::-;32944:2;32939:3;32935:12;32928:19;;32587:366;;;:::o;32959:419::-;33125:4;33163:2;33152:9;33148:18;33140:26;;33212:9;33206:4;33202:20;33198:1;33187:9;33183:17;33176:47;33240:131;33366:4;33240:131;:::i;:::-;33232:139;;32959:419;;;:::o;33384:148::-;33486:11;33523:3;33508:18;;33384:148;;;;:::o;33538:377::-;33644:3;33672:39;33705:5;33672:39;:::i;:::-;33727:89;33809:6;33804:3;33727:89;:::i;:::-;33720:96;;33825:52;33870:6;33865:3;33858:4;33851:5;33847:16;33825:52;:::i;:::-;33902:6;33897:3;33893:16;33886:23;;33648:267;33538:377;;;;:::o;33921:155::-;34061:7;34057:1;34049:6;34045:14;34038:31;33921:155;:::o;34082:400::-;34242:3;34263:84;34345:1;34340:3;34263:84;:::i;:::-;34256:91;;34356:93;34445:3;34356:93;:::i;:::-;34474:1;34469:3;34465:11;34458:18;;34082:400;;;:::o;34488:701::-;34769:3;34791:95;34882:3;34873:6;34791:95;:::i;:::-;34784:102;;34903:95;34994:3;34985:6;34903:95;:::i;:::-;34896:102;;35015:148;35159:3;35015:148;:::i;:::-;35008:155;;35180:3;35173:10;;34488:701;;;;;:::o;35195:225::-;35335:34;35331:1;35323:6;35319:14;35312:58;35404:8;35399:2;35391:6;35387:15;35380:33;35195:225;:::o;35426:366::-;35568:3;35589:67;35653:2;35648:3;35589:67;:::i;:::-;35582:74;;35665:93;35754:3;35665:93;:::i;:::-;35783:2;35778:3;35774:12;35767:19;;35426:366;;;:::o;35798:419::-;35964:4;36002:2;35991:9;35987:18;35979:26;;36051:9;36045:4;36041:20;36037:1;36026:9;36022:17;36015:47;36079:131;36205:4;36079:131;:::i;:::-;36071:139;;35798:419;;;:::o;36223:332::-;36344:4;36382:2;36371:9;36367:18;36359:26;;36395:71;36463:1;36452:9;36448:17;36439:6;36395:71;:::i;:::-;36476:72;36544:2;36533:9;36529:18;36520:6;36476:72;:::i;:::-;36223:332;;;;;:::o;36561:137::-;36615:5;36646:6;36640:13;36631:22;;36662:30;36686:5;36662:30;:::i;:::-;36561:137;;;;:::o;36704:345::-;36771:6;36820:2;36808:9;36799:7;36795:23;36791:32;36788:119;;;36826:79;;:::i;:::-;36788:119;36946:1;36971:61;37024:7;37015:6;37004:9;37000:22;36971:61;:::i;:::-;36961:71;;36917:125;36704:345;;;;:::o;37055:233::-;37094:3;37117:24;37135:5;37117:24;:::i;:::-;37108:33;;37163:66;37156:5;37153:77;37150:103;;37233:18;;:::i;:::-;37150:103;37280:1;37273:5;37269:13;37262:20;;37055:233;;;:::o;37294:180::-;37342:77;37339:1;37332:88;37439:4;37436:1;37429:15;37463:4;37460:1;37453:15;37480:185;37520:1;37537:20;37555:1;37537:20;:::i;:::-;37532:25;;37571:20;37589:1;37571:20;:::i;:::-;37566:25;;37610:1;37600:35;;37615:18;;:::i;:::-;37600:35;37657:1;37654;37650:9;37645:14;;37480:185;;;;:::o;37671:176::-;37703:1;37720:20;37738:1;37720:20;:::i;:::-;37715:25;;37754:20;37772:1;37754:20;:::i;:::-;37749:25;;37793:1;37783:35;;37798:18;;:::i;:::-;37783:35;37839:1;37836;37832:9;37827:14;;37671:176;;;;:::o;37853:180::-;37901:77;37898:1;37891:88;37998:4;37995:1;37988:15;38022:4;38019:1;38012:15;38039:98;38090:6;38124:5;38118:12;38108:22;;38039:98;;;:::o;38143:168::-;38226:11;38260:6;38255:3;38248:19;38300:4;38295:3;38291:14;38276:29;;38143:168;;;;:::o;38317:360::-;38403:3;38431:38;38463:5;38431:38;:::i;:::-;38485:70;38548:6;38543:3;38485:70;:::i;:::-;38478:77;;38564:52;38609:6;38604:3;38597:4;38590:5;38586:16;38564:52;:::i;:::-;38641:29;38663:6;38641:29;:::i;:::-;38636:3;38632:39;38625:46;;38407:270;38317:360;;;;:::o;38683:640::-;38878:4;38916:3;38905:9;38901:19;38893:27;;38930:71;38998:1;38987:9;38983:17;38974:6;38930:71;:::i;:::-;39011:72;39079:2;39068:9;39064:18;39055:6;39011:72;:::i;:::-;39093;39161:2;39150:9;39146:18;39137:6;39093:72;:::i;:::-;39212:9;39206:4;39202:20;39197:2;39186:9;39182:18;39175:48;39240:76;39311:4;39302:6;39240:76;:::i;:::-;39232:84;;38683:640;;;;;;;:::o;39329:141::-;39385:5;39416:6;39410:13;39401:22;;39432:32;39458:5;39432:32;:::i;:::-;39329:141;;;;:::o;39476:349::-;39545:6;39594:2;39582:9;39573:7;39569:23;39565:32;39562:119;;;39600:79;;:::i;:::-;39562:119;39720:1;39745:63;39800:7;39791:6;39780:9;39776:22;39745:63;:::i;:::-;39735:73;;39691:127;39476:349;;;;:::o

Swarm Source

ipfs://3aad9c0ef44c3c504cef82023070aef85de9848021d061acf73ddcde1a8163b5
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.