ETH Price: $2,691.75 (-1.56%)

Token

JTTribe (JTT)
 

Overview

Max Total Supply

441 JTT

Holders

110

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
germangleza.eth
Balance
6 JTT
0xE7423F67d92a124f9CecA08B0E96EA52ab8044aA
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:
JTTribe

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Unlicense license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-04-09
*/

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

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

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * 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.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
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 simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _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}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _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 sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _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}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _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)
        }
    }
}

// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

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

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

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

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

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

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

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

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

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

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

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

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

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

// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _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) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

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

/**
  ______ _____   _____ ______ ___  __ _  _  _ 
 |  ____|  __ \ / ____|____  |__ \/_ | || || |
 | |__  | |__) | |        / /   ) || | \| |/ |
 |  __| |  _  /| |       / /   / / | |\_   _/ 
 | |____| | \ \| |____  / /   / /_ | |  | |   
 |______|_|  \_\\_____|/_/   |____||_|  |_|   
 */

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

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

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

/**
 * @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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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);
}

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

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

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

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

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

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

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

/**
 * @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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

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

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }
}

/**
   _____       ___     ___ __           ____  _ __      
  / ___/____  / (_)___/ (_) /___  __   / __ )(_) /______
  \__ \/ __ \/ / / __  / / __/ / / /  / __  / / __/ ___/
 ___/ / /_/ / / / /_/ / / /_/ /_/ /  / /_/ / / /_(__  ) 
/____/\____/_/_/\__,_/_/\__/\__, /  /_____/_/\__/____/  
                           /____/                        
 */

/**
   _____       ___     ___ __           ____  _ __      
  / ___/____  / (_)___/ (_) /___  __   / __ )(_) /______
  \__ \/ __ \/ / / __  / / __/ / / /  / __  / / __/ ___/
 ___/ / /_/ / / / /_/ / / /_/ /_/ /  / /_/ / / /_(__  ) 
/____/\____/_/_/\__,_/_/\__/\__, /  /_____/_/\__/____/  
                           /____/                        
 */

library BitScan {
    uint256 constant private DEBRUIJN_256 = 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff;
    bytes constant private LOOKUP_TABLE_256 = hex"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8";

    /**
        @dev Isolate the least significant set bit.
     */ 
    function isolateLS1B256(uint256 bb) pure internal returns (uint256) {
        require(bb > 0);
        unchecked {
            return bb & (0 - bb);
        }
    } 

    /**
        @dev Isolate the most significant set bit.
     */ 
    function isolateMS1B256(uint256 bb) pure internal returns (uint256) {
        require(bb > 0);
        unchecked {
            bb |= bb >> 128;
            bb |= bb >> 64;
            bb |= bb >> 32;
            bb |= bb >> 16;
            bb |= bb >> 8;
            bb |= bb >> 4;
            bb |= bb >> 2;
            bb |= bb >> 1;
            
            return (bb >> 1) + 1;
        }
    } 

    /**
        @dev Find the index of the lest significant set bit. (trailing zero count)
     */ 
    function bitScanForward256(uint256 bb) pure internal returns (uint8) {
        unchecked {
            return uint8(LOOKUP_TABLE_256[(isolateLS1B256(bb) * DEBRUIJN_256) >> 248]);
        }   
    }

    /**
        @dev Find the index of the most significant set bit.
     */ 
    function bitScanReverse256(uint256 bb) pure internal returns (uint8) {
        unchecked {
            return 255 - uint8(LOOKUP_TABLE_256[((isolateMS1B256(bb) * DEBRUIJN_256) >> 248)]);
        }   
    }

    function log2(uint256 bb) pure internal returns (uint8) {
        unchecked {
            return uint8(LOOKUP_TABLE_256[(isolateMS1B256(bb) * DEBRUIJN_256) >> 248]);
        } 
    }
}

/**
   _____       ___     ___ __           ____  _ __      
  / ___/____  / (_)___/ (_) /___  __   / __ )(_) /______
  \__ \/ __ \/ / / __  / / __/ / / /  / __  / / __/ ___/
 ___/ / /_/ / / / /_/ / / /_/ /_/ /  / /_/ / / /_(__  ) 
/____/\____/_/_/\__,_/_/\__/\__, /  /_____/_/\__/____/  
                           /____/                        
 */

library Popcount {
    uint256 private constant m1 = 0x5555555555555555555555555555555555555555555555555555555555555555;
    uint256 private constant m2 = 0x3333333333333333333333333333333333333333333333333333333333333333;
    uint256 private constant m4 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;
    uint256 private constant h01 = 0x0101010101010101010101010101010101010101010101010101010101010101;

    function popcount256A(uint256 x) internal pure returns (uint256 count) {
        unchecked{
            for (count=0; x!=0; count++)
                x &= x - 1;
        }
    }

    function popcount256B(uint256 x) internal pure returns (uint256) {
        if (x == type(uint256).max) {
            return 256;
        }
        unchecked {
            x -= (x >> 1) & m1;             //put count of each 2 bits into those 2 bits
            x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits 
            x = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits 
            x = (x * h01) >> 248;  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ... 
        }
        return x;
    }
}

/**
 * @dev This Library is a modified version of Openzeppelin's BitMaps library with extra features.
 *
 * 1. Functions of finding the index of the closest set bit from a given index are added.
 *    The indexing of each bucket is modifed to count from the MSB to the LSB instead of from the LSB to the MSB.
 *    The modification of indexing makes finding the closest previous set bit more efficient in gas usage.
 * 2. Setting and unsetting the bitmap consecutively.
 * 3. Accounting number of set bits within a given range.   
 *
*/

/**
 * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.
 * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].
 */

library BitMaps {
    using BitScan for uint256;
    uint256 private constant MASK_INDEX_ZERO = (1 << 255);
    uint256 private constant MASK_FULL = type(uint256).max;

    struct BitMap {
        mapping(uint256 => uint256) _data;
    }

    /**
     * @dev Returns whether the bit at `index` is set.
     */
    function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {
        uint256 bucket = index >> 8;
        uint256 mask = MASK_INDEX_ZERO >> (index & 0xff);
        return bitmap._data[bucket] & mask != 0;
    }

    /**
     * @dev Sets the bit at `index` to the boolean `value`.
     */
    function setTo(
        BitMap storage bitmap,
        uint256 index,
        bool value
    ) internal {
        if (value) {
            set(bitmap, index);
        } else {
            unset(bitmap, index);
        }
    }

    /**
     * @dev Sets the bit at `index`.
     */
    function set(BitMap storage bitmap, uint256 index) internal {
        uint256 bucket = index >> 8;
        uint256 mask = MASK_INDEX_ZERO >> (index & 0xff);
        bitmap._data[bucket] |= mask;
    }

    /**
     * @dev Unsets the bit at `index`.
     */
    function unset(BitMap storage bitmap, uint256 index) internal {
        uint256 bucket = index >> 8;
        uint256 mask = MASK_INDEX_ZERO >> (index & 0xff);
        bitmap._data[bucket] &= ~mask;
    }

    /**
     * @dev Consecutively sets `amount` of bits starting from the bit at `startIndex`.
     */    
    function setBatch(BitMap storage bitmap, uint256 startIndex, uint256 amount) internal {
        uint256 bucket = startIndex >> 8;

        uint256 bucketStartIndex = (startIndex & 0xff);

        unchecked {
            if(bucketStartIndex + amount < 256) {
                bitmap._data[bucket] |= MASK_FULL << (256 - amount) >> bucketStartIndex;
            } else {
                bitmap._data[bucket] |= MASK_FULL >> bucketStartIndex;
                amount -= (256 - bucketStartIndex);
                bucket++;

                while(amount > 256) {
                    bitmap._data[bucket] = MASK_FULL;
                    amount -= 256;
                    bucket++;
                }

                bitmap._data[bucket] |= MASK_FULL << (256 - amount);
            }
        }
    }

    /**
     * @dev Consecutively unsets `amount` of bits starting from the bit at `startIndex`.
     */    
    function unsetBatch(BitMap storage bitmap, uint256 startIndex, uint256 amount) internal {
        uint256 bucket = startIndex >> 8;

        uint256 bucketStartIndex = (startIndex & 0xff);

        unchecked {
            if(bucketStartIndex + amount < 256) {
                bitmap._data[bucket] &= ~(MASK_FULL << (256 - amount) >> bucketStartIndex);
            } else {
                bitmap._data[bucket] &= ~(MASK_FULL >> bucketStartIndex);
                amount -= (256 - bucketStartIndex);
                bucket++;

                while(amount > 256) {
                    bitmap._data[bucket] = 0;
                    amount -= 256;
                    bucket++;
                }

                bitmap._data[bucket] &= ~(MASK_FULL << (256 - amount));
            }
        }
    }

    /**
     * @dev Returns number of set bits within a range.
     */
    function popcountA(BitMap storage bitmap, uint256 startIndex, uint256 amount) internal view returns(uint256 count) {
        uint256 bucket = startIndex >> 8;

        uint256 bucketStartIndex = (startIndex & 0xff);

        unchecked {
            if(bucketStartIndex + amount < 256) {
                count +=  Popcount.popcount256A(
                    bitmap._data[bucket] & (MASK_FULL << (256 - amount) >> bucketStartIndex)
                );
            } else {
                count += Popcount.popcount256A(
                    bitmap._data[bucket] & (MASK_FULL >> bucketStartIndex)
                );
                amount -= (256 - bucketStartIndex);
                bucket++;

                while(amount > 256) {
                    count += Popcount.popcount256A(bitmap._data[bucket]);
                    amount -= 256;
                    bucket++;
                }
                count += Popcount.popcount256A(
                    bitmap._data[bucket] & (MASK_FULL << (256 - amount))
                );
            }
        }
    }

    /**
     * @dev Returns number of set bits within a range.
     */
    function popcountB(BitMap storage bitmap, uint256 startIndex, uint256 amount) internal view returns(uint256 count) {
        uint256 bucket = startIndex >> 8;

        uint256 bucketStartIndex = (startIndex & 0xff);

        unchecked {
            if(bucketStartIndex + amount < 256) {
                count +=  Popcount.popcount256B(
                    bitmap._data[bucket] & (MASK_FULL << (256 - amount) >> bucketStartIndex)
                );
            } else {
                count += Popcount.popcount256B(
                    bitmap._data[bucket] & (MASK_FULL >> bucketStartIndex)
                );
                amount -= (256 - bucketStartIndex);
                bucket++;

                while(amount > 256) {
                    count += Popcount.popcount256B(bitmap._data[bucket]);
                    amount -= 256;
                    bucket++;
                }
                count += Popcount.popcount256B(
                    bitmap._data[bucket] & (MASK_FULL << (256 - amount))
                );
            }
        }
    }

    /**
     * @dev Find the closest index of the set bit before `index`.
     */
    function scanForward(BitMap storage bitmap, uint256 index) internal view returns (uint256 setBitIndex) {
        uint256 bucket = index >> 8;

        // index within the bucket
        uint256 bucketIndex = (index & 0xff);

        // load a bitboard from the bitmap.
        uint256 bb = bitmap._data[bucket];

        // offset the bitboard to scan from `bucketIndex`.
        bb = bb >> (0xff ^ bucketIndex); // bb >> (255 - bucketIndex)
        
        if(bb > 0) {
            unchecked {
                setBitIndex = (bucket << 8) | (bucketIndex -  bb.bitScanForward256());    
            }
        } else {
            while(true) {
                require(bucket > 0, "BitMaps: The set bit before the index doesn't exist.");
                unchecked {
                    bucket--;
                }
                // No offset. Always scan from the least significiant bit now.
                bb = bitmap._data[bucket];
                
                if(bb > 0) {
                    unchecked {
                        setBitIndex = (bucket << 8) | (255 -  bb.bitScanForward256());
                        break;
                    }
                } 
            }
        }
    }

    function getBucket(BitMap storage bitmap, uint256 bucket) internal view returns (uint256) {
        return bitmap._data[bucket];
    }
}

contract ERC721Psi is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;
    using BitMaps for BitMaps.BitMap;

    BitMaps.BitMap private _batchHead;

    string private _name;
    string private _symbol;

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

    mapping(uint256 => address) private _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    /**
     * @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_;
        _currentIndex = _startTokenId();
    }

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal pure returns (uint256) {
        // It will become modifiable in the future versions
        return 1;
    }

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

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        return _currentIndex - _startTokenId();
    }

    /**
     * @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 (uint) 
    {
        require(owner != address(0), "ERC721Psi: balance query for the zero address");

        uint count;
        for( uint i = _startTokenId(); i < _nextTokenId(); ++i ){
            if(_exists(i)){
                if( owner == ownerOf(i)){
                    ++count;
                }
            }
        }
        return count;
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        (address owner, ) = _ownerAndBatchHeadOf(tokenId);
        return owner;
    }

    function _ownerAndBatchHeadOf(uint256 tokenId) internal view returns (address owner, uint256 tokenIdBatchHead){
        require(_exists(tokenId), "ERC721Psi: owner query for nonexistent token");
        tokenIdBatchHead = _getBatchHead(tokenId);
        owner = _owners[tokenIdBatchHead];
    }

    /**
     * @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), "ERC721Psi: URI query for nonexistent token");

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

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

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

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721Psi: 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),
            "ERC721Psi: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        require(operator != _msgSender(), "ERC721Psi: approve to caller");

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721Psi: 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),
            "ERC721Psi: 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, 1,_data),
            "ERC721Psi: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return tokenId < _nextTokenId() && _startTokenId() <= tokenId;
    }

    /**
     * @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),
            "ERC721Psi: operator query for nonexistent token"
        );
        address owner = ownerOf(tokenId);
        return (spender == owner ||
            getApproved(tokenId) == spender ||
            isApprovedForAll(owner, spender));
    }

    /**
     * @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) internal virtual {
        _safeMint(to, quantity, "");
    }

    
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        uint256 nextTokenId = _nextTokenId();
        _mint(to, quantity);
        require(
            _checkOnERC721Received(address(0), to, nextTokenId, quantity, _data),
            "ERC721Psi: transfer to non ERC721Receiver implementer"
        );
    }

    function _mint(
        address to,
        uint256 quantity
    ) internal virtual {
        uint256 nextTokenId = _nextTokenId();
        
        require(quantity > 0, "ERC721Psi: quantity must be greater 0");
        require(to != address(0), "ERC721Psi: mint to the zero address");
        
        _beforeTokenTransfers(address(0), to, nextTokenId, quantity);
        _currentIndex += quantity;
        _owners[nextTokenId] = to;
        _batchHead.set(nextTokenId);

        uint256 toMasked;
        uint256 end = nextTokenId + quantity;

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

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

        _afterTokenTransfers(address(0), to, nextTokenId, quantity);
    }

    /**
     * @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 {
        (address owner, uint256 tokenIdBatchHead) = _ownerAndBatchHeadOf(tokenId);

        require(
            owner == from,
            "ERC721Psi: transfer of token that is not own"
        );
        require(to != address(0), "ERC721Psi: transfer to the zero address");

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        uint256 subsequentTokenId = tokenId + 1;

        if(!_batchHead.get(subsequentTokenId) &&  
            subsequentTokenId < _nextTokenId()
        ) {
            _owners[subsequentTokenId] = from;
            _batchHead.set(subsequentTokenId);
        }

        _owners[tokenId] = to;
        if(tokenId != tokenIdBatchHead) {
            _batchHead.set(tokenId);
        }

        emit Transfer(from, to, tokenId);

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

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

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

    function _getBatchHead(uint256 tokenId) internal view returns (uint256 tokenIdBatchHead) {
        tokenIdBatchHead = _batchHead.scanForward(tokenId); 
    }

    function totalSupply() public virtual view returns (uint256) {
        return _totalMinted();
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * This function is compatiable with ERC721AQueryable.
     */
    function tokensOfOwner(address owner) external view virtual returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                if (_exists(i)) {
                    if (ownerOf(i) == owner) {
                        tokenIds[tokenIdsIdx++] = i;
                    }
                }
            }
            return tokenIds;   
        }
    }

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

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

contract JTTribe is ERC721Psi, Ownable {
    using Strings for uint256;
    using MerkleProof for bytes32[];

    uint256 public supply;
    uint256 public price;
    string public baseURI;
    string public hiddenBaseURI;
    bool public reveal = false;
    bool public paused = false;
    bytes32 public merkleProof;

    mapping(uint256 => bytes32) public _whitelistRoot;

    constructor(
        string memory _baseUri, 
        string memory _hiddenBaseURI, 
        uint256 _price,
        uint256 _supply
        ) ERC721Psi("JTTribe", "JTT") {
        baseURI = _baseUri;
        hiddenBaseURI = _hiddenBaseURI;
        price = _price;
        supply = _supply;
    }

    /**
     * @dev Simple mint of the NFT
     */
    function mint() public payable {
        require(totalSupply() <= supply, "cannot mint more than supply");
        require(msg.value == price, "set correct price");
        _safeMint(msg.sender, 1);
    }

    /**
     * @dev Function to mint with Crossmint
     */
    function crossmint(address _to, uint256 _quantity) public payable {
        require(totalSupply() <= supply, "cannot mint more than supply");
        uint256 amount = _quantity * price; 
        require(msg.value == amount, "set correct price"); 
        _safeMint(_to, _quantity);
    }

    /**
     * @dev Function to give NFTs for free only being set by Owner
     */
    function claimNFT(bytes32[] calldata _merkleProof) external payable {
        require(paused == true, "function is in pause");
        require(totalSupply() <= supply, "cannot mint more than supply");
        require(verifyWhitelist(msg.sender, 1, _merkleProof), "not in the whitelist");
        _safeMint(msg.sender, 1);
    }

    /** 
     * @dev Function to withdraw only to owner
     */
    function withdraw() public onlyOwner {
        uint256 balance = address(this).balance;
        (bool success, ) = payable(owner()).call{value: balance}("");
        require(success);
    }

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

    function toBytes32(address addr) pure internal returns (bytes32){
        return bytes32(uint256(uint160(addr)));
    }

    /***************************************/
    /********** AIRDROP FUNCTIONS **********/
    /***************************************/

    function giveMultiNFTSender(address _to, uint256 _amount) public onlyOwner {
        require(totalSupply() <= supply, "cannot claim more than supply");
        _safeMint(_to, _amount);
    }

    function giveMultipleNFTSenders(address[] memory _recipients, uint256[] memory _amounts) public onlyOwner {
        require(_recipients.length == _amounts.length, "arrays length mismatch");
        require(totalSupply() + _recipients.length <= supply, "cannot claim more than supply");
        for (uint i = 0; i < _recipients.length; i++) {
            _safeMint(_recipients[i], _amounts[i]);
        }
    }

    /**************************************/
    /********** SETTER FUNCTIONS **********/
    /**************************************/

    function setPause(bool _paused) public onlyOwner {
        paused = _paused;
    }

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

    function setSupply(uint256 _newSupply) public onlyOwner {
        supply = _newSupply;
    }

    function setURI(string memory _newURI) public onlyOwner {
        baseURI = _newURI;
    }

    function setHiddenURI(string memory _newHiddenURI) public onlyOwner {
        hiddenBaseURI = _newHiddenURI;
    }

    function setReveal(bool _reveal) public onlyOwner {
        reveal = _reveal;
    }

    function setWhitelistRoot(uint256 sale, bytes32 _merkleRoot) public onlyOwner {
        _whitelistRoot[sale] = _merkleRoot;
    }

    /**************************************/
    /********** VIEW FUNCTIONS **********/
    /**************************************/

    function tokenURI(uint256 _tokenId) public view override returns (string memory) {
        require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _base = _baseURI();
        if (reveal == false) {
            return string(abi.encodePacked(hiddenBaseURI, "hidden.json"));
        } else {
            return bytes(_base).length > 0 ? string(abi.encodePacked(_base, _tokenId.toString(), ".json")) : "";
        }
    }

    function verifyWhitelist(address user, uint256 sale, bytes32[] calldata _merkleProof) public view returns(bool) {
        bytes32 leaf = keccak256(abi.encodePacked(user, sale));
        return _merkleProof.verify(_whitelistRoot[sale], leaf);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_baseUri","type":"string"},{"internalType":"string","name":"_hiddenBaseURI","type":"string"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_supply","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_whitelistRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"claimNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"crossmint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"giveMultiNFTSender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"giveMultipleNFTSenders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"hiddenBaseURI","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":"merkleProof","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","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":"_newHiddenURI","type":"string"}],"name":"setHiddenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_reveal","type":"bool"}],"name":"setReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newSupply","type":"uint256"}],"name":"setSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newURI","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sale","type":"uint256"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setWhitelistRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":"address","name":"user","type":"address"},{"internalType":"uint256","name":"sale","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"verifyWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600c805461ffff191690553480156200001c57600080fd5b5060405162002e1c38038062002e1c8339810160408190526200003f91620001f5565b604051806040016040528060078152602001664a54547269626560c81b8152506040518060400160405280600381526020016212951560ea1b81525081600190816200008c9190620002fe565b5060026200009b8282620002fe565b5050600160045550620000ae33620000de565b600a620000bc8582620002fe565b50600b620000cb8482620002fe565b5060099190915560085550620003ca9050565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200015857600080fd5b81516001600160401b038082111562000175576200017562000130565b604051601f8301601f19908116603f01168101908282118183101715620001a057620001a062000130565b81604052838152602092508683858801011115620001bd57600080fd5b600091505b83821015620001e15785820183015181830184015290820190620001c2565b600093810190920192909252949350505050565b600080600080608085870312156200020c57600080fd5b84516001600160401b03808211156200022457600080fd5b620002328883890162000146565b955060208701519150808211156200024957600080fd5b50620002588782880162000146565b604087015160609097015195989097509350505050565b600181811c908216806200028457607f821691505b602082108103620002a557634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002f957600081815260208120601f850160051c81016020861015620002d45750805b601f850160051c820191505b81811015620002f557828155600101620002e0565b5050505b505050565b81516001600160401b038111156200031a576200031a62000130565b62000332816200032b84546200026f565b84620002ab565b602080601f8311600181146200036a5760008415620003515750858301515b600019600386901b1c1916600185901b178555620002f5565b600085815260208120601f198616915b828110156200039b578886015182559484019460019091019084016200037a565b5085821015620003ba5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612a4280620003da6000396000f3fe60806040526004361061023b5760003560e01c80636c0360eb1161012e578063a22cb465116100ab578063c87b56dd1161006f578063c87b56dd1461066b578063e985e9c51461068b578063edf8cb60146106ab578063f2fde38b146106be578063f5cec9aa146106de57600080fd5b8063a22cb465146105d1578063a475b5dd146105f1578063b88d4fde1461060b578063bbaac02f1461062b578063bedb86fb1461064b57600080fd5b806385a32894116100f257806385a32894146105485780638da5cb5b1461056857806391b7f5ed1461058657806395d89b41146105a6578063a035b1fe146105bb57600080fd5b80636c0360eb146104bc57806370a08231146104d1578063715018a6146104f15780638128f9ff146105065780638462151c1461051b57600080fd5b80632a3f300c116101bc5780634018ef55116101805780634018ef551461042a57806342842e0e1461044a57806358891a371461046a5780635c975abb1461047d5780636352211e1461049c57600080fd5b80632a3f300c146103925780633009d76c146103b2578063361c15ae146103c85780633b4c4b25146103f55780633ccfd60b1461041557600080fd5b8063095ea7b311610203578063095ea7b31461031557806311276eb3146103355780631249c58b1461035557806318160ddd1461035d57806323b872dd1461037257600080fd5b806301ffc9a71461024057806302fe530514610275578063047fc9aa1461029757806306fdde03146102bb578063081812fc146102dd575b600080fd5b34801561024c57600080fd5b5061026061025b366004611f99565b6106fe565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b50610295610290366004612055565b610750565b005b3480156102a357600080fd5b506102ad60085481565b60405190815260200161026c565b3480156102c757600080fd5b506102d0610768565b60405161026c91906120ee565b3480156102e957600080fd5b506102fd6102f8366004612101565b6107fa565b6040516001600160a01b03909116815260200161026c565b34801561032157600080fd5b50610295610330366004612136565b61088a565b34801561034157600080fd5b506102956103503660046121ef565b6109a1565b610295610ab2565b34801561036957600080fd5b506102ad610b2d565b34801561037e57600080fd5b5061029561038d3660046122af565b610b3c565b34801561039e57600080fd5b506102956103ad3660046122fb565b610b6d565b3480156103be57600080fd5b506102ad600d5481565b3480156103d457600080fd5b506102ad6103e3366004612101565b600e6020526000908152604090205481565b34801561040157600080fd5b50610295610410366004612101565b610b88565b34801561042157600080fd5b50610295610b95565b34801561043657600080fd5b50610295610445366004612136565b610c0f565b34801561045657600080fd5b506102956104653660046122af565b610c7a565b610295610478366004612136565b610c95565b34801561048957600080fd5b50600c5461026090610100900460ff1681565b3480156104a857600080fd5b506102fd6104b7366004612101565b610d1d565b3480156104c857600080fd5b506102d0610d31565b3480156104dd57600080fd5b506102ad6104ec366004612316565b610dbf565b3480156104fd57600080fd5b50610295610e8e565b34801561051257600080fd5b506102d0610ea0565b34801561052757600080fd5b5061053b610536366004612316565b610ead565b60405161026c9190612331565b34801561055457600080fd5b50610295610563366004612375565b610f74565b34801561057457600080fd5b506007546001600160a01b03166102fd565b34801561059257600080fd5b506102956105a1366004612101565b610f8e565b3480156105b257600080fd5b506102d0610f9b565b3480156105c757600080fd5b506102ad60095481565b3480156105dd57600080fd5b506102956105ec366004612397565b610faa565b3480156105fd57600080fd5b50600c546102609060ff1681565b34801561061757600080fd5b506102956106263660046123ca565b61106e565b34801561063757600080fd5b50610295610646366004612055565b6110a6565b34801561065757600080fd5b506102956106663660046122fb565b6110ba565b34801561067757600080fd5b506102d0610686366004612101565b6110dc565b34801561069757600080fd5b506102606106a6366004612446565b6111d6565b6102956106b93660046124bc565b611204565b3480156106ca57600080fd5b506102956106d9366004612316565b6112dc565b3480156106ea57600080fd5b506102606106f93660046124fe565b611355565b60006001600160e01b031982166380ac58cd60e01b148061072f57506001600160e01b03198216635b5e139f60e01b145b8061074a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6107586113f7565b600a61076482826125d2565b5050565b60606001805461077790612558565b80601f01602080910402602001604051908101604052809291908181526020018280546107a390612558565b80156107f05780601f106107c5576101008083540402835291602001916107f0565b820191906000526020600020905b8154815290600101906020018083116107d357829003601f168201915b5050505050905090565b600061080582611451565b61086e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084015b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061089582610d1d565b9050806001600160a01b0316836001600160a01b0316036109045760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b6064820152608401610865565b336001600160a01b0382161480610920575061092081336111d6565b6109925760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527f206f776e6572206e6f7220617070726f76656420666f7220616c6c00000000006064820152608401610865565b61099c838361146d565b505050565b6109a96113f7565b80518251146109f35760405162461bcd60e51b81526020600482015260166024820152750c2e4e4c2f2e640d8cadccee8d040dad2e6dac2e8c6d60531b6044820152606401610865565b6008548251610a00610b2d565b610a0a91906126a8565b1115610a585760405162461bcd60e51b815260206004820152601d60248201527f63616e6e6f7420636c61696d206d6f7265207468616e20737570706c790000006044820152606401610865565b60005b825181101561099c57610aa0838281518110610a7957610a796126bb565b6020026020010151838381518110610a9357610a936126bb565b60200260200101516114db565b80610aaa816126d1565b915050610a5b565b600854610abd610b2d565b1115610adb5760405162461bcd60e51b8152600401610865906126ea565b6009543414610b205760405162461bcd60e51b815260206004820152601160248201527073657420636f727265637420707269636560781b6044820152606401610865565b610b2b3360016114db565b565b6000610b376114f5565b905090565b610b463382611506565b610b625760405162461bcd60e51b815260040161086590612721565b61099c8383836115d3565b610b756113f7565b600c805460ff1916911515919091179055565b610b906113f7565b600855565b610b9d6113f7565b476000610bb26007546001600160a01b031690565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610bfc576040519150601f19603f3d011682016040523d82523d6000602084013e610c01565b606091505b505090508061076457600080fd5b610c176113f7565b600854610c22610b2d565b1115610c705760405162461bcd60e51b815260206004820152601d60248201527f63616e6e6f7420636c61696d206d6f7265207468616e20737570706c790000006044820152606401610865565b61076482826114db565b61099c8383836040518060200160405280600081525061106e565b600854610ca0610b2d565b1115610cbe5760405162461bcd60e51b8152600401610865906126ea565b600060095482610cce9190612775565b9050803414610d135760405162461bcd60e51b815260206004820152601160248201527073657420636f727265637420707269636560781b6044820152606401610865565b61099c83836114db565b600080610d29836117c0565b509392505050565b600a8054610d3e90612558565b80601f0160208091040260200160405190810160405280929190818152602001828054610d6a90612558565b8015610db75780601f10610d8c57610100808354040283529160200191610db7565b820191906000526020600020905b815481529060010190602001808311610d9a57829003601f168201915b505050505081565b60006001600160a01b038216610e2d5760405162461bcd60e51b815260206004820152602d60248201527f4552433732315073693a2062616c616e636520717565727920666f722074686560448201526c207a65726f206164647265737360981b6064820152608401610865565b600060015b600454811015610e8757610e4581611451565b15610e7757610e5381610d1d565b6001600160a01b0316846001600160a01b031603610e7757610e74826126d1565b91505b610e80816126d1565b9050610e32565b5092915050565b610e966113f7565b610b2b6000611857565b600b8054610d3e90612558565b6060600080610ebb84610dbf565b905060008167ffffffffffffffff811115610ed857610ed8611fb6565b604051908082528060200260200182016040528015610f01578160200160208202803683370190505b50905060015b828414610f6b57610f1781611451565b15610f6357856001600160a01b0316610f2f82610d1d565b6001600160a01b031603610f635780828580600101965081518110610f5657610f566126bb565b6020026020010181815250505b600101610f07565b50949350505050565b610f7c6113f7565b6000918252600e602052604090912055565b610f966113f7565b600955565b60606002805461077790612558565b336001600160a01b038316036110025760405162461bcd60e51b815260206004820152601c60248201527f4552433732315073693a20617070726f766520746f2063616c6c6572000000006044820152606401610865565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6110783383611506565b6110945760405162461bcd60e51b815260040161086590612721565b6110a0848484846118a9565b50505050565b6110ae6113f7565b600b61076482826125d2565b6110c26113f7565b600c80549115156101000261ff0019909216919091179055565b60606110e782611451565b61114b5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610865565b60006111556118de565b600c5490915060ff16151560000361119057600b604051602001611179919061278c565b604051602081830303815290604052915050919050565b60008151116111ae57604051806020016040528060008152506111c9565b806111b8846118ed565b604051602001611179929190612815565b9392505050565b50919050565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b600c5460ff6101009091041615156001146112585760405162461bcd60e51b815260206004820152601460248201527366756e6374696f6e20697320696e20706175736560601b6044820152606401610865565b600854611263610b2d565b11156112815760405162461bcd60e51b8152600401610865906126ea565b61128e3360018484611355565b6112d15760405162461bcd60e51b81526020600482015260146024820152731b9bdd081a5b881d1a19481dda1a5d195b1a5cdd60621b6044820152606401610865565b6107643360016114db565b6112e46113f7565b6001600160a01b0381166113495760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610865565b61135281611857565b50565b6040516bffffffffffffffffffffffff19606086901b1660208201526034810184905260009081906054016040516020818303038152906040528051906020012090506113ed600e600087815260200190815260200160002054828686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509294939250506119809050565b9695505050505050565b6007546001600160a01b03163314610b2b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610865565b600061145c60045490565b8210801561074a5750506001111590565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906114a282610d1d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b610764828260405180602001604052806000815250611996565b60006001600454610b379190612854565b600061151182611451565b6115755760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610865565b600061158083610d1d565b9050806001600160a01b0316846001600160a01b031614806115bb5750836001600160a01b03166115b0846107fa565b6001600160a01b0316145b806115cb57506115cb81856111d6565b949350505050565b6000806115df836117c0565b91509150846001600160a01b0316826001600160a01b0316146116595760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b6064820152608401610865565b6001600160a01b0384166116bf5760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b6064820152608401610865565b6116ca60008461146d565b60006116d78460016126a8565b600881901c600090815260208190526040902054909150600160ff1b60ff83161c16158015611707575060045481105b1561173d57600081815260036020526040812080546001600160a01b0319166001600160a01b03891617905561173d90826119bb565b600084815260036020526040902080546001600160a01b0319166001600160a01b038716179055818414611776576117766000856119bb565b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b6000806117cc83611451565b61182d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610865565b611836836119e7565b6000818152600360205260409020546001600160a01b031694909350915050565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6118b48484846115d3565b6118c28484846001856119f3565b6110a05760405162461bcd60e51b815260040161086590612867565b6060600a805461077790612558565b606060006118fa83611b2a565b600101905060008167ffffffffffffffff81111561191a5761191a611fb6565b6040519080825280601f01601f191660200182016040528015611944576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461194e57509392505050565b60008261198d8584611c02565b14949350505050565b60006119a160045490565b90506119ad8484611c47565b6118c26000858386866119f3565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b600061074a8183611ddd565b60006001600160a01b0385163b15611b1d57506001835b611a1484866126a8565b811015611b1757604051630a85bd0160e11b81526001600160a01b0387169063150b7a0290611a4d9033908b90869089906004016128bc565b6020604051808303816000875af1925050508015611a88575060408051601f3d908101601f19168201909252611a85918101906128ef565b60015b611ae5573d808015611ab6576040519150601f19603f3d011682016040523d82523d6000602084013e611abb565b606091505b508051600003611add5760405162461bcd60e51b815260040161086590612867565b805181602001fd5b828015611b0257506001600160e01b03198116630a85bd0160e11b145b92505080611b0f816126d1565b915050611a0a565b50611b21565b5060015b95945050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611b695772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611b95576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611bb357662386f26fc10000830492506010015b6305f5e1008310611bcb576305f5e100830492506008015b6127108310611bdf57612710830492506004015b60648310611bf1576064830492506002015b600a831061074a5760010192915050565b600081815b8451811015610d2957611c3382868381518110611c2657611c266126bb565b6020026020010151611ed5565b915080611c3f816126d1565b915050611c07565b6000611c5260045490565b905060008211611cb25760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b6064820152608401610865565b6001600160a01b038316611d145760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610865565b8160046000828254611d2691906126a8565b9091555050600081815260036020526040812080546001600160a01b0319166001600160a01b038616179055611d5c90826119bb565b600080611d6984846126a8565b90506001600160a01b0385169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146117b857808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101611da5565b600881901c60008181526020849052604081205490919060ff808516919082181c8015611e1f57611e0d81611f01565b60ff168203600884901b179350611ecc565b60008311611e8c5760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b6064820152608401610865565b506000199091016000818152602086905260409020549091908015611ec757611eb481611f01565b60ff0360ff16600884901b179350611ecc565b611e1f565b50505092915050565b6000818310611ef15760008281526020849052604090206111c9565b5060009182526020526040902090565b6000604051806101200160405280610100815260200161290d610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff611f4a85611f6b565b02901c81518110611f5d57611f5d6126bb565b016020015160f81c92915050565b6000808211611f7957600080fd5b5060008190031690565b6001600160e01b03198116811461135257600080fd5b600060208284031215611fab57600080fd5b81356111c981611f83565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611ff557611ff5611fb6565b604052919050565b600067ffffffffffffffff83111561201757612017611fb6565b61202a601f8401601f1916602001611fcc565b905082815283838301111561203e57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561206757600080fd5b813567ffffffffffffffff81111561207e57600080fd5b8201601f8101841361208f57600080fd5b6115cb84823560208401611ffd565b60005b838110156120b95781810151838201526020016120a1565b50506000910152565b600081518084526120da81602086016020860161209e565b601f01601f19169290920160200192915050565b6020815260006111c960208301846120c2565b60006020828403121561211357600080fd5b5035919050565b80356001600160a01b038116811461213157600080fd5b919050565b6000806040838503121561214957600080fd5b6121528361211a565b946020939093013593505050565b600067ffffffffffffffff82111561217a5761217a611fb6565b5060051b60200190565b600082601f83011261219557600080fd5b813560206121aa6121a583612160565b611fcc565b82815260059290921b840181019181810190868411156121c957600080fd5b8286015b848110156121e457803583529183019183016121cd565b509695505050505050565b6000806040838503121561220257600080fd5b823567ffffffffffffffff8082111561221a57600080fd5b818501915085601f83011261222e57600080fd5b8135602061223e6121a583612160565b82815260059290921b8401810191818101908984111561225d57600080fd5b948201945b83861015612282576122738661211a565b82529482019490820190612262565b9650508601359250508082111561229857600080fd5b506122a585828601612184565b9150509250929050565b6000806000606084860312156122c457600080fd5b6122cd8461211a565b92506122db6020850161211a565b9150604084013590509250925092565b8035801515811461213157600080fd5b60006020828403121561230d57600080fd5b6111c9826122eb565b60006020828403121561232857600080fd5b6111c98261211a565b6020808252825182820181905260009190848201906040850190845b818110156123695783518352928401929184019160010161234d565b50909695505050505050565b6000806040838503121561238857600080fd5b50508035926020909101359150565b600080604083850312156123aa57600080fd5b6123b38361211a565b91506123c1602084016122eb565b90509250929050565b600080600080608085870312156123e057600080fd5b6123e98561211a565b93506123f76020860161211a565b925060408501359150606085013567ffffffffffffffff81111561241a57600080fd5b8501601f8101871361242b57600080fd5b61243a87823560208401611ffd565b91505092959194509250565b6000806040838503121561245957600080fd5b6124628361211a565b91506123c16020840161211a565b60008083601f84011261248257600080fd5b50813567ffffffffffffffff81111561249a57600080fd5b6020830191508360208260051b85010111156124b557600080fd5b9250929050565b600080602083850312156124cf57600080fd5b823567ffffffffffffffff8111156124e657600080fd5b6124f285828601612470565b90969095509350505050565b6000806000806060858703121561251457600080fd5b61251d8561211a565b935060208501359250604085013567ffffffffffffffff81111561254057600080fd5b61254c87828801612470565b95989497509550505050565b600181811c9082168061256c57607f821691505b6020821081036111d057634e487b7160e01b600052602260045260246000fd5b601f82111561099c57600081815260208120601f850160051c810160208610156125b35750805b601f850160051c820191505b818110156117b8578281556001016125bf565b815167ffffffffffffffff8111156125ec576125ec611fb6565b612600816125fa8454612558565b8461258c565b602080601f831160018114612635576000841561261d5750858301515b600019600386901b1c1916600185901b1785556117b8565b600085815260208120601f198616915b8281101561266457888601518255948401946001909101908401612645565b50858210156126825787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b8082018082111561074a5761074a612692565b634e487b7160e01b600052603260045260246000fd5b6000600182016126e3576126e3612692565b5060010190565b6020808252601c908201527f63616e6e6f74206d696e74206d6f7265207468616e20737570706c7900000000604082015260600190565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b808202811582820484141761074a5761074a612692565b600080835461279a81612558565b600182811680156127b257600181146127c7576127f6565b60ff19841687528215158302870194506127f6565b8760005260208060002060005b858110156127ed5781548a8201529084019082016127d4565b50505082870194505b50506a3434b23232b7173539b7b760a91b83525050600b019392505050565b6000835161282781846020880161209e565b83519083019061283b81836020880161209e565b64173539b7b760d91b9101908152600501949350505050565b8181038181111561074a5761074a612692565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906113ed908301846120c2565b60006020828403121561290157600080fd5b81516111c981611f8356fe0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212204158aafb7d2449b6f12c1c7ee164d007d55ef889f5a370be15b2545105818a0f64736f6c63430008130033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000016345785d8a0000000000000000000000000000000000000000000000000000000000000000115c0000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d54503131597a75515859656a726657476f50575078377a7353644d4561715733667a646e39757a4c7554534d2f000000000000000000000000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d506631445357617848316a7a36725a466a64466e6475767156377a4d744e41796839676d43634742466259582f00000000000000000000

Deployed Bytecode

0x60806040526004361061023b5760003560e01c80636c0360eb1161012e578063a22cb465116100ab578063c87b56dd1161006f578063c87b56dd1461066b578063e985e9c51461068b578063edf8cb60146106ab578063f2fde38b146106be578063f5cec9aa146106de57600080fd5b8063a22cb465146105d1578063a475b5dd146105f1578063b88d4fde1461060b578063bbaac02f1461062b578063bedb86fb1461064b57600080fd5b806385a32894116100f257806385a32894146105485780638da5cb5b1461056857806391b7f5ed1461058657806395d89b41146105a6578063a035b1fe146105bb57600080fd5b80636c0360eb146104bc57806370a08231146104d1578063715018a6146104f15780638128f9ff146105065780638462151c1461051b57600080fd5b80632a3f300c116101bc5780634018ef55116101805780634018ef551461042a57806342842e0e1461044a57806358891a371461046a5780635c975abb1461047d5780636352211e1461049c57600080fd5b80632a3f300c146103925780633009d76c146103b2578063361c15ae146103c85780633b4c4b25146103f55780633ccfd60b1461041557600080fd5b8063095ea7b311610203578063095ea7b31461031557806311276eb3146103355780631249c58b1461035557806318160ddd1461035d57806323b872dd1461037257600080fd5b806301ffc9a71461024057806302fe530514610275578063047fc9aa1461029757806306fdde03146102bb578063081812fc146102dd575b600080fd5b34801561024c57600080fd5b5061026061025b366004611f99565b6106fe565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b50610295610290366004612055565b610750565b005b3480156102a357600080fd5b506102ad60085481565b60405190815260200161026c565b3480156102c757600080fd5b506102d0610768565b60405161026c91906120ee565b3480156102e957600080fd5b506102fd6102f8366004612101565b6107fa565b6040516001600160a01b03909116815260200161026c565b34801561032157600080fd5b50610295610330366004612136565b61088a565b34801561034157600080fd5b506102956103503660046121ef565b6109a1565b610295610ab2565b34801561036957600080fd5b506102ad610b2d565b34801561037e57600080fd5b5061029561038d3660046122af565b610b3c565b34801561039e57600080fd5b506102956103ad3660046122fb565b610b6d565b3480156103be57600080fd5b506102ad600d5481565b3480156103d457600080fd5b506102ad6103e3366004612101565b600e6020526000908152604090205481565b34801561040157600080fd5b50610295610410366004612101565b610b88565b34801561042157600080fd5b50610295610b95565b34801561043657600080fd5b50610295610445366004612136565b610c0f565b34801561045657600080fd5b506102956104653660046122af565b610c7a565b610295610478366004612136565b610c95565b34801561048957600080fd5b50600c5461026090610100900460ff1681565b3480156104a857600080fd5b506102fd6104b7366004612101565b610d1d565b3480156104c857600080fd5b506102d0610d31565b3480156104dd57600080fd5b506102ad6104ec366004612316565b610dbf565b3480156104fd57600080fd5b50610295610e8e565b34801561051257600080fd5b506102d0610ea0565b34801561052757600080fd5b5061053b610536366004612316565b610ead565b60405161026c9190612331565b34801561055457600080fd5b50610295610563366004612375565b610f74565b34801561057457600080fd5b506007546001600160a01b03166102fd565b34801561059257600080fd5b506102956105a1366004612101565b610f8e565b3480156105b257600080fd5b506102d0610f9b565b3480156105c757600080fd5b506102ad60095481565b3480156105dd57600080fd5b506102956105ec366004612397565b610faa565b3480156105fd57600080fd5b50600c546102609060ff1681565b34801561061757600080fd5b506102956106263660046123ca565b61106e565b34801561063757600080fd5b50610295610646366004612055565b6110a6565b34801561065757600080fd5b506102956106663660046122fb565b6110ba565b34801561067757600080fd5b506102d0610686366004612101565b6110dc565b34801561069757600080fd5b506102606106a6366004612446565b6111d6565b6102956106b93660046124bc565b611204565b3480156106ca57600080fd5b506102956106d9366004612316565b6112dc565b3480156106ea57600080fd5b506102606106f93660046124fe565b611355565b60006001600160e01b031982166380ac58cd60e01b148061072f57506001600160e01b03198216635b5e139f60e01b145b8061074a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6107586113f7565b600a61076482826125d2565b5050565b60606001805461077790612558565b80601f01602080910402602001604051908101604052809291908181526020018280546107a390612558565b80156107f05780601f106107c5576101008083540402835291602001916107f0565b820191906000526020600020905b8154815290600101906020018083116107d357829003601f168201915b5050505050905090565b600061080582611451565b61086e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084015b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061089582610d1d565b9050806001600160a01b0316836001600160a01b0316036109045760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b6064820152608401610865565b336001600160a01b0382161480610920575061092081336111d6565b6109925760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527f206f776e6572206e6f7220617070726f76656420666f7220616c6c00000000006064820152608401610865565b61099c838361146d565b505050565b6109a96113f7565b80518251146109f35760405162461bcd60e51b81526020600482015260166024820152750c2e4e4c2f2e640d8cadccee8d040dad2e6dac2e8c6d60531b6044820152606401610865565b6008548251610a00610b2d565b610a0a91906126a8565b1115610a585760405162461bcd60e51b815260206004820152601d60248201527f63616e6e6f7420636c61696d206d6f7265207468616e20737570706c790000006044820152606401610865565b60005b825181101561099c57610aa0838281518110610a7957610a796126bb565b6020026020010151838381518110610a9357610a936126bb565b60200260200101516114db565b80610aaa816126d1565b915050610a5b565b600854610abd610b2d565b1115610adb5760405162461bcd60e51b8152600401610865906126ea565b6009543414610b205760405162461bcd60e51b815260206004820152601160248201527073657420636f727265637420707269636560781b6044820152606401610865565b610b2b3360016114db565b565b6000610b376114f5565b905090565b610b463382611506565b610b625760405162461bcd60e51b815260040161086590612721565b61099c8383836115d3565b610b756113f7565b600c805460ff1916911515919091179055565b610b906113f7565b600855565b610b9d6113f7565b476000610bb26007546001600160a01b031690565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610bfc576040519150601f19603f3d011682016040523d82523d6000602084013e610c01565b606091505b505090508061076457600080fd5b610c176113f7565b600854610c22610b2d565b1115610c705760405162461bcd60e51b815260206004820152601d60248201527f63616e6e6f7420636c61696d206d6f7265207468616e20737570706c790000006044820152606401610865565b61076482826114db565b61099c8383836040518060200160405280600081525061106e565b600854610ca0610b2d565b1115610cbe5760405162461bcd60e51b8152600401610865906126ea565b600060095482610cce9190612775565b9050803414610d135760405162461bcd60e51b815260206004820152601160248201527073657420636f727265637420707269636560781b6044820152606401610865565b61099c83836114db565b600080610d29836117c0565b509392505050565b600a8054610d3e90612558565b80601f0160208091040260200160405190810160405280929190818152602001828054610d6a90612558565b8015610db75780601f10610d8c57610100808354040283529160200191610db7565b820191906000526020600020905b815481529060010190602001808311610d9a57829003601f168201915b505050505081565b60006001600160a01b038216610e2d5760405162461bcd60e51b815260206004820152602d60248201527f4552433732315073693a2062616c616e636520717565727920666f722074686560448201526c207a65726f206164647265737360981b6064820152608401610865565b600060015b600454811015610e8757610e4581611451565b15610e7757610e5381610d1d565b6001600160a01b0316846001600160a01b031603610e7757610e74826126d1565b91505b610e80816126d1565b9050610e32565b5092915050565b610e966113f7565b610b2b6000611857565b600b8054610d3e90612558565b6060600080610ebb84610dbf565b905060008167ffffffffffffffff811115610ed857610ed8611fb6565b604051908082528060200260200182016040528015610f01578160200160208202803683370190505b50905060015b828414610f6b57610f1781611451565b15610f6357856001600160a01b0316610f2f82610d1d565b6001600160a01b031603610f635780828580600101965081518110610f5657610f566126bb565b6020026020010181815250505b600101610f07565b50949350505050565b610f7c6113f7565b6000918252600e602052604090912055565b610f966113f7565b600955565b60606002805461077790612558565b336001600160a01b038316036110025760405162461bcd60e51b815260206004820152601c60248201527f4552433732315073693a20617070726f766520746f2063616c6c6572000000006044820152606401610865565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6110783383611506565b6110945760405162461bcd60e51b815260040161086590612721565b6110a0848484846118a9565b50505050565b6110ae6113f7565b600b61076482826125d2565b6110c26113f7565b600c80549115156101000261ff0019909216919091179055565b60606110e782611451565b61114b5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610865565b60006111556118de565b600c5490915060ff16151560000361119057600b604051602001611179919061278c565b604051602081830303815290604052915050919050565b60008151116111ae57604051806020016040528060008152506111c9565b806111b8846118ed565b604051602001611179929190612815565b9392505050565b50919050565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b600c5460ff6101009091041615156001146112585760405162461bcd60e51b815260206004820152601460248201527366756e6374696f6e20697320696e20706175736560601b6044820152606401610865565b600854611263610b2d565b11156112815760405162461bcd60e51b8152600401610865906126ea565b61128e3360018484611355565b6112d15760405162461bcd60e51b81526020600482015260146024820152731b9bdd081a5b881d1a19481dda1a5d195b1a5cdd60621b6044820152606401610865565b6107643360016114db565b6112e46113f7565b6001600160a01b0381166113495760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610865565b61135281611857565b50565b6040516bffffffffffffffffffffffff19606086901b1660208201526034810184905260009081906054016040516020818303038152906040528051906020012090506113ed600e600087815260200190815260200160002054828686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509294939250506119809050565b9695505050505050565b6007546001600160a01b03163314610b2b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610865565b600061145c60045490565b8210801561074a5750506001111590565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906114a282610d1d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b610764828260405180602001604052806000815250611996565b60006001600454610b379190612854565b600061151182611451565b6115755760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610865565b600061158083610d1d565b9050806001600160a01b0316846001600160a01b031614806115bb5750836001600160a01b03166115b0846107fa565b6001600160a01b0316145b806115cb57506115cb81856111d6565b949350505050565b6000806115df836117c0565b91509150846001600160a01b0316826001600160a01b0316146116595760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b6064820152608401610865565b6001600160a01b0384166116bf5760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b6064820152608401610865565b6116ca60008461146d565b60006116d78460016126a8565b600881901c600090815260208190526040902054909150600160ff1b60ff83161c16158015611707575060045481105b1561173d57600081815260036020526040812080546001600160a01b0319166001600160a01b03891617905561173d90826119bb565b600084815260036020526040902080546001600160a01b0319166001600160a01b038716179055818414611776576117766000856119bb565b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b6000806117cc83611451565b61182d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610865565b611836836119e7565b6000818152600360205260409020546001600160a01b031694909350915050565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6118b48484846115d3565b6118c28484846001856119f3565b6110a05760405162461bcd60e51b815260040161086590612867565b6060600a805461077790612558565b606060006118fa83611b2a565b600101905060008167ffffffffffffffff81111561191a5761191a611fb6565b6040519080825280601f01601f191660200182016040528015611944576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461194e57509392505050565b60008261198d8584611c02565b14949350505050565b60006119a160045490565b90506119ad8484611c47565b6118c26000858386866119f3565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b600061074a8183611ddd565b60006001600160a01b0385163b15611b1d57506001835b611a1484866126a8565b811015611b1757604051630a85bd0160e11b81526001600160a01b0387169063150b7a0290611a4d9033908b90869089906004016128bc565b6020604051808303816000875af1925050508015611a88575060408051601f3d908101601f19168201909252611a85918101906128ef565b60015b611ae5573d808015611ab6576040519150601f19603f3d011682016040523d82523d6000602084013e611abb565b606091505b508051600003611add5760405162461bcd60e51b815260040161086590612867565b805181602001fd5b828015611b0257506001600160e01b03198116630a85bd0160e11b145b92505080611b0f816126d1565b915050611a0a565b50611b21565b5060015b95945050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611b695772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611b95576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611bb357662386f26fc10000830492506010015b6305f5e1008310611bcb576305f5e100830492506008015b6127108310611bdf57612710830492506004015b60648310611bf1576064830492506002015b600a831061074a5760010192915050565b600081815b8451811015610d2957611c3382868381518110611c2657611c266126bb565b6020026020010151611ed5565b915080611c3f816126d1565b915050611c07565b6000611c5260045490565b905060008211611cb25760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b6064820152608401610865565b6001600160a01b038316611d145760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610865565b8160046000828254611d2691906126a8565b9091555050600081815260036020526040812080546001600160a01b0319166001600160a01b038616179055611d5c90826119bb565b600080611d6984846126a8565b90506001600160a01b0385169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146117b857808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101611da5565b600881901c60008181526020849052604081205490919060ff808516919082181c8015611e1f57611e0d81611f01565b60ff168203600884901b179350611ecc565b60008311611e8c5760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b6064820152608401610865565b506000199091016000818152602086905260409020549091908015611ec757611eb481611f01565b60ff0360ff16600884901b179350611ecc565b611e1f565b50505092915050565b6000818310611ef15760008281526020849052604090206111c9565b5060009182526020526040902090565b6000604051806101200160405280610100815260200161290d610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff611f4a85611f6b565b02901c81518110611f5d57611f5d6126bb565b016020015160f81c92915050565b6000808211611f7957600080fd5b5060008190031690565b6001600160e01b03198116811461135257600080fd5b600060208284031215611fab57600080fd5b81356111c981611f83565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611ff557611ff5611fb6565b604052919050565b600067ffffffffffffffff83111561201757612017611fb6565b61202a601f8401601f1916602001611fcc565b905082815283838301111561203e57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561206757600080fd5b813567ffffffffffffffff81111561207e57600080fd5b8201601f8101841361208f57600080fd5b6115cb84823560208401611ffd565b60005b838110156120b95781810151838201526020016120a1565b50506000910152565b600081518084526120da81602086016020860161209e565b601f01601f19169290920160200192915050565b6020815260006111c960208301846120c2565b60006020828403121561211357600080fd5b5035919050565b80356001600160a01b038116811461213157600080fd5b919050565b6000806040838503121561214957600080fd5b6121528361211a565b946020939093013593505050565b600067ffffffffffffffff82111561217a5761217a611fb6565b5060051b60200190565b600082601f83011261219557600080fd5b813560206121aa6121a583612160565b611fcc565b82815260059290921b840181019181810190868411156121c957600080fd5b8286015b848110156121e457803583529183019183016121cd565b509695505050505050565b6000806040838503121561220257600080fd5b823567ffffffffffffffff8082111561221a57600080fd5b818501915085601f83011261222e57600080fd5b8135602061223e6121a583612160565b82815260059290921b8401810191818101908984111561225d57600080fd5b948201945b83861015612282576122738661211a565b82529482019490820190612262565b9650508601359250508082111561229857600080fd5b506122a585828601612184565b9150509250929050565b6000806000606084860312156122c457600080fd5b6122cd8461211a565b92506122db6020850161211a565b9150604084013590509250925092565b8035801515811461213157600080fd5b60006020828403121561230d57600080fd5b6111c9826122eb565b60006020828403121561232857600080fd5b6111c98261211a565b6020808252825182820181905260009190848201906040850190845b818110156123695783518352928401929184019160010161234d565b50909695505050505050565b6000806040838503121561238857600080fd5b50508035926020909101359150565b600080604083850312156123aa57600080fd5b6123b38361211a565b91506123c1602084016122eb565b90509250929050565b600080600080608085870312156123e057600080fd5b6123e98561211a565b93506123f76020860161211a565b925060408501359150606085013567ffffffffffffffff81111561241a57600080fd5b8501601f8101871361242b57600080fd5b61243a87823560208401611ffd565b91505092959194509250565b6000806040838503121561245957600080fd5b6124628361211a565b91506123c16020840161211a565b60008083601f84011261248257600080fd5b50813567ffffffffffffffff81111561249a57600080fd5b6020830191508360208260051b85010111156124b557600080fd5b9250929050565b600080602083850312156124cf57600080fd5b823567ffffffffffffffff8111156124e657600080fd5b6124f285828601612470565b90969095509350505050565b6000806000806060858703121561251457600080fd5b61251d8561211a565b935060208501359250604085013567ffffffffffffffff81111561254057600080fd5b61254c87828801612470565b95989497509550505050565b600181811c9082168061256c57607f821691505b6020821081036111d057634e487b7160e01b600052602260045260246000fd5b601f82111561099c57600081815260208120601f850160051c810160208610156125b35750805b601f850160051c820191505b818110156117b8578281556001016125bf565b815167ffffffffffffffff8111156125ec576125ec611fb6565b612600816125fa8454612558565b8461258c565b602080601f831160018114612635576000841561261d5750858301515b600019600386901b1c1916600185901b1785556117b8565b600085815260208120601f198616915b8281101561266457888601518255948401946001909101908401612645565b50858210156126825787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b8082018082111561074a5761074a612692565b634e487b7160e01b600052603260045260246000fd5b6000600182016126e3576126e3612692565b5060010190565b6020808252601c908201527f63616e6e6f74206d696e74206d6f7265207468616e20737570706c7900000000604082015260600190565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b808202811582820484141761074a5761074a612692565b600080835461279a81612558565b600182811680156127b257600181146127c7576127f6565b60ff19841687528215158302870194506127f6565b8760005260208060002060005b858110156127ed5781548a8201529084019082016127d4565b50505082870194505b50506a3434b23232b7173539b7b760a91b83525050600b019392505050565b6000835161282781846020880161209e565b83519083019061283b81836020880161209e565b64173539b7b760d91b9101908152600501949350505050565b8181038181111561074a5761074a612692565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906113ed908301846120c2565b60006020828403121561290157600080fd5b81516111c981611f8356fe0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212204158aafb7d2449b6f12c1c7ee164d007d55ef889f5a370be15b2545105818a0f64736f6c63430008130033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000016345785d8a0000000000000000000000000000000000000000000000000000000000000000115c0000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d54503131597a75515859656a726657476f50575078377a7353644d4561715733667a646e39757a4c7554534d2f000000000000000000000000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d506631445357617848316a7a36725a466a64466e6475767156377a4d744e41796839676d43634742466259582f00000000000000000000

-----Decoded View---------------
Arg [0] : _baseUri (string): ipfs://QmTP11YzuQXYejrfWGoPWPx7zsSdMEaqW3fzdn9uzLuTSM/
Arg [1] : _hiddenBaseURI (string): ipfs://QmPf1DSWaxH1jz6rZFjdFnduvqV7zMtNAyh9gmCcGBFbYX/
Arg [2] : _price (uint256): 100000000000000000
Arg [3] : _supply (uint256): 4444

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 000000000000000000000000000000000000000000000000016345785d8a0000
Arg [3] : 000000000000000000000000000000000000000000000000000000000000115c
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000036
Arg [5] : 697066733a2f2f516d54503131597a75515859656a726657476f50575078377a
Arg [6] : 7353644d4561715733667a646e39757a4c7554534d2f00000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000036
Arg [8] : 697066733a2f2f516d506631445357617848316a7a36725a466a64466e647576
Arg [9] : 7156377a4d744e41796839676d43634742466259582f00000000000000000000


Deployed Bytecode Sourcemap

79417:4799:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63165:355;;;;;;;;;;-1:-1:-1;63165:355:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;63165:355:0;;;;;;;;82888:92;;;;;;;;;;-1:-1:-1;82888:92:0;;;;;:::i;:::-;;:::i;:::-;;79535:21;;;;;;;;;;;;;;;;;;;2018:25:1;;;2006:2;1991:18;79535:21:0;1872:177:1;64731:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;66284:311::-;;;;;;;;;;-1:-1:-1;66284:311:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3159:32:1;;;3141:51;;3129:2;3114:18;66284:311:0;2995:203:1;65808:410:0;;;;;;;;;;-1:-1:-1;65808:410:0;;;;;:::i;:::-;;:::i;82033:415::-;;;;;;;;;;-1:-1:-1;82033:415:0;;;;;:::i;:::-;;:::i;80179:208::-;;;:::i;77195:101::-;;;;;;;;;;;;;:::i;67349:379::-;;;;;;;;;;-1:-1:-1;67349:379:0;;;;;:::i;:::-;;:::i;83112:85::-;;;;;;;;;;-1:-1:-1;83112:85:0;;;;;:::i;:::-;;:::i;79718:26::-;;;;;;;;;;;;;;;;79753:49;;;;;;;;;;-1:-1:-1;79753:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;82786:94;;;;;;;;;;-1:-1:-1;82786:94:0;;;;;:::i;:::-;;:::i;81251:193::-;;;;;;;;;;;;;:::i;81832:::-;;;;;;;;;;-1:-1:-1;81832:193:0;;;;;:::i;:::-;;:::i;67799:185::-;;;;;;;;;;-1:-1:-1;67799:185:0;;;;;:::i;:::-;;:::i;80458:292::-;;;;;;:::i;:::-;;:::i;79685:26::-;;;;;;;;;;-1:-1:-1;79685:26:0;;;;;;;;;;;64136:222;;;;;;;;;;-1:-1:-1;64136:222:0;;;;;:::i;:::-;;:::i;79590:21::-;;;;;;;;;;;;;:::i;63584:490::-;;;;;;;;;;-1:-1:-1;63584:490:0;;;;;:::i;:::-;;:::i;12135:103::-;;;;;;;;;;;;;:::i;79618:27::-;;;;;;;;;;;;;:::i;77592:601::-;;;;;;;;;;-1:-1:-1;77592:601:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;83205:131::-;;;;;;;;;;-1:-1:-1;83205:131:0;;;;;:::i;:::-;;:::i;11487:87::-;;;;;;;;;;-1:-1:-1;11560:6:0;;-1:-1:-1;;;;;11560:6:0;11487:87;;82688:90;;;;;;;;;;-1:-1:-1;82688:90:0;;;;;:::i;:::-;;:::i;64900:104::-;;;;;;;;;;;;;:::i;79563:20::-;;;;;;;;;;;;;;;;66667:330;;;;;;;;;;-1:-1:-1;66667:330:0;;;;;:::i;:::-;;:::i;79652:26::-;;;;;;;;;;-1:-1:-1;79652:26:0;;;;;;;;68055:368;;;;;;;;;;-1:-1:-1;68055:368:0;;;;;:::i;:::-;;:::i;82988:116::-;;;;;;;;;;-1:-1:-1;82988:116:0;;;;;:::i;:::-;;:::i;82596:84::-;;;;;;;;;;-1:-1:-1;82596:84:0;;;;;:::i;:::-;;:::i;83482:473::-;;;;;;;;;;-1:-1:-1;83482:473:0;;;;;:::i;:::-;;:::i;67068:214::-;;;;;;;;;;-1:-1:-1;67068:214:0;;;;;:::i;:::-;;:::i;80844:332::-;;;;;;:::i;:::-;;:::i;12393:201::-;;;;;;;;;;-1:-1:-1;12393:201:0;;;;;:::i;:::-;;:::i;83963:250::-;;;;;;;;;;-1:-1:-1;83963:250:0;;;;;:::i;:::-;;:::i;63165:355::-;63312:4;-1:-1:-1;;;;;;63354:40:0;;-1:-1:-1;;;63354:40:0;;:105;;-1:-1:-1;;;;;;;63411:48:0;;-1:-1:-1;;;63411:48:0;63354:105;:158;;;-1:-1:-1;;;;;;;;;;36647:40:0;;;63476:36;63334:178;63165:355;-1:-1:-1;;63165:355:0:o;82888:92::-;11373:13;:11;:13::i;:::-;82955:7:::1;:17;82965:7:::0;82955;:17:::1;:::i;:::-;;82888:92:::0;:::o;64731:100::-;64785:13;64818:5;64811:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64731:100;:::o;66284:311::-;66405:7;66452:16;66460:7;66452;:16::i;:::-;66430:113;;;;-1:-1:-1;;;66430:113:0;;12977:2:1;66430:113:0;;;12959:21:1;13016:2;12996:18;;;12989:30;13055:34;13035:18;;;13028:62;-1:-1:-1;;;13106:18:1;;;13099:45;13161:19;;66430:113:0;;;;;;;;;-1:-1:-1;66563:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;66563:24:0;;66284:311::o;65808:410::-;65889:13;65905:16;65913:7;65905;:16::i;:::-;65889:32;;65946:5;-1:-1:-1;;;;;65940:11:0;:2;-1:-1:-1;;;;;65940:11:0;;65932:60;;;;-1:-1:-1;;;65932:60:0;;13393:2:1;65932:60:0;;;13375:21:1;13432:2;13412:18;;;13405:30;13471:34;13451:18;;;13444:62;-1:-1:-1;;;13522:18:1;;;13515:34;13566:19;;65932:60:0;13191:400:1;65932:60:0;10276:10;-1:-1:-1;;;;;66027:21:0;;;;:62;;-1:-1:-1;66052:37:0;66069:5;10276:10;67068:214;:::i;66052:37::-;66005:171;;;;-1:-1:-1;;;66005:171:0;;13798:2:1;66005:171:0;;;13780:21:1;13837:2;13817:18;;;13810:30;13876:34;13856:18;;;13849:62;13947:29;13927:18;;;13920:57;13994:19;;66005:171:0;13596:423:1;66005:171:0;66189:21;66198:2;66202:7;66189:8;:21::i;:::-;65878:340;65808:410;;:::o;82033:415::-;11373:13;:11;:13::i;:::-;82180:8:::1;:15;82158:11;:18;:37;82150:72;;;::::0;-1:-1:-1;;;82150:72:0;;14226:2:1;82150:72:0::1;::::0;::::1;14208:21:1::0;14265:2;14245:18;;;14238:30;-1:-1:-1;;;14284:18:1;;;14277:52;14346:18;;82150:72:0::1;14024:346:1::0;82150:72:0::1;82279:6;;82257:11;:18;82241:13;:11;:13::i;:::-;:34;;;;:::i;:::-;:44;;82233:86;;;::::0;-1:-1:-1;;;82233:86:0;;14839:2:1;82233:86:0::1;::::0;::::1;14821:21:1::0;14878:2;14858:18;;;14851:30;14917:31;14897:18;;;14890:59;14966:18;;82233:86:0::1;14637:353:1::0;82233:86:0::1;82335:6;82330:111;82351:11;:18;82347:1;:22;82330:111;;;82391:38;82401:11;82413:1;82401:14;;;;;;;;:::i;:::-;;;;;;;82417:8;82426:1;82417:11;;;;;;;;:::i;:::-;;;;;;;82391:9;:38::i;:::-;82371:3:::0;::::1;::::0;::::1;:::i;:::-;;;;82330:111;;80179:208:::0;80246:6;;80229:13;:11;:13::i;:::-;:23;;80221:64;;;;-1:-1:-1;;;80221:64:0;;;;;;;:::i;:::-;80317:5;;80304:9;:18;80296:48;;;;-1:-1:-1;;;80296:48:0;;15826:2:1;80296:48:0;;;15808:21:1;15865:2;15845:18;;;15838:30;-1:-1:-1;;;15884:18:1;;;15877:47;15941:18;;80296:48:0;15624:341:1;80296:48:0;80355:24;80365:10;80377:1;80355:9;:24::i;:::-;80179:208::o;77195:101::-;77247:7;77274:14;:12;:14::i;:::-;77267:21;;77195:101;:::o;67349:379::-;67558:41;10276:10;67591:7;67558:18;:41::i;:::-;67536:143;;;;-1:-1:-1;;;67536:143:0;;;;;;;:::i;:::-;67692:28;67702:4;67708:2;67712:7;67692:9;:28::i;83112:85::-;11373:13;:11;:13::i;:::-;83173:6:::1;:16:::0;;-1:-1:-1;;83173:16:0::1;::::0;::::1;;::::0;;;::::1;::::0;;83112:85::o;82786:94::-;11373:13;:11;:13::i;:::-;82853:6:::1;:19:::0;82786:94::o;81251:193::-;11373:13;:11;:13::i;:::-;81317:21:::1;81299:15;81376:7;11560:6:::0;;-1:-1:-1;;;;;11560:6:0;;11487:87;81376:7:::1;-1:-1:-1::0;;;;;81368:21:0::1;81397:7;81368:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81349:60;;;81428:7;81420:16;;;::::0;::::1;81832:193:::0;11373:13;:11;:13::i;:::-;81943:6:::1;;81926:13;:11;:13::i;:::-;:23;;81918:65;;;::::0;-1:-1:-1;;;81918:65:0;;14839:2:1;81918:65:0::1;::::0;::::1;14821:21:1::0;14878:2;14858:18;;;14851:30;14917:31;14897:18;;;14890:59;14966:18;;81918:65:0::1;14637:353:1::0;81918:65:0::1;81994:23;82004:3;82009:7;81994:9;:23::i;67799:185::-:0;67937:39;67954:4;67960:2;67964:7;67937:39;;;;;;;;;;;;:16;:39::i;80458:292::-;80560:6;;80543:13;:11;:13::i;:::-;:23;;80535:64;;;;-1:-1:-1;;;80535:64:0;;;;;;;:::i;:::-;80610:14;80639:5;;80627:9;:17;;;;:::i;:::-;80610:34;;80677:6;80664:9;:19;80656:49;;;;-1:-1:-1;;;80656:49:0;;15826:2:1;80656:49:0;;;15808:21:1;15865:2;15845:18;;;15838:30;-1:-1:-1;;;15884:18:1;;;15877:47;15941:18;;80656:49:0;15624:341:1;80656:49:0;80717:25;80727:3;80732:9;80717;:25::i;64136:222::-;64253:7;64279:13;64298:29;64319:7;64298:20;:29::i;:::-;-1:-1:-1;64278:49:0;64136:222;-1:-1:-1;;;64136:222:0:o;79590:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;63584:490::-;63706:4;-1:-1:-1;;;;;63737:19:0;;63729:77;;;;-1:-1:-1;;;63729:77:0;;16976:2:1;63729:77:0;;;16958:21:1;17015:2;16995:18;;;16988:30;17054:34;17034:18;;;17027:62;-1:-1:-1;;;17105:18:1;;;17098:43;17158:19;;63729:77:0;16774:409:1;63729:77:0;63819:10;62683:1;63840:204;62853:13;;63871:1;:18;63840:204;;;63914:10;63922:1;63914:7;:10::i;:::-;63911:122;;;63957:10;63965:1;63957:7;:10::i;:::-;-1:-1:-1;;;;;63948:19:0;:5;-1:-1:-1;;;;;63948:19:0;;63944:74;;63991:7;;;:::i;:::-;;;63944:74;63891:3;;;:::i;:::-;;;63840:204;;;-1:-1:-1;64061:5:0;63584:490;-1:-1:-1;;63584:490:0:o;12135:103::-;11373:13;:11;:13::i;:::-;12200:30:::1;12227:1;12200:18;:30::i;79618:27::-:0;;;;;;;:::i;77592:601::-;77661:16;77715:19;77749:22;77774:16;77784:5;77774:9;:16::i;:::-;77749:41;;77805:25;77847:14;77833:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77833:29:0;-1:-1:-1;77805:57:0;-1:-1:-1;62683:1:0;77877:265;77926:14;77911:11;:29;77877:265;;77970:10;77978:1;77970:7;:10::i;:::-;77966:161;;;78023:5;-1:-1:-1;;;;;78009:19:0;:10;78017:1;78009:7;:10::i;:::-;-1:-1:-1;;;;;78009:19:0;;78005:103;;78083:1;78057:8;78066:13;;;;;;78057:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;78005:103;77942:3;;77877:265;;;-1:-1:-1;78163:8:0;77592:601;-1:-1:-1;;;;77592:601:0:o;83205:131::-;11373:13;:11;:13::i;:::-;83294:20:::1;::::0;;;:14:::1;:20;::::0;;;;;:34;83205:131::o;82688:90::-;11373:13;:11;:13::i;:::-;82753:5:::1;:17:::0;82688:90::o;64900:104::-;64956:13;64989:7;64982:14;;;;;:::i;66667:330::-;10276:10;-1:-1:-1;;;;;66802:24:0;;;66794:65;;;;-1:-1:-1;;;66794:65:0;;17390:2:1;66794:65:0;;;17372:21:1;17429:2;17409:18;;;17402:30;17468;17448:18;;;17441:58;17516:18;;66794:65:0;17188:352:1;66794:65:0;10276:10;66872:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;66872:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;66872:53:0;;;;;;;;;;66941:48;;540:41:1;;;66872:42:0;;10276:10;66941:48;;513:18:1;66941:48:0;;;;;;;66667:330;;:::o;68055:368::-;68244:41;10276:10;68277:7;68244:18;:41::i;:::-;68222:143;;;;-1:-1:-1;;;68222:143:0;;;;;;;:::i;:::-;68376:39;68390:4;68396:2;68400:7;68409:5;68376:13;:39::i;:::-;68055:368;;;;:::o;82988:116::-;11373:13;:11;:13::i;:::-;83067::::1;:29;83083:13:::0;83067;:29:::1;:::i;82596:84::-:0;11373:13;:11;:13::i;:::-;82656:6:::1;:16:::0;;;::::1;;;;-1:-1:-1::0;;82656:16:0;;::::1;::::0;;;::::1;::::0;;82596:84::o;83482:473::-;83548:13;83582:17;83590:8;83582:7;:17::i;:::-;83574:77;;;;-1:-1:-1;;;83574:77:0;;17747:2:1;83574:77:0;;;17729:21:1;17786:2;17766:18;;;17759:30;17825:34;17805:18;;;17798:62;-1:-1:-1;;;17876:18:1;;;17869:45;17931:19;;83574:77:0;17545:411:1;83574:77:0;83664:19;83686:10;:8;:10::i;:::-;83711:6;;83664:32;;-1:-1:-1;83711:6:0;;:15;;:6;:15;83707:241;;83774:13;83757:46;;;;;;;;:::i;:::-;;;;;;;;;;;;;83743:61;;;83482:473;;;:::o;83707:241::-;83866:1;83850:5;83844:19;:23;:92;;;;;;;;;;;;;;;;;83894:5;83901:19;:8;:17;:19::i;:::-;83877:53;;;;;;;;;:::i;83844:92::-;83837:99;83482:473;-1:-1:-1;;;83482:473:0:o;83707:241::-;83563:392;83482:473;;;:::o;67068:214::-;-1:-1:-1;;;;;67239:25:0;;;67210:4;67239:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;67068:214::o;80844:332::-;80931:6;;;;;;;;:14;;:6;:14;80923:47;;;;-1:-1:-1;;;80923:47:0;;19823:2:1;80923:47:0;;;19805:21:1;19862:2;19842:18;;;19835:30;-1:-1:-1;;;19881:18:1;;;19874:50;19941:18;;80923:47:0;19621:344:1;80923:47:0;81006:6;;80989:13;:11;:13::i;:::-;:23;;80981:64;;;;-1:-1:-1;;;80981:64:0;;;;;;;:::i;:::-;81064:44;81080:10;81092:1;81095:12;;81064:15;:44::i;:::-;81056:77;;;;-1:-1:-1;;;81056:77:0;;20172:2:1;81056:77:0;;;20154:21:1;20211:2;20191:18;;;20184:30;-1:-1:-1;;;20230:18:1;;;20223:50;20290:18;;81056:77:0;19970:344:1;81056:77:0;81144:24;81154:10;81166:1;81144:9;:24::i;12393:201::-;11373:13;:11;:13::i;:::-;-1:-1:-1;;;;;12482:22:0;::::1;12474:73;;;::::0;-1:-1:-1;;;12474:73:0;;20521:2:1;12474:73:0::1;::::0;::::1;20503:21:1::0;20560:2;20540:18;;;20533:30;20599:34;20579:18;;;20572:62;-1:-1:-1;;;20650:18:1;;;20643:36;20696:19;;12474:73:0::1;20319:402:1::0;12474:73:0::1;12558:28;12577:8;12558:18;:28::i;:::-;12393:201:::0;:::o;83963:250::-;84111:28;;-1:-1:-1;;20903:2:1;20899:15;;;20895:53;84111:28:0;;;20883:66:1;20965:12;;;20958:28;;;84069:4:0;;;;21002:12:1;;84111:28:0;;;;;;;;;;;;84101:39;;;;;;84086:54;;84158:47;84178:14;:20;84193:4;84178:20;;;;;;;;;;;;84200:4;84158:12;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84158:19:0;;:47;;-1:-1:-1;;84158:19:0;:47;-1:-1:-1;84158:47:0:i;:::-;84151:54;83963:250;-1:-1:-1;;;;;;83963:250:0:o;11652:132::-;11560:6;;-1:-1:-1;;;;;11560:6:0;10276:10;11716:23;11708:68;;;;-1:-1:-1;;;11708:68:0;;21227:2:1;11708:68:0;;;21209:21:1;;;21246:18;;;21239:30;21305:34;21285:18;;;21278:62;21357:18;;11708:68:0;21025:356:1;69917:151:0;69982:4;70016:14;62853:13;;;62771:103;70016:14;70006:7;:24;:54;;;;-1:-1:-1;;62683:1:0;70034:26;;;69917:151::o;75160:167::-;75235:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;75235:29:0;-1:-1:-1;;;;;75235:29:0;;;;;;;;:24;;75289:16;75235:24;75289:7;:16::i;:::-;-1:-1:-1;;;;;75280:39:0;;;;;;;;;;;75160:167;;:::o;71046:112::-;71123:27;71133:2;71137:8;71123:27;;;;;;;;;;;;:9;:27::i;62972:121::-;63027:7;62683:1;63054:13;;:31;;;;:::i;70235:448::-;70364:4;70408:16;70416:7;70408;:16::i;:::-;70386:113;;;;-1:-1:-1;;;70386:113:0;;21721:2:1;70386:113:0;;;21703:21:1;21760:2;21740:18;;;21733:30;21799:34;21779:18;;;21772:62;-1:-1:-1;;;21850:18:1;;;21843:45;21905:19;;70386:113:0;21519:411:1;70386:113:0;70510:13;70526:16;70534:7;70526;:16::i;:::-;70510:32;;70572:5;-1:-1:-1;;;;;70561:16:0;:7;-1:-1:-1;;;;;70561:16:0;;:64;;;;70618:7;-1:-1:-1;;;;;70594:31:0;:20;70606:7;70594:11;:20::i;:::-;-1:-1:-1;;;;;70594:31:0;;70561:64;:113;;;;70642:32;70659:5;70666:7;70642:16;:32::i;:::-;70553:122;70235:448;-1:-1:-1;;;;70235:448:0:o;73985:1057::-;74110:13;74125:24;74153:29;74174:7;74153:20;:29::i;:::-;74109:73;;;;74226:4;-1:-1:-1;;;;;74217:13:0;:5;-1:-1:-1;;;;;74217:13:0;;74195:107;;;;-1:-1:-1;;;74195:107:0;;22137:2:1;74195:107:0;;;22119:21:1;22176:2;22156:18;;;22149:30;22215:34;22195:18;;;22188:62;-1:-1:-1;;;22266:18:1;;;22259:42;22318:19;;74195:107:0;21935:408:1;74195:107:0;-1:-1:-1;;;;;74321:16:0;;74313:68;;;;-1:-1:-1;;;74313:68:0;;22550:2:1;74313:68:0;;;22532:21:1;22589:2;22569:18;;;22562:30;22628:34;22608:18;;;22601:62;-1:-1:-1;;;22679:18:1;;;22672:37;22726:19;;74313:68:0;22348:403:1;74313:68:0;74502:29;74519:1;74523:7;74502:8;:29::i;:::-;74547:25;74575:11;:7;74585:1;74575:11;:::i;:::-;54554:1;54545:10;;;74603;54632:20;;;;;;;;;;;54545:10;;-1:-1:-1;;;;54609:4:0;54601:12;;54581:33;54632:27;:32;;;74602:87;;-1:-1:-1;62853:13:0;;74655:17;:34;74602:87;74599:210;;;74716:26;;;;:7;:26;;;;;:33;;-1:-1:-1;;;;;;74716:33:0;-1:-1:-1;;;;;74716:33:0;;;;;74764;;74716:26;74764:14;:33::i;:::-;74821:16;;;;:7;:16;;;;;:21;;-1:-1:-1;;;;;;74821:21:0;-1:-1:-1;;;;;74821:21:0;;;;;74856:27;;;74853:82;;74900:23;:10;74915:7;74900:14;:23::i;:::-;74971:7;74967:2;-1:-1:-1;;;;;74952:27:0;74961:4;-1:-1:-1;;;;;74952:27:0;;;;;;;;;;;74992:42;74098:944;;;73985:1057;;;:::o;64366:298::-;64436:13;64451:24;64495:16;64503:7;64495;:16::i;:::-;64487:73;;;;-1:-1:-1;;;64487:73:0;;22958:2:1;64487:73:0;;;22940:21:1;22997:2;22977:18;;;22970:30;23036:34;23016:18;;;23009:62;-1:-1:-1;;;23087:18:1;;;23080:42;23139:19;;64487:73:0;22756:408:1;64487:73:0;64590:22;64604:7;64590:13;:22::i;:::-;64631:25;;;;:7;:25;;;;;;-1:-1:-1;;;;;64631:25:0;;64571:41;;-1:-1:-1;64366:298:0;-1:-1:-1;;64366:298:0:o;12754:191::-;12847:6;;;-1:-1:-1;;;;;12864:17:0;;;-1:-1:-1;;;;;;12864:17:0;;;;;;;12897:40;;12847:6;;;12864:17;12847:6;;12897:40;;12828:16;;12897:40;12817:128;12754:191;:::o;69305:357::-;69462:28;69472:4;69478:2;69482:7;69462:9;:28::i;:::-;69523:50;69546:4;69552:2;69556:7;69565:1;69567:5;69523:22;:50::i;:::-;69501:153;;;;-1:-1:-1;;;69501:153:0;;;;;;;:::i;81452:100::-;81504:13;81537:7;81530:14;;;;;:::i;26087:716::-;26143:13;26194:14;26211:17;26222:5;26211:10;:17::i;:::-;26231:1;26211:21;26194:38;;26247:20;26281:6;26270:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26270:18:0;-1:-1:-1;26247:41:0;-1:-1:-1;26412:28:0;;;26428:2;26412:28;26469:288;-1:-1:-1;;26501:5:0;-1:-1:-1;;;26638:2:0;26627:14;;26622:30;26501:5;26609:44;26699:2;26690:11;;;-1:-1:-1;26720:21:0;26469:288;26720:21;-1:-1:-1;26778:6:0;26087:716;-1:-1:-1;;;26087:716:0:o;1189:190::-;1314:4;1367;1338:25;1351:5;1358:4;1338:12;:25::i;:::-;:33;;1189:190;-1:-1:-1;;;;1189:190:0:o;71172:387::-;71303:19;71325:14;62853:13;;;62771:103;71325:14;71303:36;;71350:19;71356:2;71360:8;71350:5;:19::i;:::-;71402:68;71433:1;71437:2;71441:11;71454:8;71464:5;71402:22;:68::i;55058:204::-;55155:1;55146:10;;;55129:14;55226:20;;;;;;;;;;;;:28;;-1:-1:-1;;;55210:4:0;55202:12;;;55182:33;;;;55226:28;;;;;55058:204::o;77028:159::-;77091:24;77147:31;77091:24;77170:7;77147:22;:31::i;75981:1039::-;76168:6;-1:-1:-1;;;;;76191:13:0;;38147:19;:23;76187:826;;-1:-1:-1;76227:4:0;76268:12;76246:689;76292:23;76307:8;76292:12;:23;:::i;:::-;76282:7;:33;76246:689;;;76350:72;;-1:-1:-1;;;76350:72:0;;-1:-1:-1;;;;;76350:36:0;;;;;:72;;10276:10;;76401:4;;76407:7;;76416:5;;76350:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76350:72:0;;;;;;;;-1:-1:-1;;76350:72:0;;;;;;;;;;;;:::i;:::-;;;76346:574;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76606:6;:13;76623:1;76606:18;76602:299;;76653:63;;-1:-1:-1;;;76653:63:0;;;;;;;:::i;76602:299::-;76843:6;76837:13;76828:6;76824:2;76820:15;76813:38;76346:574;76474:1;:56;;;;-1:-1:-1;;;;;;;76479:51:0;;-1:-1:-1;;;76479:51:0;76474:56;76470:60;;76423:127;76317:9;;;;:::i;:::-;;;;76246:689;;;;76949:8;;76187:826;-1:-1:-1;76997:4:0;76187:826;75981:1039;;;;;;;:::o;23109:922::-;23162:7;;-1:-1:-1;;;23240:15:0;;23236:102;;-1:-1:-1;;;23276:15:0;;;-1:-1:-1;23320:2:0;23310:12;23236:102;23365:6;23356:5;:15;23352:102;;23401:6;23392:15;;;-1:-1:-1;23436:2:0;23426:12;23352:102;23481:6;23472:5;:15;23468:102;;23517:6;23508:15;;;-1:-1:-1;23552:2:0;23542:12;23468:102;23597:5;23588;:14;23584:99;;23632:5;23623:14;;;-1:-1:-1;23666:1:0;23656:11;23584:99;23710:5;23701;:14;23697:99;;23745:5;23736:14;;;-1:-1:-1;23779:1:0;23769:11;23697:99;23823:5;23814;:14;23810:99;;23858:5;23849:14;;;-1:-1:-1;23892:1:0;23882:11;23810:99;23936:5;23927;:14;23923:66;;23972:1;23962:11;24017:6;23109:922;-1:-1:-1;;23109:922:0:o;2056:296::-;2139:7;2182:4;2139:7;2197:118;2221:5;:12;2217:1;:16;2197:118;;;2270:33;2280:12;2294:5;2300:1;2294:8;;;;;;;;:::i;:::-;;;;;;;2270:9;:33::i;:::-;2255:48;-1:-1:-1;2235:3:0;;;;:::i;:::-;;;;2197:118;;71567:2081;71665:19;71687:14;62853:13;;;62771:103;71687:14;71665:36;;71741:1;71730:8;:12;71722:62;;;;-1:-1:-1;;;71722:62:0;;24673:2:1;71722:62:0;;;24655:21:1;24712:2;24692:18;;;24685:30;24751:34;24731:18;;;24724:62;-1:-1:-1;;;24802:18:1;;;24795:35;24847:19;;71722:62:0;24471:401:1;71722:62:0;-1:-1:-1;;;;;71803:16:0;;71795:64;;;;-1:-1:-1;;;71795:64:0;;25079:2:1;71795:64:0;;;25061:21:1;25118:2;25098:18;;;25091:30;25157:34;25137:18;;;25130:62;-1:-1:-1;;;25208:18:1;;;25201:33;25251:19;;71795:64:0;24877:399:1;71795:64:0;71968:8;71951:13;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;;71987:20:0;;;;:7;:20;;;;;:25;;-1:-1:-1;;;;;;71987:25:0;-1:-1:-1;;;;;71987:25:0;;;;;72023:27;;71987:20;72023:14;:27::i;:::-;72063:16;;72104:22;72118:8;72104:11;:22;:::i;:::-;72090:36;;-1:-1:-1;;;;;72607:2:0;72603:25;72591:37;;72951:11;72915:8;72878:1;72820:25;72765:1;72708;72685:306;73296:1;73283:11;73279:19;73241:317;73333:3;73324:7;73321:16;73241:317;;73535:7;73525:8;73522:1;73495:25;73492:1;73489;73484:59;73382:1;73369:15;73241:317;;59823:1234;59963:1;59954:10;;;59905:19;60120:20;;;;;;;;;;;59905:19;;59954:10;60044:4;60036:12;;;;60225:18;;;60218:26;60297:6;;60294:756;;60395:22;:2;:20;:22::i;:::-;60380:37;;:11;:37;60374:1;60364:6;:11;;60363:55;60349:69;;60294:756;;;60518:1;60509:6;:10;60501:75;;;;-1:-1:-1;;;60501:75:0;;25483:2:1;60501:75:0;;;25465:21:1;25522:2;25502:18;;;25495:30;25561:34;25541:18;;;25534:62;-1:-1:-1;;;25612:18:1;;;25605:50;25672:19;;60501:75:0;25281:416:1;60501:75:0;-1:-1:-1;;;60628:8:0;;;60759:12;:20;;;;;;;;;;;60628:8;;-1:-1:-1;60819:6:0;;60816:207;;60925:22;:2;:20;:22::i;:::-;60918:3;:29;60901:47;;60912:1;60902:6;:11;;60901:47;60887:61;;60975:5;;60816:207;60470:569;;;59926:1131;;;59823:1234;;;;:::o;9096:149::-;9159:7;9190:1;9186;:5;:51;;9321:13;9415:15;;;9451:4;9444:15;;;9498:4;9482:21;;9186:51;;;-1:-1:-1;9321:13:0;9415:15;;;9451:4;9444:15;9498:4;9482:21;;;9096:149::o;51017:201::-;51079:5;51135:16;;;;;;;;;;;;;;;;;51191:3;49533:64;51153:18;51168:2;51153:14;:18::i;:::-;:33;51152:42;;51135:60;;;;;;;;:::i;:::-;;;;;;;;51017:201;-1:-1:-1;;51017:201:0:o;50244:169::-;50303:7;50336:1;50331:2;:6;50323:15;;;;;;-1:-1:-1;50387:1:0;:6;;;50381:13;;50244:169::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:127::-;653:10;648:3;644:20;641:1;634:31;684:4;681:1;674:15;708:4;705:1;698:15;724:275;795:2;789:9;860:2;841:13;;-1:-1:-1;;837:27:1;825:40;;895:18;880:34;;916:22;;;877:62;874:88;;;942:18;;:::i;:::-;978:2;971:22;724:275;;-1:-1:-1;724:275:1:o;1004:407::-;1069:5;1103:18;1095:6;1092:30;1089:56;;;1125:18;;:::i;:::-;1163:57;1208:2;1187:15;;-1:-1:-1;;1183:29:1;1214:4;1179:40;1163:57;:::i;:::-;1154:66;;1243:6;1236:5;1229:21;1283:3;1274:6;1269:3;1265:16;1262:25;1259:45;;;1300:1;1297;1290:12;1259:45;1349:6;1344:3;1337:4;1330:5;1326:16;1313:43;1403:1;1396:4;1387:6;1380:5;1376:18;1372:29;1365:40;1004:407;;;;;:::o;1416:451::-;1485:6;1538:2;1526:9;1517:7;1513:23;1509:32;1506:52;;;1554:1;1551;1544:12;1506:52;1594:9;1581:23;1627:18;1619:6;1616:30;1613:50;;;1659:1;1656;1649:12;1613:50;1682:22;;1735:4;1727:13;;1723:27;-1:-1:-1;1713:55:1;;1764:1;1761;1754:12;1713:55;1787:74;1853:7;1848:2;1835:16;1830:2;1826;1822:11;1787:74;:::i;2054:250::-;2139:1;2149:113;2163:6;2160:1;2157:13;2149:113;;;2239:11;;;2233:18;2220:11;;;2213:39;2185:2;2178:10;2149:113;;;-1:-1:-1;;2296:1:1;2278:16;;2271:27;2054:250::o;2309:271::-;2351:3;2389:5;2383:12;2416:6;2411:3;2404:19;2432:76;2501:6;2494:4;2489:3;2485:14;2478:4;2471:5;2467:16;2432:76;:::i;:::-;2562:2;2541:15;-1:-1:-1;;2537:29:1;2528:39;;;;2569:4;2524:50;;2309:271;-1:-1:-1;;2309:271:1:o;2585:220::-;2734:2;2723:9;2716:21;2697:4;2754:45;2795:2;2784:9;2780:18;2772:6;2754:45;:::i;2810:180::-;2869:6;2922:2;2910:9;2901:7;2897:23;2893:32;2890:52;;;2938:1;2935;2928:12;2890:52;-1:-1:-1;2961:23:1;;2810:180;-1:-1:-1;2810:180:1:o;3203:173::-;3271:20;;-1:-1:-1;;;;;3320:31:1;;3310:42;;3300:70;;3366:1;3363;3356:12;3300:70;3203:173;;;:::o;3381:254::-;3449:6;3457;3510:2;3498:9;3489:7;3485:23;3481:32;3478:52;;;3526:1;3523;3516:12;3478:52;3549:29;3568:9;3549:29;:::i;:::-;3539:39;3625:2;3610:18;;;;3597:32;;-1:-1:-1;;;3381:254:1:o;3640:183::-;3700:4;3733:18;3725:6;3722:30;3719:56;;;3755:18;;:::i;:::-;-1:-1:-1;3800:1:1;3796:14;3812:4;3792:25;;3640:183::o;3828:662::-;3882:5;3935:3;3928:4;3920:6;3916:17;3912:27;3902:55;;3953:1;3950;3943:12;3902:55;3989:6;3976:20;4015:4;4039:60;4055:43;4095:2;4055:43;:::i;:::-;4039:60;:::i;:::-;4133:15;;;4219:1;4215:10;;;;4203:23;;4199:32;;;4164:12;;;;4243:15;;;4240:35;;;4271:1;4268;4261:12;4240:35;4307:2;4299:6;4295:15;4319:142;4335:6;4330:3;4327:15;4319:142;;;4401:17;;4389:30;;4439:12;;;;4352;;4319:142;;;-1:-1:-1;4479:5:1;3828:662;-1:-1:-1;;;;;;3828:662:1:o;4495:1146::-;4613:6;4621;4674:2;4662:9;4653:7;4649:23;4645:32;4642:52;;;4690:1;4687;4680:12;4642:52;4730:9;4717:23;4759:18;4800:2;4792:6;4789:14;4786:34;;;4816:1;4813;4806:12;4786:34;4854:6;4843:9;4839:22;4829:32;;4899:7;4892:4;4888:2;4884:13;4880:27;4870:55;;4921:1;4918;4911:12;4870:55;4957:2;4944:16;4979:4;5003:60;5019:43;5059:2;5019:43;:::i;5003:60::-;5097:15;;;5179:1;5175:10;;;;5167:19;;5163:28;;;5128:12;;;;5203:19;;;5200:39;;;5235:1;5232;5225:12;5200:39;5259:11;;;;5279:148;5295:6;5290:3;5287:15;5279:148;;;5361:23;5380:3;5361:23;:::i;:::-;5349:36;;5312:12;;;;5405;;;;5279:148;;;5446:5;-1:-1:-1;;5489:18:1;;5476:32;;-1:-1:-1;;5520:16:1;;;5517:36;;;5549:1;5546;5539:12;5517:36;;5572:63;5627:7;5616:8;5605:9;5601:24;5572:63;:::i;:::-;5562:73;;;4495:1146;;;;;:::o;5646:328::-;5723:6;5731;5739;5792:2;5780:9;5771:7;5767:23;5763:32;5760:52;;;5808:1;5805;5798:12;5760:52;5831:29;5850:9;5831:29;:::i;:::-;5821:39;;5879:38;5913:2;5902:9;5898:18;5879:38;:::i;:::-;5869:48;;5964:2;5953:9;5949:18;5936:32;5926:42;;5646:328;;;;;:::o;5979:160::-;6044:20;;6100:13;;6093:21;6083:32;;6073:60;;6129:1;6126;6119:12;6144:180;6200:6;6253:2;6241:9;6232:7;6228:23;6224:32;6221:52;;;6269:1;6266;6259:12;6221:52;6292:26;6308:9;6292:26;:::i;6511:186::-;6570:6;6623:2;6611:9;6602:7;6598:23;6594:32;6591:52;;;6639:1;6636;6629:12;6591:52;6662:29;6681:9;6662:29;:::i;6702:632::-;6873:2;6925:21;;;6995:13;;6898:18;;;7017:22;;;6844:4;;6873:2;7096:15;;;;7070:2;7055:18;;;6844:4;7139:169;7153:6;7150:1;7147:13;7139:169;;;7214:13;;7202:26;;7283:15;;;;7248:12;;;;7175:1;7168:9;7139:169;;;-1:-1:-1;7325:3:1;;6702:632;-1:-1:-1;;;;;;6702:632:1:o;7339:248::-;7407:6;7415;7468:2;7456:9;7447:7;7443:23;7439:32;7436:52;;;7484:1;7481;7474:12;7436:52;-1:-1:-1;;7507:23:1;;;7577:2;7562:18;;;7549:32;;-1:-1:-1;7339:248:1:o;7592:254::-;7657:6;7665;7718:2;7706:9;7697:7;7693:23;7689:32;7686:52;;;7734:1;7731;7724:12;7686:52;7757:29;7776:9;7757:29;:::i;:::-;7747:39;;7805:35;7836:2;7825:9;7821:18;7805:35;:::i;:::-;7795:45;;7592:254;;;;;:::o;7851:667::-;7946:6;7954;7962;7970;8023:3;8011:9;8002:7;7998:23;7994:33;7991:53;;;8040:1;8037;8030:12;7991:53;8063:29;8082:9;8063:29;:::i;:::-;8053:39;;8111:38;8145:2;8134:9;8130:18;8111:38;:::i;:::-;8101:48;;8196:2;8185:9;8181:18;8168:32;8158:42;;8251:2;8240:9;8236:18;8223:32;8278:18;8270:6;8267:30;8264:50;;;8310:1;8307;8300:12;8264:50;8333:22;;8386:4;8378:13;;8374:27;-1:-1:-1;8364:55:1;;8415:1;8412;8405:12;8364:55;8438:74;8504:7;8499:2;8486:16;8481:2;8477;8473:11;8438:74;:::i;:::-;8428:84;;;7851:667;;;;;;;:::o;8523:260::-;8591:6;8599;8652:2;8640:9;8631:7;8627:23;8623:32;8620:52;;;8668:1;8665;8658:12;8620:52;8691:29;8710:9;8691:29;:::i;:::-;8681:39;;8739:38;8773:2;8762:9;8758:18;8739:38;:::i;8788:367::-;8851:8;8861:6;8915:3;8908:4;8900:6;8896:17;8892:27;8882:55;;8933:1;8930;8923:12;8882:55;-1:-1:-1;8956:20:1;;8999:18;8988:30;;8985:50;;;9031:1;9028;9021:12;8985:50;9068:4;9060:6;9056:17;9044:29;;9128:3;9121:4;9111:6;9108:1;9104:14;9096:6;9092:27;9088:38;9085:47;9082:67;;;9145:1;9142;9135:12;9082:67;8788:367;;;;;:::o;9160:437::-;9246:6;9254;9307:2;9295:9;9286:7;9282:23;9278:32;9275:52;;;9323:1;9320;9313:12;9275:52;9363:9;9350:23;9396:18;9388:6;9385:30;9382:50;;;9428:1;9425;9418:12;9382:50;9467:70;9529:7;9520:6;9509:9;9505:22;9467:70;:::i;:::-;9556:8;;9441:96;;-1:-1:-1;9160:437:1;-1:-1:-1;;;;9160:437:1:o;9602:579::-;9706:6;9714;9722;9730;9783:2;9771:9;9762:7;9758:23;9754:32;9751:52;;;9799:1;9796;9789:12;9751:52;9822:29;9841:9;9822:29;:::i;:::-;9812:39;;9898:2;9887:9;9883:18;9870:32;9860:42;;9953:2;9942:9;9938:18;9925:32;9980:18;9972:6;9969:30;9966:50;;;10012:1;10009;10002:12;9966:50;10051:70;10113:7;10104:6;10093:9;10089:22;10051:70;:::i;:::-;9602:579;;;;-1:-1:-1;10140:8:1;-1:-1:-1;;;;9602:579:1:o;10186:380::-;10265:1;10261:12;;;;10308;;;10329:61;;10383:4;10375:6;10371:17;10361:27;;10329:61;10436:2;10428:6;10425:14;10405:18;10402:38;10399:161;;10482:10;10477:3;10473:20;10470:1;10463:31;10517:4;10514:1;10507:15;10545:4;10542:1;10535:15;10697:545;10799:2;10794:3;10791:11;10788:448;;;10835:1;10860:5;10856:2;10849:17;10905:4;10901:2;10891:19;10975:2;10963:10;10959:19;10956:1;10952:27;10946:4;10942:38;11011:4;10999:10;10996:20;10993:47;;;-1:-1:-1;11034:4:1;10993:47;11089:2;11084:3;11080:12;11077:1;11073:20;11067:4;11063:31;11053:41;;11144:82;11162:2;11155:5;11152:13;11144:82;;;11207:17;;;11188:1;11177:13;11144:82;;11418:1352;11544:3;11538:10;11571:18;11563:6;11560:30;11557:56;;;11593:18;;:::i;:::-;11622:97;11712:6;11672:38;11704:4;11698:11;11672:38;:::i;:::-;11666:4;11622:97;:::i;:::-;11774:4;;11838:2;11827:14;;11855:1;11850:663;;;;12557:1;12574:6;12571:89;;;-1:-1:-1;12626:19:1;;;12620:26;12571:89;-1:-1:-1;;11375:1:1;11371:11;;;11367:24;11363:29;11353:40;11399:1;11395:11;;;11350:57;12673:81;;11820:944;;11850:663;10644:1;10637:14;;;10681:4;10668:18;;-1:-1:-1;;11886:20:1;;;12004:236;12018:7;12015:1;12012:14;12004:236;;;12107:19;;;12101:26;12086:42;;12199:27;;;;12167:1;12155:14;;;;12034:19;;12004:236;;;12008:3;12268:6;12259:7;12256:19;12253:201;;;12329:19;;;12323:26;-1:-1:-1;;12412:1:1;12408:14;;;12424:3;12404:24;12400:37;12396:42;12381:58;12366:74;;12253:201;-1:-1:-1;;;;;12500:1:1;12484:14;;;12480:22;12467:36;;-1:-1:-1;11418:1352:1:o;14375:127::-;14436:10;14431:3;14427:20;14424:1;14417:31;14467:4;14464:1;14457:15;14491:4;14488:1;14481:15;14507:125;14572:9;;;14593:10;;;14590:36;;;14606:18;;:::i;14995:127::-;15056:10;15051:3;15047:20;15044:1;15037:31;15087:4;15084:1;15077:15;15111:4;15108:1;15101:15;15127:135;15166:3;15187:17;;;15184:43;;15207:18;;:::i;:::-;-1:-1:-1;15254:1:1;15243:13;;15127:135::o;15267:352::-;15469:2;15451:21;;;15508:2;15488:18;;;15481:30;15547;15542:2;15527:18;;15520:58;15610:2;15595:18;;15267:352::o;15970:416::-;16172:2;16154:21;;;16211:2;16191:18;;;16184:30;16250:34;16245:2;16230:18;;16223:62;-1:-1:-1;;;16316:2:1;16301:18;;16294:50;16376:3;16361:19;;15970:416::o;16601:168::-;16674:9;;;16705;;16722:15;;;16716:22;;16702:37;16692:71;;16743:18;;:::i;17961:987::-;18190:3;18219:1;18252:6;18246:13;18282:36;18308:9;18282:36;:::i;:::-;18337:1;18354:18;;;18381:133;;;;18528:1;18523:356;;;;18347:532;;18381:133;-1:-1:-1;;18414:24:1;;18402:37;;18487:14;;18480:22;18468:35;;18459:45;;;-1:-1:-1;18381:133:1;;18523:356;18554:6;18551:1;18544:17;18584:4;18629:2;18626:1;18616:16;18654:1;18668:165;18682:6;18679:1;18676:13;18668:165;;;18760:14;;18747:11;;;18740:35;18803:16;;;;18697:10;;18668:165;;;18672:3;;;18862:6;18857:3;18853:16;18846:23;;18347:532;-1:-1:-1;;;;;18888:26:1;;-1:-1:-1;;18939:2:1;18930:12;;17961:987;-1:-1:-1;;;17961:987:1:o;18953:663::-;19233:3;19271:6;19265:13;19287:66;19346:6;19341:3;19334:4;19326:6;19322:17;19287:66;:::i;:::-;19416:13;;19375:16;;;;19438:70;19416:13;19375:16;19485:4;19473:17;;19438:70;:::i;:::-;-1:-1:-1;;;19530:20:1;;19559:22;;;19608:1;19597:13;;18953:663;-1:-1:-1;;;;18953:663:1:o;21386:128::-;21453:9;;;21474:11;;;21471:37;;;21488:18;;:::i;23169:417::-;23371:2;23353:21;;;23410:2;23390:18;;;23383:30;23449:34;23444:2;23429:18;;23422:62;-1:-1:-1;;;23515:2:1;23500:18;;23493:51;23576:3;23561:19;;23169:417::o;23723:489::-;-1:-1:-1;;;;;23992:15:1;;;23974:34;;24044:15;;24039:2;24024:18;;24017:43;24091:2;24076:18;;24069:34;;;24139:3;24134:2;24119:18;;24112:31;;;23917:4;;24160:46;;24186:19;;24178:6;24160:46;:::i;24217:249::-;24286:6;24339:2;24327:9;24318:7;24314:23;24310:32;24307:52;;;24355:1;24352;24345:12;24307:52;24387:9;24381:16;24406:30;24430:5;24406:30;:::i

Swarm Source

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