ETH Price: $3,208.14 (+0.79%)
Gas: 2 Gwei

Token

DemonicSamurai (DESAMU)
 

Overview

Max Total Supply

982 DESAMU

Holders

73

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
rekokudos.eth
Balance
5 DESAMU
0x8C80142523A9d3F9C4C6C0463fE8096f1F54b15c
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:
DemonicSamurai

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

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


// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

// File: @openzeppelin/contracts/utils/math/Math.sol


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.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);
    }
}

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


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: 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);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


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

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

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

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

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

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

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

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

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

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

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

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

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

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

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

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

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

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256, /* firstTokenId */
        uint256 batchSize
    ) internal virtual {
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}
}

// File: erc721a/contracts/IERC721A.sol


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/ERC721A.sol


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

pragma solidity ^0.8.4;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId].value;
    }

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: Demonic Samurai.sol

//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)

pragma solidity ^0.8.16;








contract DemonicSamurai is ERC721A, Ownable, ReentrancyGuard {
  using Address for address;
  using Strings for uint;
  string  public  baseTokenURI = "ipfs://bafybeiei35ntnylkg3u3jgjv4uqbc37idlcuiqiuvuyyqjtw5ov2zw37gq";

  uint256 public  maxSupply = 999;
  uint256 public  MAX_MINTS_PER_TX = 5;
  uint256 public  PUBLIC_SALE_PRICE = 0.005 ether;
  
  bool public isPublicSaleActive = false;
  
  constructor() ERC721A("DemonicSamurai", "DESAMU") {

  }
  
  function mint(uint256 numberOfTokens)
      external
      payable
  {
    require(isPublicSaleActive, "Public sale is not open");
    require(
      totalSupply() + numberOfTokens <= maxSupply,
      "Maximum supply exceeded"
    );
    require(
            (PUBLIC_SALE_PRICE * numberOfTokens) <= msg.value,
            "Incorrect ETH value sent"
    );
    _safeMint(msg.sender, numberOfTokens);
  }
  
  function setBaseURI(string memory baseURI)
    public
    onlyOwner
  {
    baseTokenURI = baseURI;
  }
  
  function _startTokenId() internal view virtual override returns (uint256) {
        return 1;
    }

  function treasuryMint(uint numberOfTokens, address user)
    public
    onlyOwner
  {
    require(
      numberOfTokens > 0,
      "Invalid mint amount"
    );
    require(
      totalSupply() + numberOfTokens <= maxSupply,
      "Maximum supply exceeded"
    );
    _safeMint(user, numberOfTokens);
  }


  function tokenURI(uint _tokenId)
    public
    view
    virtual
    override
    returns (string memory)
  {
    require(
      _exists(_tokenId),
      "ERC721Metadata: URI query for nonexistent token"
    );
    return string(abi.encodePacked(baseTokenURI, "/", _tokenId.toString(), ".json"));
  }

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

  function setIsPublicSaleActive(bool _isPublicSaleActive)
      external
      onlyOwner
  {
      isPublicSaleActive = _isPublicSaleActive;
  }
  
  function setSalePrice(uint256 _price)
      external
      onlyOwner
  {
      PUBLIC_SALE_PRICE = _price;
  }

  function setMaxLimitPerTransaction(uint256 _limit)
      external
      onlyOwner
  {
      MAX_MINTS_PER_TX = _limit;
  }
  

  function withdraw()
    public
    onlyOwner
    nonReentrant
  {
    Address.sendValue(payable(msg.sender), address(this).balance);
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_MINTS_PER_TX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_SALE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"isPublicSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isPublicSaleActive","type":"bool"}],"name":"setIsPublicSaleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setMaxLimitPerTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"treasuryMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060800160405280604281526020016200370a60429139600a90816200002e919062000495565b506103e7600b556005600c556611c37937e08000600d556000600e60006101000a81548160ff0219169083151502179055503480156200006d57600080fd5b506040518060400160405280600e81526020017f44656d6f6e696353616d757261690000000000000000000000000000000000008152506040518060400160405280600681526020017f444553414d5500000000000000000000000000000000000000000000000000008152508160029081620000eb919062000495565b508060039081620000fd919062000495565b506200010e6200014460201b60201c565b6000819055505050620001366200012a6200014d60201b60201c565b6200015560201b60201c565b60016009819055506200057c565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200029d57607f821691505b602082108103620002b357620002b262000255565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200031d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002de565b620003298683620002de565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000376620003706200036a8462000341565b6200034b565b62000341565b9050919050565b6000819050919050565b620003928362000355565b620003aa620003a1826200037d565b848454620002eb565b825550505050565b600090565b620003c1620003b2565b620003ce81848462000387565b505050565b5b81811015620003f657620003ea600082620003b7565b600181019050620003d4565b5050565b601f82111562000445576200040f81620002b9565b6200041a84620002ce565b810160208510156200042a578190505b620004426200043985620002ce565b830182620003d3565b50505b505050565b600082821c905092915050565b60006200046a600019846008026200044a565b1980831691505092915050565b600062000485838362000457565b9150826002028217905092915050565b620004a0826200021b565b67ffffffffffffffff811115620004bc57620004bb62000226565b5b620004c8825462000284565b620004d5828285620003fa565b600060209050601f8311600181146200050d5760008415620004f8578287015190505b62000504858262000477565b86555062000574565b601f1984166200051d86620002b9565b60005b82811015620005475784890151825560018201915060208501945060208101905062000520565b8683101562000567578489015162000563601f89168262000457565b8355505b6001600288020188555050505b505050505050565b61317e806200058c6000396000f3fe6080604052600436106101c25760003560e01c806370a08231116100f7578063b88d4fde11610095578063d5abeb0111610064578063d5abeb01146105d7578063e985e9c514610602578063f2a3013e1461063f578063f2fde38b14610668576101c2565b8063b88d4fde14610528578063c6a91b4214610544578063c87b56dd1461056f578063d547cfb7146105ac576101c2565b806395d89b41116100d157806395d89b411461048f5780639e9fcffc146104ba578063a0712d68146104e3578063a22cb465146104ff576101c2565b806370a0823114610410578063715018a61461044d5780638da5cb5b14610464576101c2565b80631e84c413116101645780633ccfd60b1161013e5780633ccfd60b1461037757806342842e0e1461038e57806355f804b3146103aa5780636352211e146103d3576101c2565b80631e84c4131461030757806323b872dd1461033257806328cad13d1461034e576101c2565b8063081812fc116101a0578063081812fc1461025a578063095ea7b31461029757806318160ddd146102b35780631919fed7146102de576101c2565b806301ffc9a7146101c757806306fdde031461020457806307e89ec01461022f575b600080fd5b3480156101d357600080fd5b506101ee60048036038101906101e99190611f75565b610691565b6040516101fb9190611fbd565b60405180910390f35b34801561021057600080fd5b50610219610723565b6040516102269190612068565b60405180910390f35b34801561023b57600080fd5b506102446107b5565b60405161025191906120a3565b60405180910390f35b34801561026657600080fd5b50610281600480360381019061027c91906120ea565b6107bb565b60405161028e9190612158565b60405180910390f35b6102b160048036038101906102ac919061219f565b61083a565b005b3480156102bf57600080fd5b506102c861097e565b6040516102d591906120a3565b60405180910390f35b3480156102ea57600080fd5b50610305600480360381019061030091906120ea565b610995565b005b34801561031357600080fd5b5061031c6109a7565b6040516103299190611fbd565b60405180910390f35b61034c600480360381019061034791906121df565b6109ba565b005b34801561035a57600080fd5b506103756004803603810190610370919061225e565b610cdc565b005b34801561038357600080fd5b5061038c610d01565b005b6103a860048036038101906103a391906121df565b610d25565b005b3480156103b657600080fd5b506103d160048036038101906103cc91906123c0565b610d45565b005b3480156103df57600080fd5b506103fa60048036038101906103f591906120ea565b610d60565b6040516104079190612158565b60405180910390f35b34801561041c57600080fd5b5061043760048036038101906104329190612409565b610d72565b60405161044491906120a3565b60405180910390f35b34801561045957600080fd5b50610462610e2a565b005b34801561047057600080fd5b50610479610e3e565b6040516104869190612158565b60405180910390f35b34801561049b57600080fd5b506104a4610e68565b6040516104b19190612068565b60405180910390f35b3480156104c657600080fd5b506104e160048036038101906104dc91906120ea565b610efa565b005b6104fd60048036038101906104f891906120ea565b610f0c565b005b34801561050b57600080fd5b5061052660048036038101906105219190612436565b61100f565b005b610542600480360381019061053d9190612517565b61111a565b005b34801561055057600080fd5b5061055961118d565b60405161056691906120a3565b60405180910390f35b34801561057b57600080fd5b50610596600480360381019061059191906120ea565b611193565b6040516105a39190612068565b60405180910390f35b3480156105b857600080fd5b506105c161120f565b6040516105ce9190612068565b60405180910390f35b3480156105e357600080fd5b506105ec61129d565b6040516105f991906120a3565b60405180910390f35b34801561060e57600080fd5b506106296004803603810190610624919061259a565b6112a3565b6040516106369190611fbd565b60405180910390f35b34801561064b57600080fd5b50610666600480360381019061066191906125da565b611337565b005b34801561067457600080fd5b5061068f600480360381019061068a9190612409565b6113e7565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106ec57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061071c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461073290612649565b80601f016020809104026020016040519081016040528092919081815260200182805461075e90612649565b80156107ab5780601f10610780576101008083540402835291602001916107ab565b820191906000526020600020905b81548152906001019060200180831161078e57829003601f168201915b5050505050905090565b600d5481565b60006107c68261146a565b6107fc576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061084582610d60565b90508073ffffffffffffffffffffffffffffffffffffffff166108666114c9565b73ffffffffffffffffffffffffffffffffffffffff16146108c9576108928161088d6114c9565b6112a3565b6108c8576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006109886114d1565b6001546000540303905090565b61099d6114da565b80600d8190555050565b600e60009054906101000a900460ff1681565b60006109c582611558565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a2c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610a3884611624565b91509150610a4e8187610a496114c9565b61164b565b610a9a57610a6386610a5e6114c9565b6112a3565b610a99576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b00576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d868686600161168f565b8015610b1857600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610be685610bc2888887611695565b7c0200000000000000000000000000000000000000000000000000000000176116bd565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610c6c5760006001850190506000600460008381526020019081526020016000205403610c6a576000548114610c69578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610cd486868660016116e8565b505050505050565b610ce46114da565b80600e60006101000a81548160ff02191690831515021790555050565b610d096114da565b610d116116ee565b610d1b334761173d565b610d23611831565b565b610d408383836040518060200160405280600081525061111a565b505050565b610d4d6114da565b80600a9081610d5c9190612826565b5050565b6000610d6b82611558565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610dd9576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610e326114da565b610e3c600061183b565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610e7790612649565b80601f0160208091040260200160405190810160405280929190818152602001828054610ea390612649565b8015610ef05780601f10610ec557610100808354040283529160200191610ef0565b820191906000526020600020905b815481529060010190602001808311610ed357829003601f168201915b5050505050905090565b610f026114da565b80600c8190555050565b600e60009054906101000a900460ff16610f5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5290612944565b60405180910390fd5b600b5481610f6761097e565b610f719190612993565b1115610fb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa990612a13565b60405180910390fd5b3481600d54610fc19190612a33565b1115611002576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff990612ad9565b60405180910390fd5b61100c3382611901565b50565b806007600061101c6114c9565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166110c96114c9565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161110e9190611fbd565b60405180910390a35050565b6111258484846109ba565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611187576111508484848461191f565b611186576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600c5481565b606061119e8261146a565b6111dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d490612b6b565b60405180910390fd5b600a6111e883611a6f565b6040516020016111f9929190612ce2565b6040516020818303038152906040529050919050565b600a805461121c90612649565b80601f016020809104026020016040519081016040528092919081815260200182805461124890612649565b80156112955780601f1061126a57610100808354040283529160200191611295565b820191906000526020600020905b81548152906001019060200180831161127857829003601f168201915b505050505081565b600b5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61133f6114da565b60008211611382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137990612d68565b60405180910390fd5b600b548261138e61097e565b6113989190612993565b11156113d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d090612a13565b60405180910390fd5b6113e38183611901565b5050565b6113ef6114da565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361145e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145590612dfa565b60405180910390fd5b6114678161183b565b50565b6000816114756114d1565b11158015611484575060005482105b80156114c2575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b6114e2611b3d565b73ffffffffffffffffffffffffffffffffffffffff16611500610e3e565b73ffffffffffffffffffffffffffffffffffffffff1614611556576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154d90612e66565b60405180910390fd5b565b600080829050806115676114d1565b116115ed576000548110156115ec5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036115ea575b600081036115e05760046000836001900393508381526020019081526020016000205490506115b6565b809250505061161f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86116ac868684611b45565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600260095403611733576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172a90612ed2565b60405180910390fd5b6002600981905550565b80471015611780576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177790612f3e565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516117a690612f8f565b60006040518083038185875af1925050503d80600081146117e3576040519150601f19603f3d011682016040523d82523d6000602084013e6117e8565b606091505b505090508061182c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182390613016565b60405180910390fd5b505050565b6001600981905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61191b828260405180602001604052806000815250611b4e565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026119456114c9565b8786866040518563ffffffff1660e01b8152600401611967949392919061308b565b6020604051808303816000875af19250505080156119a357506040513d601f19601f820116820180604052508101906119a091906130ec565b60015b611a1c573d80600081146119d3576040519150601f19603f3d011682016040523d82523d6000602084013e6119d8565b606091505b506000815103611a14576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606060006001611a7e84611beb565b01905060008167ffffffffffffffff811115611a9d57611a9c612295565b5b6040519080825280601f01601f191660200182016040528015611acf5781602001600182028036833780820191505090505b509050600082602001820190505b600115611b32578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611b2657611b25613119565b5b04945060008503611add575b819350505050919050565b600033905090565b60009392505050565b611b588383611d3e565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611be657600080549050600083820390505b611b98600086838060010194508661191f565b611bce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611b85578160005414611be357600080fd5b50505b505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611c49577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611c3f57611c3e613119565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611c86576d04ee2d6d415b85acef81000000008381611c7c57611c7b613119565b5b0492506020810190505b662386f26fc100008310611cb557662386f26fc100008381611cab57611caa613119565b5b0492506010810190505b6305f5e1008310611cde576305f5e1008381611cd457611cd3613119565b5b0492506008810190505b6127108310611d03576127108381611cf957611cf8613119565b5b0492506004810190505b60648310611d265760648381611d1c57611d1b613119565b5b0492506002810190505b600a8310611d35576001810190505b80915050919050565b60008054905060008203611d7e576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d8b600084838561168f565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611e0283611df36000866000611695565b611dfc85611ef9565b176116bd565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114611ea357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050611e68565b5060008203611ede576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050611ef460008483856116e8565b505050565b60006001821460e11b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611f5281611f1d565b8114611f5d57600080fd5b50565b600081359050611f6f81611f49565b92915050565b600060208284031215611f8b57611f8a611f13565b5b6000611f9984828501611f60565b91505092915050565b60008115159050919050565b611fb781611fa2565b82525050565b6000602082019050611fd26000830184611fae565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612012578082015181840152602081019050611ff7565b60008484015250505050565b6000601f19601f8301169050919050565b600061203a82611fd8565b6120448185611fe3565b9350612054818560208601611ff4565b61205d8161201e565b840191505092915050565b60006020820190508181036000830152612082818461202f565b905092915050565b6000819050919050565b61209d8161208a565b82525050565b60006020820190506120b86000830184612094565b92915050565b6120c78161208a565b81146120d257600080fd5b50565b6000813590506120e4816120be565b92915050565b600060208284031215612100576120ff611f13565b5b600061210e848285016120d5565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061214282612117565b9050919050565b61215281612137565b82525050565b600060208201905061216d6000830184612149565b92915050565b61217c81612137565b811461218757600080fd5b50565b60008135905061219981612173565b92915050565b600080604083850312156121b6576121b5611f13565b5b60006121c48582860161218a565b92505060206121d5858286016120d5565b9150509250929050565b6000806000606084860312156121f8576121f7611f13565b5b60006122068682870161218a565b93505060206122178682870161218a565b9250506040612228868287016120d5565b9150509250925092565b61223b81611fa2565b811461224657600080fd5b50565b60008135905061225881612232565b92915050565b60006020828403121561227457612273611f13565b5b600061228284828501612249565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122cd8261201e565b810181811067ffffffffffffffff821117156122ec576122eb612295565b5b80604052505050565b60006122ff611f09565b905061230b82826122c4565b919050565b600067ffffffffffffffff82111561232b5761232a612295565b5b6123348261201e565b9050602081019050919050565b82818337600083830152505050565b600061236361235e84612310565b6122f5565b90508281526020810184848401111561237f5761237e612290565b5b61238a848285612341565b509392505050565b600082601f8301126123a7576123a661228b565b5b81356123b7848260208601612350565b91505092915050565b6000602082840312156123d6576123d5611f13565b5b600082013567ffffffffffffffff8111156123f4576123f3611f18565b5b61240084828501612392565b91505092915050565b60006020828403121561241f5761241e611f13565b5b600061242d8482850161218a565b91505092915050565b6000806040838503121561244d5761244c611f13565b5b600061245b8582860161218a565b925050602061246c85828601612249565b9150509250929050565b600067ffffffffffffffff82111561249157612490612295565b5b61249a8261201e565b9050602081019050919050565b60006124ba6124b584612476565b6122f5565b9050828152602081018484840111156124d6576124d5612290565b5b6124e1848285612341565b509392505050565b600082601f8301126124fe576124fd61228b565b5b813561250e8482602086016124a7565b91505092915050565b6000806000806080858703121561253157612530611f13565b5b600061253f8782880161218a565b94505060206125508782880161218a565b9350506040612561878288016120d5565b925050606085013567ffffffffffffffff81111561258257612581611f18565b5b61258e878288016124e9565b91505092959194509250565b600080604083850312156125b1576125b0611f13565b5b60006125bf8582860161218a565b92505060206125d08582860161218a565b9150509250929050565b600080604083850312156125f1576125f0611f13565b5b60006125ff858286016120d5565b92505060206126108582860161218a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061266157607f821691505b6020821081036126745761267361261a565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026126dc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261269f565b6126e6868361269f565b95508019841693508086168417925050509392505050565b6000819050919050565b600061272361271e6127198461208a565b6126fe565b61208a565b9050919050565b6000819050919050565b61273d83612708565b6127516127498261272a565b8484546126ac565b825550505050565b600090565b612766612759565b612771818484612734565b505050565b5b818110156127955761278a60008261275e565b600181019050612777565b5050565b601f8211156127da576127ab8161267a565b6127b48461268f565b810160208510156127c3578190505b6127d76127cf8561268f565b830182612776565b50505b505050565b600082821c905092915050565b60006127fd600019846008026127df565b1980831691505092915050565b600061281683836127ec565b9150826002028217905092915050565b61282f82611fd8565b67ffffffffffffffff81111561284857612847612295565b5b6128528254612649565b61285d828285612799565b600060209050601f831160018114612890576000841561287e578287015190505b612888858261280a565b8655506128f0565b601f19841661289e8661267a565b60005b828110156128c6578489015182556001820191506020850194506020810190506128a1565b868310156128e357848901516128df601f8916826127ec565b8355505b6001600288020188555050505b505050505050565b7f5075626c69632073616c65206973206e6f74206f70656e000000000000000000600082015250565b600061292e601783611fe3565b9150612939826128f8565b602082019050919050565b6000602082019050818103600083015261295d81612921565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061299e8261208a565b91506129a98361208a565b92508282019050808211156129c1576129c0612964565b5b92915050565b7f4d6178696d756d20737570706c79206578636565646564000000000000000000600082015250565b60006129fd601783611fe3565b9150612a08826129c7565b602082019050919050565b60006020820190508181036000830152612a2c816129f0565b9050919050565b6000612a3e8261208a565b9150612a498361208a565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612a8257612a81612964565b5b828202905092915050565b7f496e636f7272656374204554482076616c75652073656e740000000000000000600082015250565b6000612ac3601883611fe3565b9150612ace82612a8d565b602082019050919050565b60006020820190508181036000830152612af281612ab6565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000612b55602f83611fe3565b9150612b6082612af9565b604082019050919050565b60006020820190508181036000830152612b8481612b48565b9050919050565b600081905092915050565b60008154612ba381612649565b612bad8186612b8b565b94506001821660008114612bc85760018114612bdd57612c10565b60ff1983168652811515820286019350612c10565b612be68561267a565b60005b83811015612c0857815481890152600182019150602081019050612be9565b838801955050505b50505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b6000612c4f600183612b8b565b9150612c5a82612c19565b600182019050919050565b6000612c7082611fd8565b612c7a8185612b8b565b9350612c8a818560208601611ff4565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000612ccc600583612b8b565b9150612cd782612c96565b600582019050919050565b6000612cee8285612b96565b9150612cf982612c42565b9150612d058284612c65565b9150612d1082612cbf565b91508190509392505050565b7f496e76616c6964206d696e7420616d6f756e7400000000000000000000000000600082015250565b6000612d52601383611fe3565b9150612d5d82612d1c565b602082019050919050565b60006020820190508181036000830152612d8181612d45565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612de4602683611fe3565b9150612def82612d88565b604082019050919050565b60006020820190508181036000830152612e1381612dd7565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e50602083611fe3565b9150612e5b82612e1a565b602082019050919050565b60006020820190508181036000830152612e7f81612e43565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612ebc601f83611fe3565b9150612ec782612e86565b602082019050919050565b60006020820190508181036000830152612eeb81612eaf565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000612f28601d83611fe3565b9150612f3382612ef2565b602082019050919050565b60006020820190508181036000830152612f5781612f1b565b9050919050565b600081905092915050565b50565b6000612f79600083612f5e565b9150612f8482612f69565b600082019050919050565b6000612f9a82612f6c565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b6000613000603a83611fe3565b915061300b82612fa4565b604082019050919050565b6000602082019050818103600083015261302f81612ff3565b9050919050565b600081519050919050565b600082825260208201905092915050565b600061305d82613036565b6130678185613041565b9350613077818560208601611ff4565b6130808161201e565b840191505092915050565b60006080820190506130a06000830187612149565b6130ad6020830186612149565b6130ba6040830185612094565b81810360608301526130cc8184613052565b905095945050505050565b6000815190506130e681611f49565b92915050565b60006020828403121561310257613101611f13565b5b6000613110848285016130d7565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212204ae6b9c96235598d2bbe2c64d6268f193daad17611b1aa9a138fdeda62fbcbff64736f6c63430008100033697066733a2f2f62616679626569656933356e746e796c6b673375336a676a763475716263333769646c63756971697576757979716a7477356f76327a7733376771

Deployed Bytecode

0x6080604052600436106101c25760003560e01c806370a08231116100f7578063b88d4fde11610095578063d5abeb0111610064578063d5abeb01146105d7578063e985e9c514610602578063f2a3013e1461063f578063f2fde38b14610668576101c2565b8063b88d4fde14610528578063c6a91b4214610544578063c87b56dd1461056f578063d547cfb7146105ac576101c2565b806395d89b41116100d157806395d89b411461048f5780639e9fcffc146104ba578063a0712d68146104e3578063a22cb465146104ff576101c2565b806370a0823114610410578063715018a61461044d5780638da5cb5b14610464576101c2565b80631e84c413116101645780633ccfd60b1161013e5780633ccfd60b1461037757806342842e0e1461038e57806355f804b3146103aa5780636352211e146103d3576101c2565b80631e84c4131461030757806323b872dd1461033257806328cad13d1461034e576101c2565b8063081812fc116101a0578063081812fc1461025a578063095ea7b31461029757806318160ddd146102b35780631919fed7146102de576101c2565b806301ffc9a7146101c757806306fdde031461020457806307e89ec01461022f575b600080fd5b3480156101d357600080fd5b506101ee60048036038101906101e99190611f75565b610691565b6040516101fb9190611fbd565b60405180910390f35b34801561021057600080fd5b50610219610723565b6040516102269190612068565b60405180910390f35b34801561023b57600080fd5b506102446107b5565b60405161025191906120a3565b60405180910390f35b34801561026657600080fd5b50610281600480360381019061027c91906120ea565b6107bb565b60405161028e9190612158565b60405180910390f35b6102b160048036038101906102ac919061219f565b61083a565b005b3480156102bf57600080fd5b506102c861097e565b6040516102d591906120a3565b60405180910390f35b3480156102ea57600080fd5b50610305600480360381019061030091906120ea565b610995565b005b34801561031357600080fd5b5061031c6109a7565b6040516103299190611fbd565b60405180910390f35b61034c600480360381019061034791906121df565b6109ba565b005b34801561035a57600080fd5b506103756004803603810190610370919061225e565b610cdc565b005b34801561038357600080fd5b5061038c610d01565b005b6103a860048036038101906103a391906121df565b610d25565b005b3480156103b657600080fd5b506103d160048036038101906103cc91906123c0565b610d45565b005b3480156103df57600080fd5b506103fa60048036038101906103f591906120ea565b610d60565b6040516104079190612158565b60405180910390f35b34801561041c57600080fd5b5061043760048036038101906104329190612409565b610d72565b60405161044491906120a3565b60405180910390f35b34801561045957600080fd5b50610462610e2a565b005b34801561047057600080fd5b50610479610e3e565b6040516104869190612158565b60405180910390f35b34801561049b57600080fd5b506104a4610e68565b6040516104b19190612068565b60405180910390f35b3480156104c657600080fd5b506104e160048036038101906104dc91906120ea565b610efa565b005b6104fd60048036038101906104f891906120ea565b610f0c565b005b34801561050b57600080fd5b5061052660048036038101906105219190612436565b61100f565b005b610542600480360381019061053d9190612517565b61111a565b005b34801561055057600080fd5b5061055961118d565b60405161056691906120a3565b60405180910390f35b34801561057b57600080fd5b50610596600480360381019061059191906120ea565b611193565b6040516105a39190612068565b60405180910390f35b3480156105b857600080fd5b506105c161120f565b6040516105ce9190612068565b60405180910390f35b3480156105e357600080fd5b506105ec61129d565b6040516105f991906120a3565b60405180910390f35b34801561060e57600080fd5b506106296004803603810190610624919061259a565b6112a3565b6040516106369190611fbd565b60405180910390f35b34801561064b57600080fd5b50610666600480360381019061066191906125da565b611337565b005b34801561067457600080fd5b5061068f600480360381019061068a9190612409565b6113e7565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106ec57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061071c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461073290612649565b80601f016020809104026020016040519081016040528092919081815260200182805461075e90612649565b80156107ab5780601f10610780576101008083540402835291602001916107ab565b820191906000526020600020905b81548152906001019060200180831161078e57829003601f168201915b5050505050905090565b600d5481565b60006107c68261146a565b6107fc576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061084582610d60565b90508073ffffffffffffffffffffffffffffffffffffffff166108666114c9565b73ffffffffffffffffffffffffffffffffffffffff16146108c9576108928161088d6114c9565b6112a3565b6108c8576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006109886114d1565b6001546000540303905090565b61099d6114da565b80600d8190555050565b600e60009054906101000a900460ff1681565b60006109c582611558565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a2c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610a3884611624565b91509150610a4e8187610a496114c9565b61164b565b610a9a57610a6386610a5e6114c9565b6112a3565b610a99576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610b00576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d868686600161168f565b8015610b1857600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610be685610bc2888887611695565b7c0200000000000000000000000000000000000000000000000000000000176116bd565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610c6c5760006001850190506000600460008381526020019081526020016000205403610c6a576000548114610c69578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610cd486868660016116e8565b505050505050565b610ce46114da565b80600e60006101000a81548160ff02191690831515021790555050565b610d096114da565b610d116116ee565b610d1b334761173d565b610d23611831565b565b610d408383836040518060200160405280600081525061111a565b505050565b610d4d6114da565b80600a9081610d5c9190612826565b5050565b6000610d6b82611558565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610dd9576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610e326114da565b610e3c600061183b565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610e7790612649565b80601f0160208091040260200160405190810160405280929190818152602001828054610ea390612649565b8015610ef05780601f10610ec557610100808354040283529160200191610ef0565b820191906000526020600020905b815481529060010190602001808311610ed357829003601f168201915b5050505050905090565b610f026114da565b80600c8190555050565b600e60009054906101000a900460ff16610f5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5290612944565b60405180910390fd5b600b5481610f6761097e565b610f719190612993565b1115610fb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa990612a13565b60405180910390fd5b3481600d54610fc19190612a33565b1115611002576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff990612ad9565b60405180910390fd5b61100c3382611901565b50565b806007600061101c6114c9565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166110c96114c9565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161110e9190611fbd565b60405180910390a35050565b6111258484846109ba565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611187576111508484848461191f565b611186576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600c5481565b606061119e8261146a565b6111dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d490612b6b565b60405180910390fd5b600a6111e883611a6f565b6040516020016111f9929190612ce2565b6040516020818303038152906040529050919050565b600a805461121c90612649565b80601f016020809104026020016040519081016040528092919081815260200182805461124890612649565b80156112955780601f1061126a57610100808354040283529160200191611295565b820191906000526020600020905b81548152906001019060200180831161127857829003601f168201915b505050505081565b600b5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61133f6114da565b60008211611382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137990612d68565b60405180910390fd5b600b548261138e61097e565b6113989190612993565b11156113d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d090612a13565b60405180910390fd5b6113e38183611901565b5050565b6113ef6114da565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361145e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145590612dfa565b60405180910390fd5b6114678161183b565b50565b6000816114756114d1565b11158015611484575060005482105b80156114c2575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b6114e2611b3d565b73ffffffffffffffffffffffffffffffffffffffff16611500610e3e565b73ffffffffffffffffffffffffffffffffffffffff1614611556576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154d90612e66565b60405180910390fd5b565b600080829050806115676114d1565b116115ed576000548110156115ec5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036115ea575b600081036115e05760046000836001900393508381526020019081526020016000205490506115b6565b809250505061161f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86116ac868684611b45565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600260095403611733576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172a90612ed2565b60405180910390fd5b6002600981905550565b80471015611780576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177790612f3e565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516117a690612f8f565b60006040518083038185875af1925050503d80600081146117e3576040519150601f19603f3d011682016040523d82523d6000602084013e6117e8565b606091505b505090508061182c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182390613016565b60405180910390fd5b505050565b6001600981905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61191b828260405180602001604052806000815250611b4e565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026119456114c9565b8786866040518563ffffffff1660e01b8152600401611967949392919061308b565b6020604051808303816000875af19250505080156119a357506040513d601f19601f820116820180604052508101906119a091906130ec565b60015b611a1c573d80600081146119d3576040519150601f19603f3d011682016040523d82523d6000602084013e6119d8565b606091505b506000815103611a14576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606060006001611a7e84611beb565b01905060008167ffffffffffffffff811115611a9d57611a9c612295565b5b6040519080825280601f01601f191660200182016040528015611acf5781602001600182028036833780820191505090505b509050600082602001820190505b600115611b32578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611b2657611b25613119565b5b04945060008503611add575b819350505050919050565b600033905090565b60009392505050565b611b588383611d3e565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611be657600080549050600083820390505b611b98600086838060010194508661191f565b611bce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611b85578160005414611be357600080fd5b50505b505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611c49577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611c3f57611c3e613119565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611c86576d04ee2d6d415b85acef81000000008381611c7c57611c7b613119565b5b0492506020810190505b662386f26fc100008310611cb557662386f26fc100008381611cab57611caa613119565b5b0492506010810190505b6305f5e1008310611cde576305f5e1008381611cd457611cd3613119565b5b0492506008810190505b6127108310611d03576127108381611cf957611cf8613119565b5b0492506004810190505b60648310611d265760648381611d1c57611d1b613119565b5b0492506002810190505b600a8310611d35576001810190505b80915050919050565b60008054905060008203611d7e576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d8b600084838561168f565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611e0283611df36000866000611695565b611dfc85611ef9565b176116bd565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114611ea357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050611e68565b5060008203611ede576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050611ef460008483856116e8565b505050565b60006001821460e11b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611f5281611f1d565b8114611f5d57600080fd5b50565b600081359050611f6f81611f49565b92915050565b600060208284031215611f8b57611f8a611f13565b5b6000611f9984828501611f60565b91505092915050565b60008115159050919050565b611fb781611fa2565b82525050565b6000602082019050611fd26000830184611fae565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612012578082015181840152602081019050611ff7565b60008484015250505050565b6000601f19601f8301169050919050565b600061203a82611fd8565b6120448185611fe3565b9350612054818560208601611ff4565b61205d8161201e565b840191505092915050565b60006020820190508181036000830152612082818461202f565b905092915050565b6000819050919050565b61209d8161208a565b82525050565b60006020820190506120b86000830184612094565b92915050565b6120c78161208a565b81146120d257600080fd5b50565b6000813590506120e4816120be565b92915050565b600060208284031215612100576120ff611f13565b5b600061210e848285016120d5565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061214282612117565b9050919050565b61215281612137565b82525050565b600060208201905061216d6000830184612149565b92915050565b61217c81612137565b811461218757600080fd5b50565b60008135905061219981612173565b92915050565b600080604083850312156121b6576121b5611f13565b5b60006121c48582860161218a565b92505060206121d5858286016120d5565b9150509250929050565b6000806000606084860312156121f8576121f7611f13565b5b60006122068682870161218a565b93505060206122178682870161218a565b9250506040612228868287016120d5565b9150509250925092565b61223b81611fa2565b811461224657600080fd5b50565b60008135905061225881612232565b92915050565b60006020828403121561227457612273611f13565b5b600061228284828501612249565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122cd8261201e565b810181811067ffffffffffffffff821117156122ec576122eb612295565b5b80604052505050565b60006122ff611f09565b905061230b82826122c4565b919050565b600067ffffffffffffffff82111561232b5761232a612295565b5b6123348261201e565b9050602081019050919050565b82818337600083830152505050565b600061236361235e84612310565b6122f5565b90508281526020810184848401111561237f5761237e612290565b5b61238a848285612341565b509392505050565b600082601f8301126123a7576123a661228b565b5b81356123b7848260208601612350565b91505092915050565b6000602082840312156123d6576123d5611f13565b5b600082013567ffffffffffffffff8111156123f4576123f3611f18565b5b61240084828501612392565b91505092915050565b60006020828403121561241f5761241e611f13565b5b600061242d8482850161218a565b91505092915050565b6000806040838503121561244d5761244c611f13565b5b600061245b8582860161218a565b925050602061246c85828601612249565b9150509250929050565b600067ffffffffffffffff82111561249157612490612295565b5b61249a8261201e565b9050602081019050919050565b60006124ba6124b584612476565b6122f5565b9050828152602081018484840111156124d6576124d5612290565b5b6124e1848285612341565b509392505050565b600082601f8301126124fe576124fd61228b565b5b813561250e8482602086016124a7565b91505092915050565b6000806000806080858703121561253157612530611f13565b5b600061253f8782880161218a565b94505060206125508782880161218a565b9350506040612561878288016120d5565b925050606085013567ffffffffffffffff81111561258257612581611f18565b5b61258e878288016124e9565b91505092959194509250565b600080604083850312156125b1576125b0611f13565b5b60006125bf8582860161218a565b92505060206125d08582860161218a565b9150509250929050565b600080604083850312156125f1576125f0611f13565b5b60006125ff858286016120d5565b92505060206126108582860161218a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061266157607f821691505b6020821081036126745761267361261a565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026126dc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261269f565b6126e6868361269f565b95508019841693508086168417925050509392505050565b6000819050919050565b600061272361271e6127198461208a565b6126fe565b61208a565b9050919050565b6000819050919050565b61273d83612708565b6127516127498261272a565b8484546126ac565b825550505050565b600090565b612766612759565b612771818484612734565b505050565b5b818110156127955761278a60008261275e565b600181019050612777565b5050565b601f8211156127da576127ab8161267a565b6127b48461268f565b810160208510156127c3578190505b6127d76127cf8561268f565b830182612776565b50505b505050565b600082821c905092915050565b60006127fd600019846008026127df565b1980831691505092915050565b600061281683836127ec565b9150826002028217905092915050565b61282f82611fd8565b67ffffffffffffffff81111561284857612847612295565b5b6128528254612649565b61285d828285612799565b600060209050601f831160018114612890576000841561287e578287015190505b612888858261280a565b8655506128f0565b601f19841661289e8661267a565b60005b828110156128c6578489015182556001820191506020850194506020810190506128a1565b868310156128e357848901516128df601f8916826127ec565b8355505b6001600288020188555050505b505050505050565b7f5075626c69632073616c65206973206e6f74206f70656e000000000000000000600082015250565b600061292e601783611fe3565b9150612939826128f8565b602082019050919050565b6000602082019050818103600083015261295d81612921565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061299e8261208a565b91506129a98361208a565b92508282019050808211156129c1576129c0612964565b5b92915050565b7f4d6178696d756d20737570706c79206578636565646564000000000000000000600082015250565b60006129fd601783611fe3565b9150612a08826129c7565b602082019050919050565b60006020820190508181036000830152612a2c816129f0565b9050919050565b6000612a3e8261208a565b9150612a498361208a565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612a8257612a81612964565b5b828202905092915050565b7f496e636f7272656374204554482076616c75652073656e740000000000000000600082015250565b6000612ac3601883611fe3565b9150612ace82612a8d565b602082019050919050565b60006020820190508181036000830152612af281612ab6565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000612b55602f83611fe3565b9150612b6082612af9565b604082019050919050565b60006020820190508181036000830152612b8481612b48565b9050919050565b600081905092915050565b60008154612ba381612649565b612bad8186612b8b565b94506001821660008114612bc85760018114612bdd57612c10565b60ff1983168652811515820286019350612c10565b612be68561267a565b60005b83811015612c0857815481890152600182019150602081019050612be9565b838801955050505b50505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b6000612c4f600183612b8b565b9150612c5a82612c19565b600182019050919050565b6000612c7082611fd8565b612c7a8185612b8b565b9350612c8a818560208601611ff4565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000612ccc600583612b8b565b9150612cd782612c96565b600582019050919050565b6000612cee8285612b96565b9150612cf982612c42565b9150612d058284612c65565b9150612d1082612cbf565b91508190509392505050565b7f496e76616c6964206d696e7420616d6f756e7400000000000000000000000000600082015250565b6000612d52601383611fe3565b9150612d5d82612d1c565b602082019050919050565b60006020820190508181036000830152612d8181612d45565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612de4602683611fe3565b9150612def82612d88565b604082019050919050565b60006020820190508181036000830152612e1381612dd7565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e50602083611fe3565b9150612e5b82612e1a565b602082019050919050565b60006020820190508181036000830152612e7f81612e43565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612ebc601f83611fe3565b9150612ec782612e86565b602082019050919050565b60006020820190508181036000830152612eeb81612eaf565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000612f28601d83611fe3565b9150612f3382612ef2565b602082019050919050565b60006020820190508181036000830152612f5781612f1b565b9050919050565b600081905092915050565b50565b6000612f79600083612f5e565b9150612f8482612f69565b600082019050919050565b6000612f9a82612f6c565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b6000613000603a83611fe3565b915061300b82612fa4565b604082019050919050565b6000602082019050818103600083015261302f81612ff3565b9050919050565b600081519050919050565b600082825260208201905092915050565b600061305d82613036565b6130678185613041565b9350613077818560208601611ff4565b6130808161201e565b840191505092915050565b60006080820190506130a06000830187612149565b6130ad6020830186612149565b6130ba6040830185612094565b81810360608301526130cc8184613052565b905095945050505050565b6000815190506130e681611f49565b92915050565b60006020828403121561310257613101611f13565b5b6000613110848285016130d7565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212204ae6b9c96235598d2bbe2c64d6268f193daad17611b1aa9a138fdeda62fbcbff64736f6c63430008100033

Deployed Bytecode Sourcemap

108967:2464:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75734:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76636:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109273:47;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83127:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82560:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72387:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;111028:115;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109329:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86766:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;110872:148;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;111286:142;;;;;;;;;;;;;:::i;:::-;;89687:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109866:108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78029:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73571:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20921:103;;;;;;;;;;;;;:::i;:::-;;20273:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76812:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;111149:127;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109442:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83685:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90478:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109232:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110413:312;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109090:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109196:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84076:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110089:316;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;21179:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75734:639;75819:4;76158:10;76143:25;;:11;:25;;;;:102;;;;76235:10;76220:25;;:11;:25;;;;76143:102;:179;;;;76312:10;76297:25;;:11;:25;;;;76143:179;76123:199;;75734:639;;;:::o;76636:100::-;76690:13;76723:5;76716:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76636:100;:::o;109273:47::-;;;;:::o;83127:218::-;83203:7;83228:16;83236:7;83228;:16::i;:::-;83223:64;;83253:34;;;;;;;;;;;;;;83223:64;83307:15;:24;83323:7;83307:24;;;;;;;;;;;:30;;;;;;;;;;;;83300:37;;83127:218;;;:::o;82560:408::-;82649:13;82665:16;82673:7;82665;:16::i;:::-;82649:32;;82721:5;82698:28;;:19;:17;:19::i;:::-;:28;;;82694:175;;82746:44;82763:5;82770:19;:17;:19::i;:::-;82746:16;:44::i;:::-;82741:128;;82818:35;;;;;;;;;;;;;;82741:128;82694:175;82914:2;82881:15;:24;82897:7;82881:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;82952:7;82948:2;82932:28;;82941:5;82932:28;;;;;;;;;;;;82638:330;82560:408;;:::o;72387:323::-;72448:7;72676:15;:13;:15::i;:::-;72661:12;;72645:13;;:28;:46;72638:53;;72387:323;:::o;111028:115::-;20159:13;:11;:13::i;:::-;111131:6:::1;111111:17;:26;;;;111028:115:::0;:::o;109329:38::-;;;;;;;;;;;;;:::o;86766:2825::-;86908:27;86938;86957:7;86938:18;:27::i;:::-;86908:57;;87023:4;86982:45;;86998:19;86982:45;;;86978:86;;87036:28;;;;;;;;;;;;;;86978:86;87078:27;87107:23;87134:35;87161:7;87134:26;:35::i;:::-;87077:92;;;;87269:68;87294:15;87311:4;87317:19;:17;:19::i;:::-;87269:24;:68::i;:::-;87264:180;;87357:43;87374:4;87380:19;:17;:19::i;:::-;87357:16;:43::i;:::-;87352:92;;87409:35;;;;;;;;;;;;;;87352:92;87264:180;87475:1;87461:16;;:2;:16;;;87457:52;;87486:23;;;;;;;;;;;;;;87457:52;87522:43;87544:4;87550:2;87554:7;87563:1;87522:21;:43::i;:::-;87658:15;87655:160;;;87798:1;87777:19;87770:30;87655:160;88195:18;:24;88214:4;88195:24;;;;;;;;;;;;;;;;88193:26;;;;;;;;;;;;88264:18;:22;88283:2;88264:22;;;;;;;;;;;;;;;;88262:24;;;;;;;;;;;88586:146;88623:2;88672:45;88687:4;88693:2;88697:19;88672:14;:45::i;:::-;68786:8;88644:73;88586:18;:146::i;:::-;88557:17;:26;88575:7;88557:26;;;;;;;;;;;:175;;;;88903:1;68786:8;88852:19;:47;:52;88848:627;;88925:19;88957:1;88947:7;:11;88925:33;;89114:1;89080:17;:30;89098:11;89080:30;;;;;;;;;;;;:35;89076:384;;89218:13;;89203:11;:28;89199:242;;89398:19;89365:17;:30;89383:11;89365:30;;;;;;;;;;;:52;;;;89199:242;89076:384;88906:569;88848:627;89522:7;89518:2;89503:27;;89512:4;89503:27;;;;;;;;;;;;89541:42;89562:4;89568:2;89572:7;89581:1;89541:20;:42::i;:::-;86897:2694;;;86766:2825;;;:::o;110872:148::-;20159:13;:11;:13::i;:::-;110995:19:::1;110974:18;;:40;;;;;;;;;;;;;;;;;;110872:148:::0;:::o;111286:142::-;20159:13;:11;:13::i;:::-;2345:21:::1;:19;:21::i;:::-;111361:61:::2;111387:10;111400:21;111361:17;:61::i;:::-;2389:20:::1;:18;:20::i;:::-;111286:142::o:0;89687:193::-;89833:39;89850:4;89856:2;89860:7;89833:39;;;;;;;;;;;;:16;:39::i;:::-;89687:193;;;:::o;109866:108::-;20159:13;:11;:13::i;:::-;109961:7:::1;109946:12;:22;;;;;;:::i;:::-;;109866:108:::0;:::o;78029:152::-;78101:7;78144:27;78163:7;78144:18;:27::i;:::-;78121:52;;78029:152;;;:::o;73571:233::-;73643:7;73684:1;73667:19;;:5;:19;;;73663:60;;73695:28;;;;;;;;;;;;;;73663:60;67730:13;73741:18;:25;73760:5;73741:25;;;;;;;;;;;;;;;;:55;73734:62;;73571:233;;;:::o;20921:103::-;20159:13;:11;:13::i;:::-;20986:30:::1;21013:1;20986:18;:30::i;:::-;20921:103::o:0;20273:87::-;20319:7;20346:6;;;;;;;;;;;20339:13;;20273:87;:::o;76812:104::-;76868:13;76901:7;76894:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76812:104;:::o;111149:127::-;20159:13;:11;:13::i;:::-;111264:6:::1;111245:16;:25;;;;111149:127:::0;:::o;109442:416::-;109529:18;;;;;;;;;;;109521:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;109632:9;;109614:14;109598:13;:11;:13::i;:::-;:30;;;;:::i;:::-;:43;;109582:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;109751:9;109732:14;109712:17;;:34;;;;:::i;:::-;109711:49;;109689:119;;;;;;;;;;;;:::i;:::-;;;;;;;;;109815:37;109825:10;109837:14;109815:9;:37::i;:::-;109442:416;:::o;83685:234::-;83832:8;83780:18;:39;83799:19;:17;:19::i;:::-;83780:39;;;;;;;;;;;;;;;:49;83820:8;83780:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;83892:8;83856:55;;83871:19;:17;:19::i;:::-;83856:55;;;83902:8;83856:55;;;;;;:::i;:::-;;;;;;;;83685:234;;:::o;90478:407::-;90653:31;90666:4;90672:2;90676:7;90653:12;:31::i;:::-;90717:1;90699:2;:14;;;:19;90695:183;;90738:56;90769:4;90775:2;90779:7;90788:5;90738:30;:56::i;:::-;90733:145;;90822:40;;;;;;;;;;;;;;90733:145;90695:183;90478:407;;;;:::o;109232:36::-;;;;:::o;110413:312::-;110509:13;110550:17;110558:8;110550:7;:17::i;:::-;110534:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;110670:12;110689:19;:8;:17;:19::i;:::-;110653:65;;;;;;;;;:::i;:::-;;;;;;;;;;;;;110639:80;;110413:312;;;:::o;109090:99::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;109196:31::-;;;;:::o;84076:164::-;84173:4;84197:18;:25;84216:5;84197:25;;;;;;;;;;;;;;;:35;84223:8;84197:35;;;;;;;;;;;;;;;;;;;;;;;;;84190:42;;84076:164;;;;:::o;110089:316::-;20159:13;:11;:13::i;:::-;110216:1:::1;110199:14;:18;110183:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;110311:9;;110293:14;110277:13;:11;:13::i;:::-;:30;;;;:::i;:::-;:43;;110261:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;110368:31;110378:4;110384:14;110368:9;:31::i;:::-;110089:316:::0;;:::o;21179:201::-;20159:13;:11;:13::i;:::-;21288:1:::1;21268:22;;:8;:22;;::::0;21260:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;21344:28;21363:8;21344:18;:28::i;:::-;21179:201:::0;:::o;84498:282::-;84563:4;84619:7;84600:15;:13;:15::i;:::-;:26;;:66;;;;;84653:13;;84643:7;:23;84600:66;:153;;;;;84752:1;68506:8;84704:17;:26;84722:7;84704:26;;;;;;;;;;;;:44;:49;84600:153;84580:173;;84498:282;;;:::o;106806:105::-;106866:7;106893:10;106886:17;;106806:105;:::o;109982:101::-;110047:7;110074:1;110067:8;;109982:101;:::o;20438:132::-;20513:12;:10;:12::i;:::-;20502:23;;:7;:5;:7::i;:::-;:23;;;20494:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;20438:132::o;79184:1275::-;79251:7;79271:12;79286:7;79271:22;;79354:4;79335:15;:13;:15::i;:::-;:23;79331:1061;;79388:13;;79381:4;:20;79377:1015;;;79426:14;79443:17;:23;79461:4;79443:23;;;;;;;;;;;;79426:40;;79560:1;68506:8;79532:6;:24;:29;79528:845;;80197:113;80214:1;80204:6;:11;80197:113;;80257:17;:25;80275:6;;;;;;;80257:25;;;;;;;;;;;;80248:34;;80197:113;;;80343:6;80336:13;;;;;;79528:845;79403:989;79377:1015;79331:1061;80420:31;;;;;;;;;;;;;;79184:1275;;;;:::o;85661:485::-;85763:27;85792:23;85833:38;85874:15;:24;85890:7;85874:24;;;;;;;;;;;85833:65;;86051:18;86028:41;;86108:19;86102:26;86083:45;;86013:126;85661:485;;;:::o;84889:659::-;85038:11;85203:16;85196:5;85192:28;85183:37;;85363:16;85352:9;85348:32;85335:45;;85513:15;85502:9;85499:30;85491:5;85480:9;85477:20;85474:56;85464:66;;84889:659;;;;;:::o;91547:159::-;;;;;:::o;106115:311::-;106250:7;106270:16;68910:3;106296:19;:41;;106270:68;;68910:3;106364:31;106375:4;106381:2;106385:9;106364:10;:31::i;:::-;106356:40;;:62;;106349:69;;;106115:311;;;;;:::o;81007:450::-;81087:14;81255:16;81248:5;81244:28;81235:37;;81432:5;81418:11;81393:23;81389:41;81386:52;81379:5;81376:63;81366:73;;81007:450;;;;:::o;92371:158::-;;;;;:::o;2425:293::-;1827:1;2559:7;;:19;2551:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1827:1;2692:7;:18;;;;2425:293::o;24232:317::-;24347:6;24322:21;:31;;24314:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;24401:12;24419:9;:14;;24441:6;24419:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24400:52;;;24471:7;24463:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;24303:246;24232:317;;:::o;2726:213::-;1783:1;2909:7;:22;;;;2726:213::o;21540:191::-;21614:16;21633:6;;;;;;;;;;;21614:25;;21659:8;21650:6;;:17;;;;;;;;;;;;;;;;;;21714:8;21683:40;;21704:8;21683:40;;;;;;;;;;;;21603:128;21540:191;:::o;100638:112::-;100715:27;100725:2;100729:8;100715:27;;;;;;;;;;;;:9;:27::i;:::-;100638:112;;:::o;92969:716::-;93132:4;93178:2;93153:45;;;93199:19;:17;:19::i;:::-;93220:4;93226:7;93235:5;93153:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;93149:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93453:1;93436:6;:13;:18;93432:235;;93482:40;;;;;;;;;;;;;;93432:235;93625:6;93619:13;93610:6;93606:2;93602:15;93595:38;93149:529;93322:54;;;93312:64;;;:6;:64;;;;93305:71;;;92969:716;;;;;;:::o;16251:::-;16307:13;16358:14;16395:1;16375:17;16386:5;16375:10;:17::i;:::-;:21;16358:38;;16411:20;16445:6;16434:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16411:41;;16467:11;16596:6;16592:2;16588:15;16580:6;16576:28;16569:35;;16633:288;16640:4;16633:288;;;16665:5;;;;;;;;16807:8;16802:2;16795:5;16791:14;16786:30;16781:3;16773:44;16863:2;16854:11;;;;;;:::i;:::-;;;;;16897:1;16888:5;:10;16633:288;16884:21;16633:288;16942:6;16935:13;;;;;16251:716;;;:::o;18824:98::-;18877:7;18904:10;18897:17;;18824:98;:::o;105816:147::-;105953:6;105816:147;;;;;:::o;99865:689::-;99996:19;100002:2;100006:8;99996:5;:19::i;:::-;100075:1;100057:2;:14;;;:19;100053:483;;100097:11;100111:13;;100097:27;;100143:13;100165:8;100159:3;:14;100143:30;;100192:233;100223:62;100262:1;100266:2;100270:7;;;;;;100279:5;100223:30;:62::i;:::-;100218:167;;100321:40;;;;;;;;;;;;;;100218:167;100420:3;100412:5;:11;100192:233;;100507:3;100490:13;;:20;100486:34;;100512:8;;;100486:34;100078:458;;100053:483;99865:689;;;:::o;13117:922::-;13170:7;13190:14;13207:1;13190:18;;13257:6;13248:5;:15;13244:102;;13293:6;13284:15;;;;;;:::i;:::-;;;;;13328:2;13318:12;;;;13244:102;13373:6;13364:5;:15;13360:102;;13409:6;13400:15;;;;;;:::i;:::-;;;;;13444:2;13434:12;;;;13360:102;13489:6;13480:5;:15;13476:102;;13525:6;13516:15;;;;;;:::i;:::-;;;;;13560:2;13550:12;;;;13476:102;13605:5;13596;:14;13592:99;;13640:5;13631:14;;;;;;:::i;:::-;;;;;13674:1;13664:11;;;;13592:99;13718:5;13709;:14;13705:99;;13753:5;13744:14;;;;;;:::i;:::-;;;;;13787:1;13777:11;;;;13705:99;13831:5;13822;:14;13818:99;;13866:5;13857:14;;;;;;:::i;:::-;;;;;13900:1;13890:11;;;;13818:99;13944:5;13935;:14;13931:66;;13980:1;13970:11;;;;13931:66;14025:6;14018:13;;;13117:922;;;:::o;94147:2966::-;94220:20;94243:13;;94220:36;;94283:1;94271:8;:13;94267:44;;94293:18;;;;;;;;;;;;;;94267:44;94324:61;94354:1;94358:2;94362:12;94376:8;94324:21;:61::i;:::-;94868:1;67868:2;94838:1;:26;;94837:32;94825:8;:45;94799:18;:22;94818:2;94799:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;95147:139;95184:2;95238:33;95261:1;95265:2;95269:1;95238:14;:33::i;:::-;95205:30;95226:8;95205:20;:30::i;:::-;:66;95147:18;:139::i;:::-;95113:17;:31;95131:12;95113:31;;;;;;;;;;;:173;;;;95303:16;95334:11;95363:8;95348:12;:23;95334:37;;95884:16;95880:2;95876:25;95864:37;;96256:12;96216:8;96175:1;96113:25;96054:1;95993;95966:335;96627:1;96613:12;96609:20;96567:346;96668:3;96659:7;96656:16;96567:346;;96886:7;96876:8;96873:1;96846:25;96843:1;96840;96835:59;96721:1;96712:7;96708:15;96697:26;;96567:346;;;96571:77;96958:1;96946:8;:13;96942:45;;96968:19;;;;;;;;;;;;;;96942:45;97020:3;97004:13;:19;;;;94573:2462;;97045:60;97074:1;97078:2;97082:12;97096:8;97045:20;:60::i;:::-;94209:2904;94147:2966;;:::o;81559:324::-;81629:14;81862:1;81852:8;81849:15;81823:24;81819:46;81809:56;;81559:324;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:118::-;3030:24;3048:5;3030:24;:::i;:::-;3025:3;3018:37;2943:118;;:::o;3067:222::-;3160:4;3198:2;3187:9;3183:18;3175:26;;3211:71;3279:1;3268:9;3264:17;3255:6;3211:71;:::i;:::-;3067:222;;;;:::o;3295:122::-;3368:24;3386:5;3368:24;:::i;:::-;3361:5;3358:35;3348:63;;3407:1;3404;3397:12;3348:63;3295:122;:::o;3423:139::-;3469:5;3507:6;3494:20;3485:29;;3523:33;3550:5;3523:33;:::i;:::-;3423:139;;;;:::o;3568:329::-;3627:6;3676:2;3664:9;3655:7;3651:23;3647:32;3644:119;;;3682:79;;:::i;:::-;3644:119;3802:1;3827:53;3872:7;3863:6;3852:9;3848:22;3827:53;:::i;:::-;3817:63;;3773:117;3568:329;;;;:::o;3903:126::-;3940:7;3980:42;3973:5;3969:54;3958:65;;3903:126;;;:::o;4035:96::-;4072:7;4101:24;4119:5;4101:24;:::i;:::-;4090:35;;4035:96;;;:::o;4137:118::-;4224:24;4242:5;4224:24;:::i;:::-;4219:3;4212:37;4137:118;;:::o;4261:222::-;4354:4;4392:2;4381:9;4377:18;4369:26;;4405:71;4473:1;4462:9;4458:17;4449:6;4405:71;:::i;:::-;4261:222;;;;:::o;4489:122::-;4562:24;4580:5;4562:24;:::i;:::-;4555:5;4552:35;4542:63;;4601:1;4598;4591:12;4542:63;4489:122;:::o;4617:139::-;4663:5;4701:6;4688:20;4679:29;;4717:33;4744:5;4717:33;:::i;:::-;4617:139;;;;:::o;4762:474::-;4830:6;4838;4887:2;4875:9;4866:7;4862:23;4858:32;4855:119;;;4893:79;;:::i;:::-;4855:119;5013:1;5038:53;5083:7;5074:6;5063:9;5059:22;5038:53;:::i;:::-;5028:63;;4984:117;5140:2;5166:53;5211:7;5202:6;5191:9;5187:22;5166:53;:::i;:::-;5156:63;;5111:118;4762:474;;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:116::-;5937:21;5952:5;5937:21;:::i;:::-;5930:5;5927:32;5917:60;;5973:1;5970;5963:12;5917:60;5867:116;:::o;5989:133::-;6032:5;6070:6;6057:20;6048:29;;6086:30;6110:5;6086:30;:::i;:::-;5989:133;;;;:::o;6128:323::-;6184:6;6233:2;6221:9;6212:7;6208:23;6204:32;6201:119;;;6239:79;;:::i;:::-;6201:119;6359:1;6384:50;6426:7;6417:6;6406:9;6402:22;6384:50;:::i;:::-;6374:60;;6330:114;6128:323;;;;:::o;6457:117::-;6566:1;6563;6556:12;6580:117;6689:1;6686;6679:12;6703:180;6751:77;6748:1;6741:88;6848:4;6845:1;6838:15;6872:4;6869:1;6862:15;6889:281;6972:27;6994:4;6972:27;:::i;:::-;6964:6;6960:40;7102:6;7090:10;7087:22;7066:18;7054:10;7051:34;7048:62;7045:88;;;7113:18;;:::i;:::-;7045:88;7153:10;7149:2;7142:22;6932:238;6889:281;;:::o;7176:129::-;7210:6;7237:20;;:::i;:::-;7227:30;;7266:33;7294:4;7286:6;7266:33;:::i;:::-;7176:129;;;:::o;7311:308::-;7373:4;7463:18;7455:6;7452:30;7449:56;;;7485:18;;:::i;:::-;7449:56;7523:29;7545:6;7523:29;:::i;:::-;7515:37;;7607:4;7601;7597:15;7589:23;;7311:308;;;:::o;7625:146::-;7722:6;7717:3;7712;7699:30;7763:1;7754:6;7749:3;7745:16;7738:27;7625:146;;;:::o;7777:425::-;7855:5;7880:66;7896:49;7938:6;7896:49;:::i;:::-;7880:66;:::i;:::-;7871:75;;7969:6;7962:5;7955:21;8007:4;8000:5;7996:16;8045:3;8036:6;8031:3;8027:16;8024:25;8021:112;;;8052:79;;:::i;:::-;8021:112;8142:54;8189:6;8184:3;8179;8142:54;:::i;:::-;7861:341;7777:425;;;;;:::o;8222:340::-;8278:5;8327:3;8320:4;8312:6;8308:17;8304:27;8294:122;;8335:79;;:::i;:::-;8294:122;8452:6;8439:20;8477:79;8552:3;8544:6;8537:4;8529:6;8525:17;8477:79;:::i;:::-;8468:88;;8284:278;8222:340;;;;:::o;8568:509::-;8637:6;8686:2;8674:9;8665:7;8661:23;8657:32;8654:119;;;8692:79;;:::i;:::-;8654:119;8840:1;8829:9;8825:17;8812:31;8870:18;8862:6;8859:30;8856:117;;;8892:79;;:::i;:::-;8856:117;8997:63;9052:7;9043:6;9032:9;9028:22;8997:63;:::i;:::-;8987:73;;8783:287;8568:509;;;;:::o;9083:329::-;9142:6;9191:2;9179:9;9170:7;9166:23;9162:32;9159:119;;;9197:79;;:::i;:::-;9159:119;9317:1;9342:53;9387:7;9378:6;9367:9;9363:22;9342:53;:::i;:::-;9332:63;;9288:117;9083:329;;;;:::o;9418:468::-;9483:6;9491;9540:2;9528:9;9519:7;9515:23;9511:32;9508:119;;;9546:79;;:::i;:::-;9508:119;9666:1;9691:53;9736:7;9727:6;9716:9;9712:22;9691:53;:::i;:::-;9681:63;;9637:117;9793:2;9819:50;9861:7;9852:6;9841:9;9837:22;9819:50;:::i;:::-;9809:60;;9764:115;9418:468;;;;;:::o;9892:307::-;9953:4;10043:18;10035:6;10032:30;10029:56;;;10065:18;;:::i;:::-;10029:56;10103:29;10125:6;10103:29;:::i;:::-;10095:37;;10187:4;10181;10177:15;10169:23;;9892:307;;;:::o;10205:423::-;10282:5;10307:65;10323:48;10364:6;10323:48;:::i;:::-;10307:65;:::i;:::-;10298:74;;10395:6;10388:5;10381:21;10433:4;10426:5;10422:16;10471:3;10462:6;10457:3;10453:16;10450:25;10447:112;;;10478:79;;:::i;:::-;10447:112;10568:54;10615:6;10610:3;10605;10568:54;:::i;:::-;10288:340;10205:423;;;;;:::o;10647:338::-;10702:5;10751:3;10744:4;10736:6;10732:17;10728:27;10718:122;;10759:79;;:::i;:::-;10718:122;10876:6;10863:20;10901:78;10975:3;10967:6;10960:4;10952:6;10948:17;10901:78;:::i;:::-;10892:87;;10708:277;10647:338;;;;:::o;10991:943::-;11086:6;11094;11102;11110;11159:3;11147:9;11138:7;11134:23;11130:33;11127:120;;;11166:79;;:::i;:::-;11127:120;11286:1;11311:53;11356:7;11347:6;11336:9;11332:22;11311:53;:::i;:::-;11301:63;;11257:117;11413:2;11439:53;11484:7;11475:6;11464:9;11460:22;11439:53;:::i;:::-;11429:63;;11384:118;11541:2;11567:53;11612:7;11603:6;11592:9;11588:22;11567:53;:::i;:::-;11557:63;;11512:118;11697:2;11686:9;11682:18;11669:32;11728:18;11720:6;11717:30;11714:117;;;11750:79;;:::i;:::-;11714:117;11855:62;11909:7;11900:6;11889:9;11885:22;11855:62;:::i;:::-;11845:72;;11640:287;10991:943;;;;;;;:::o;11940:474::-;12008:6;12016;12065:2;12053:9;12044:7;12040:23;12036:32;12033:119;;;12071:79;;:::i;:::-;12033:119;12191:1;12216:53;12261:7;12252:6;12241:9;12237:22;12216:53;:::i;:::-;12206:63;;12162:117;12318:2;12344:53;12389:7;12380:6;12369:9;12365:22;12344:53;:::i;:::-;12334:63;;12289:118;11940:474;;;;;:::o;12420:::-;12488:6;12496;12545:2;12533:9;12524:7;12520:23;12516:32;12513:119;;;12551:79;;:::i;:::-;12513:119;12671:1;12696:53;12741:7;12732:6;12721:9;12717:22;12696:53;:::i;:::-;12686:63;;12642:117;12798:2;12824:53;12869:7;12860:6;12849:9;12845:22;12824:53;:::i;:::-;12814:63;;12769:118;12420:474;;;;;:::o;12900:180::-;12948:77;12945:1;12938:88;13045:4;13042:1;13035:15;13069:4;13066:1;13059:15;13086:320;13130:6;13167:1;13161:4;13157:12;13147:22;;13214:1;13208:4;13204:12;13235:18;13225:81;;13291:4;13283:6;13279:17;13269:27;;13225:81;13353:2;13345:6;13342:14;13322:18;13319:38;13316:84;;13372:18;;:::i;:::-;13316:84;13137:269;13086:320;;;:::o;13412:141::-;13461:4;13484:3;13476:11;;13507:3;13504:1;13497:14;13541:4;13538:1;13528:18;13520:26;;13412:141;;;:::o;13559:93::-;13596:6;13643:2;13638;13631:5;13627:14;13623:23;13613:33;;13559:93;;;:::o;13658:107::-;13702:8;13752:5;13746:4;13742:16;13721:37;;13658:107;;;;:::o;13771:393::-;13840:6;13890:1;13878:10;13874:18;13913:97;13943:66;13932:9;13913:97;:::i;:::-;14031:39;14061:8;14050:9;14031:39;:::i;:::-;14019:51;;14103:4;14099:9;14092:5;14088:21;14079:30;;14152:4;14142:8;14138:19;14131:5;14128:30;14118:40;;13847:317;;13771:393;;;;;:::o;14170:60::-;14198:3;14219:5;14212:12;;14170:60;;;:::o;14236:142::-;14286:9;14319:53;14337:34;14346:24;14364:5;14346:24;:::i;:::-;14337:34;:::i;:::-;14319:53;:::i;:::-;14306:66;;14236:142;;;:::o;14384:75::-;14427:3;14448:5;14441:12;;14384:75;;;:::o;14465:269::-;14575:39;14606:7;14575:39;:::i;:::-;14636:91;14685:41;14709:16;14685:41;:::i;:::-;14677:6;14670:4;14664:11;14636:91;:::i;:::-;14630:4;14623:105;14541:193;14465:269;;;:::o;14740:73::-;14785:3;14740:73;:::o;14819:189::-;14896:32;;:::i;:::-;14937:65;14995:6;14987;14981:4;14937:65;:::i;:::-;14872:136;14819:189;;:::o;15014:186::-;15074:120;15091:3;15084:5;15081:14;15074:120;;;15145:39;15182:1;15175:5;15145:39;:::i;:::-;15118:1;15111:5;15107:13;15098:22;;15074:120;;;15014:186;;:::o;15206:543::-;15307:2;15302:3;15299:11;15296:446;;;15341:38;15373:5;15341:38;:::i;:::-;15425:29;15443:10;15425:29;:::i;:::-;15415:8;15411:44;15608:2;15596:10;15593:18;15590:49;;;15629:8;15614:23;;15590:49;15652:80;15708:22;15726:3;15708:22;:::i;:::-;15698:8;15694:37;15681:11;15652:80;:::i;:::-;15311:431;;15296:446;15206:543;;;:::o;15755:117::-;15809:8;15859:5;15853:4;15849:16;15828:37;;15755:117;;;;:::o;15878:169::-;15922:6;15955:51;16003:1;15999:6;15991:5;15988:1;15984:13;15955:51;:::i;:::-;15951:56;16036:4;16030;16026:15;16016:25;;15929:118;15878:169;;;;:::o;16052:295::-;16128:4;16274:29;16299:3;16293:4;16274:29;:::i;:::-;16266:37;;16336:3;16333:1;16329:11;16323:4;16320:21;16312:29;;16052:295;;;;:::o;16352:1395::-;16469:37;16502:3;16469:37;:::i;:::-;16571:18;16563:6;16560:30;16557:56;;;16593:18;;:::i;:::-;16557:56;16637:38;16669:4;16663:11;16637:38;:::i;:::-;16722:67;16782:6;16774;16768:4;16722:67;:::i;:::-;16816:1;16840:4;16827:17;;16872:2;16864:6;16861:14;16889:1;16884:618;;;;17546:1;17563:6;17560:77;;;17612:9;17607:3;17603:19;17597:26;17588:35;;17560:77;17663:67;17723:6;17716:5;17663:67;:::i;:::-;17657:4;17650:81;17519:222;16854:887;;16884:618;16936:4;16932:9;16924:6;16920:22;16970:37;17002:4;16970:37;:::i;:::-;17029:1;17043:208;17057:7;17054:1;17051:14;17043:208;;;17136:9;17131:3;17127:19;17121:26;17113:6;17106:42;17187:1;17179:6;17175:14;17165:24;;17234:2;17223:9;17219:18;17206:31;;17080:4;17077:1;17073:12;17068:17;;17043:208;;;17279:6;17270:7;17267:19;17264:179;;;17337:9;17332:3;17328:19;17322:26;17380:48;17422:4;17414:6;17410:17;17399:9;17380:48;:::i;:::-;17372:6;17365:64;17287:156;17264:179;17489:1;17485;17477:6;17473:14;17469:22;17463:4;17456:36;16891:611;;;16854:887;;16444:1303;;;16352:1395;;:::o;17753:173::-;17893:25;17889:1;17881:6;17877:14;17870:49;17753:173;:::o;17932:366::-;18074:3;18095:67;18159:2;18154:3;18095:67;:::i;:::-;18088:74;;18171:93;18260:3;18171:93;:::i;:::-;18289:2;18284:3;18280:12;18273:19;;17932:366;;;:::o;18304:419::-;18470:4;18508:2;18497:9;18493:18;18485:26;;18557:9;18551:4;18547:20;18543:1;18532:9;18528:17;18521:47;18585:131;18711:4;18585:131;:::i;:::-;18577:139;;18304:419;;;:::o;18729:180::-;18777:77;18774:1;18767:88;18874:4;18871:1;18864:15;18898:4;18895:1;18888:15;18915:191;18955:3;18974:20;18992:1;18974:20;:::i;:::-;18969:25;;19008:20;19026:1;19008:20;:::i;:::-;19003:25;;19051:1;19048;19044:9;19037:16;;19072:3;19069:1;19066:10;19063:36;;;19079:18;;:::i;:::-;19063:36;18915:191;;;;:::o;19112:173::-;19252:25;19248:1;19240:6;19236:14;19229:49;19112:173;:::o;19291:366::-;19433:3;19454:67;19518:2;19513:3;19454:67;:::i;:::-;19447:74;;19530:93;19619:3;19530:93;:::i;:::-;19648:2;19643:3;19639:12;19632:19;;19291:366;;;:::o;19663:419::-;19829:4;19867:2;19856:9;19852:18;19844:26;;19916:9;19910:4;19906:20;19902:1;19891:9;19887:17;19880:47;19944:131;20070:4;19944:131;:::i;:::-;19936:139;;19663:419;;;:::o;20088:348::-;20128:7;20151:20;20169:1;20151:20;:::i;:::-;20146:25;;20185:20;20203:1;20185:20;:::i;:::-;20180:25;;20373:1;20305:66;20301:74;20298:1;20295:81;20290:1;20283:9;20276:17;20272:105;20269:131;;;20380:18;;:::i;:::-;20269:131;20428:1;20425;20421:9;20410:20;;20088:348;;;;:::o;20442:174::-;20582:26;20578:1;20570:6;20566:14;20559:50;20442:174;:::o;20622:366::-;20764:3;20785:67;20849:2;20844:3;20785:67;:::i;:::-;20778:74;;20861:93;20950:3;20861:93;:::i;:::-;20979:2;20974:3;20970:12;20963:19;;20622:366;;;:::o;20994:419::-;21160:4;21198:2;21187:9;21183:18;21175:26;;21247:9;21241:4;21237:20;21233:1;21222:9;21218:17;21211:47;21275:131;21401:4;21275:131;:::i;:::-;21267:139;;20994:419;;;:::o;21419:234::-;21559:34;21555:1;21547:6;21543:14;21536:58;21628:17;21623:2;21615:6;21611:15;21604:42;21419:234;:::o;21659:366::-;21801:3;21822:67;21886:2;21881:3;21822:67;:::i;:::-;21815:74;;21898:93;21987:3;21898:93;:::i;:::-;22016:2;22011:3;22007:12;22000:19;;21659:366;;;:::o;22031:419::-;22197:4;22235:2;22224:9;22220:18;22212:26;;22284:9;22278:4;22274:20;22270:1;22259:9;22255:17;22248:47;22312:131;22438:4;22312:131;:::i;:::-;22304:139;;22031:419;;;:::o;22456:148::-;22558:11;22595:3;22580:18;;22456:148;;;;:::o;22634:874::-;22737:3;22774:5;22768:12;22803:36;22829:9;22803:36;:::i;:::-;22855:89;22937:6;22932:3;22855:89;:::i;:::-;22848:96;;22975:1;22964:9;22960:17;22991:1;22986:166;;;;23166:1;23161:341;;;;22953:549;;22986:166;23070:4;23066:9;23055;23051:25;23046:3;23039:38;23132:6;23125:14;23118:22;23110:6;23106:35;23101:3;23097:45;23090:52;;22986:166;;23161:341;23228:38;23260:5;23228:38;:::i;:::-;23288:1;23302:154;23316:6;23313:1;23310:13;23302:154;;;23390:7;23384:14;23380:1;23375:3;23371:11;23364:35;23440:1;23431:7;23427:15;23416:26;;23338:4;23335:1;23331:12;23326:17;;23302:154;;;23485:6;23480:3;23476:16;23469:23;;23168:334;;22953:549;;22741:767;;22634:874;;;;:::o;23514:151::-;23654:3;23650:1;23642:6;23638:14;23631:27;23514:151;:::o;23671:400::-;23831:3;23852:84;23934:1;23929:3;23852:84;:::i;:::-;23845:91;;23945:93;24034:3;23945:93;:::i;:::-;24063:1;24058:3;24054:11;24047:18;;23671:400;;;:::o;24077:390::-;24183:3;24211:39;24244:5;24211:39;:::i;:::-;24266:89;24348:6;24343:3;24266:89;:::i;:::-;24259:96;;24364:65;24422:6;24417:3;24410:4;24403:5;24399:16;24364:65;:::i;:::-;24454:6;24449:3;24445:16;24438:23;;24187:280;24077:390;;;;:::o;24473:155::-;24613:7;24609:1;24601:6;24597:14;24590:31;24473:155;:::o;24634:400::-;24794:3;24815:84;24897:1;24892:3;24815:84;:::i;:::-;24808:91;;24908:93;24997:3;24908:93;:::i;:::-;25026:1;25021:3;25017:11;25010:18;;24634:400;;;:::o;25040:961::-;25419:3;25441:92;25529:3;25520:6;25441:92;:::i;:::-;25434:99;;25550:148;25694:3;25550:148;:::i;:::-;25543:155;;25715:95;25806:3;25797:6;25715:95;:::i;:::-;25708:102;;25827:148;25971:3;25827:148;:::i;:::-;25820:155;;25992:3;25985:10;;25040:961;;;;;:::o;26007:169::-;26147:21;26143:1;26135:6;26131:14;26124:45;26007:169;:::o;26182:366::-;26324:3;26345:67;26409:2;26404:3;26345:67;:::i;:::-;26338:74;;26421:93;26510:3;26421:93;:::i;:::-;26539:2;26534:3;26530:12;26523:19;;26182:366;;;:::o;26554:419::-;26720:4;26758:2;26747:9;26743:18;26735:26;;26807:9;26801:4;26797:20;26793:1;26782:9;26778:17;26771:47;26835:131;26961:4;26835:131;:::i;:::-;26827:139;;26554:419;;;:::o;26979:225::-;27119:34;27115:1;27107:6;27103:14;27096:58;27188:8;27183:2;27175:6;27171:15;27164:33;26979:225;:::o;27210:366::-;27352:3;27373:67;27437:2;27432:3;27373:67;:::i;:::-;27366:74;;27449:93;27538:3;27449:93;:::i;:::-;27567:2;27562:3;27558:12;27551:19;;27210:366;;;:::o;27582:419::-;27748:4;27786:2;27775:9;27771:18;27763:26;;27835:9;27829:4;27825:20;27821:1;27810:9;27806:17;27799:47;27863:131;27989:4;27863:131;:::i;:::-;27855:139;;27582:419;;;:::o;28007:182::-;28147:34;28143:1;28135:6;28131:14;28124:58;28007:182;:::o;28195:366::-;28337:3;28358:67;28422:2;28417:3;28358:67;:::i;:::-;28351:74;;28434:93;28523:3;28434:93;:::i;:::-;28552:2;28547:3;28543:12;28536:19;;28195:366;;;:::o;28567:419::-;28733:4;28771:2;28760:9;28756:18;28748:26;;28820:9;28814:4;28810:20;28806:1;28795:9;28791:17;28784:47;28848:131;28974:4;28848:131;:::i;:::-;28840:139;;28567:419;;;:::o;28992:181::-;29132:33;29128:1;29120:6;29116:14;29109:57;28992:181;:::o;29179:366::-;29321:3;29342:67;29406:2;29401:3;29342:67;:::i;:::-;29335:74;;29418:93;29507:3;29418:93;:::i;:::-;29536:2;29531:3;29527:12;29520:19;;29179:366;;;:::o;29551:419::-;29717:4;29755:2;29744:9;29740:18;29732:26;;29804:9;29798:4;29794:20;29790:1;29779:9;29775:17;29768:47;29832:131;29958:4;29832:131;:::i;:::-;29824:139;;29551:419;;;:::o;29976:179::-;30116:31;30112:1;30104:6;30100:14;30093:55;29976:179;:::o;30161:366::-;30303:3;30324:67;30388:2;30383:3;30324:67;:::i;:::-;30317:74;;30400:93;30489:3;30400:93;:::i;:::-;30518:2;30513:3;30509:12;30502:19;;30161:366;;;:::o;30533:419::-;30699:4;30737:2;30726:9;30722:18;30714:26;;30786:9;30780:4;30776:20;30772:1;30761:9;30757:17;30750:47;30814:131;30940:4;30814:131;:::i;:::-;30806:139;;30533:419;;;:::o;30958:147::-;31059:11;31096:3;31081:18;;30958:147;;;;:::o;31111:114::-;;:::o;31231:398::-;31390:3;31411:83;31492:1;31487:3;31411:83;:::i;:::-;31404:90;;31503:93;31592:3;31503:93;:::i;:::-;31621:1;31616:3;31612:11;31605:18;;31231:398;;;:::o;31635:379::-;31819:3;31841:147;31984:3;31841:147;:::i;:::-;31834:154;;32005:3;31998:10;;31635:379;;;:::o;32020:245::-;32160:34;32156:1;32148:6;32144:14;32137:58;32229:28;32224:2;32216:6;32212:15;32205:53;32020:245;:::o;32271:366::-;32413:3;32434:67;32498:2;32493:3;32434:67;:::i;:::-;32427:74;;32510:93;32599:3;32510:93;:::i;:::-;32628:2;32623:3;32619:12;32612:19;;32271:366;;;:::o;32643:419::-;32809:4;32847:2;32836:9;32832:18;32824:26;;32896:9;32890:4;32886:20;32882:1;32871:9;32867:17;32860:47;32924:131;33050:4;32924:131;:::i;:::-;32916:139;;32643:419;;;:::o;33068:98::-;33119:6;33153:5;33147:12;33137:22;;33068:98;;;:::o;33172:168::-;33255:11;33289:6;33284:3;33277:19;33329:4;33324:3;33320:14;33305:29;;33172:168;;;;:::o;33346:373::-;33432:3;33460:38;33492:5;33460:38;:::i;:::-;33514:70;33577:6;33572:3;33514:70;:::i;:::-;33507:77;;33593:65;33651:6;33646:3;33639:4;33632:5;33628:16;33593:65;:::i;:::-;33683:29;33705:6;33683:29;:::i;:::-;33678:3;33674:39;33667:46;;33436:283;33346:373;;;;:::o;33725:640::-;33920:4;33958:3;33947:9;33943:19;33935:27;;33972:71;34040:1;34029:9;34025:17;34016:6;33972:71;:::i;:::-;34053:72;34121:2;34110:9;34106:18;34097:6;34053:72;:::i;:::-;34135;34203:2;34192:9;34188:18;34179:6;34135:72;:::i;:::-;34254:9;34248:4;34244:20;34239:2;34228:9;34224:18;34217:48;34282:76;34353:4;34344:6;34282:76;:::i;:::-;34274:84;;33725:640;;;;;;;:::o;34371:141::-;34427:5;34458:6;34452:13;34443:22;;34474:32;34500:5;34474:32;:::i;:::-;34371:141;;;;:::o;34518:349::-;34587:6;34636:2;34624:9;34615:7;34611:23;34607:32;34604:119;;;34642:79;;:::i;:::-;34604:119;34762:1;34787:63;34842:7;34833:6;34822:9;34818:22;34787:63;:::i;:::-;34777:73;;34733:127;34518:349;;;;:::o;34873:180::-;34921:77;34918:1;34911:88;35018:4;35015:1;35008:15;35042:4;35039:1;35032:15

Swarm Source

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