ETH Price: $2,413.78 (-10.88%)

Token

Nova Astronaut (Nastro)

Overview

Max Total Supply

552 Nastro

Holders

281

Transfers

-
0

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
NovaAstronaut

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Nova.Arbiscan.io on 2023-02-16
*/

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

// File: @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;
            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/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// 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: @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)

pragma solidity ^0.8.0;


/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

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

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev See {ERC721-_burn}. This override additionally checks to see if a
     * token-specific URI was set for the token, and if so, it deletes the token URI from
     * the storage mapping.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

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


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

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: novaastro.sol


pragma solidity ^0.8.9;






contract NovaAstronaut is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("Nova Astronaut", "Nastro") {}

function safeMint(address to, uint256 num, string memory uri) public onlyOwner {
        uint256 supply = totalSupply();
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        require(supply + num <= 100000, "Exceeded total supply");
        for (uint256 i; i < num; i++) {
        _safeMint(to, supply + i);
        _setTokenURI(supply + i, uri);
        }
    }

    // The following functions are overrides required by Solidity.

    function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
        internal
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
    }

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"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":"to","type":"address"},{"internalType":"uint256","name":"num","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"safeMint","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040518060400160405280600e81526020017f4e6f766120417374726f6e6175740000000000000000000000000000000000008152506040518060400160405280600681526020017f4e617374726f0000000000000000000000000000000000000000000000000000815250816000908051906020019062000096929190620001a6565b508060019080519060200190620000af929190620001a6565b505050620000d2620000c6620000d860201b60201c565b620000e060201b60201c565b620002bb565b600033905090565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620001b49062000285565b90600052602060002090601f016020900481019282620001d8576000855562000224565b82601f10620001f357805160ff191683800117855562000224565b8280016001018555821562000224579182015b828111156200022357825182559160200191906001019062000206565b5b50905062000233919062000237565b5090565b5b808211156200025257600081600090555060010162000238565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200029e57607f821691505b60208210811415620002b557620002b462000256565b5b50919050565b61388f80620002cb6000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c806370a08231116100ad578063b88d4fde11610071578063b88d4fde14610343578063c87b56dd1461035f578063cd279c7c1461038f578063e985e9c5146103ab578063f2fde38b146103db5761012c565b806370a08231146102b1578063715018a6146102e15780638da5cb5b146102eb57806395d89b4114610309578063a22cb465146103275761012c565b806323b872dd116100f457806323b872dd146101e95780632f745c591461020557806342842e0e146102355780634f6ccce7146102515780636352211e146102815761012c565b806301ffc9a71461013157806306fdde0314610161578063081812fc1461017f578063095ea7b3146101af57806318160ddd146101cb575b600080fd5b61014b6004803603810190610146919061255f565b6103f7565b60405161015891906125a7565b60405180910390f35b610169610409565b604051610176919061265b565b60405180910390f35b610199600480360381019061019491906126b3565b61049b565b6040516101a69190612721565b60405180910390f35b6101c960048036038101906101c49190612768565b6104e1565b005b6101d36105f9565b6040516101e091906127b7565b60405180910390f35b61020360048036038101906101fe91906127d2565b610606565b005b61021f600480360381019061021a9190612768565b610666565b60405161022c91906127b7565b60405180910390f35b61024f600480360381019061024a91906127d2565b61070b565b005b61026b600480360381019061026691906126b3565b61072b565b60405161027891906127b7565b60405180910390f35b61029b600480360381019061029691906126b3565b61079c565b6040516102a89190612721565b60405180910390f35b6102cb60048036038101906102c69190612825565b610823565b6040516102d891906127b7565b60405180910390f35b6102e96108db565b005b6102f36108ef565b6040516103009190612721565b60405180910390f35b610311610919565b60405161031e919061265b565b60405180910390f35b610341600480360381019061033c919061287e565b6109ab565b005b61035d600480360381019061035891906129f3565b6109c1565b005b610379600480360381019061037491906126b3565b610a23565b604051610386919061265b565b60405180910390f35b6103a960048036038101906103a49190612b17565b610a35565b005b6103c560048036038101906103c09190612b86565b610b02565b6040516103d291906125a7565b60405180910390f35b6103f560048036038101906103f09190612825565b610b96565b005b600061040282610c1a565b9050919050565b60606000805461041890612bf5565b80601f016020809104026020016040519081016040528092919081815260200182805461044490612bf5565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b5050505050905090565b60006104a682610c94565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006104ec8261079c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561055d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161055490612c99565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661057c610cdf565b73ffffffffffffffffffffffffffffffffffffffff1614806105ab57506105aa816105a5610cdf565b610b02565b5b6105ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e190612d2b565b60405180910390fd5b6105f48383610ce7565b505050565b6000600880549050905090565b610617610611610cdf565b82610da0565b610656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064d90612dbd565b60405180910390fd5b610661838383610e35565b505050565b600061067183610823565b82106106b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a990612e4f565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610726838383604051806020016040528060008152506109c1565b505050565b60006107356105f9565b8210610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076d90612ee1565b60405180910390fd5b6008828154811061078a57610789612f01565b5b90600052602060002001549050919050565b6000806107a88361112f565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561081a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081190612f7c565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610894576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088b9061300e565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6108e361116c565b6108ed60006111ea565b565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461092890612bf5565b80601f016020809104026020016040519081016040528092919081815260200182805461095490612bf5565b80156109a15780601f10610976576101008083540402835291602001916109a1565b820191906000526020600020905b81548152906001019060200180831161098457829003601f168201915b5050505050905090565b6109bd6109b6610cdf565b83836112b0565b5050565b6109d26109cc610cdf565b83610da0565b610a11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0890612dbd565b60405180910390fd5b610a1d8484848461141d565b50505050565b6060610a2e82611479565b9050919050565b610a3d61116c565b6000610a476105f9565b90506000610a55600c61158c565b9050610a61600c61159a565b620186a08483610a71919061305d565b1115610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa9906130ff565b60405180910390fd5b60005b84811015610afa57610ad2868285610acd919061305d565b6115b0565b610ae78184610ae1919061305d565b856115ce565b8080610af29061311f565b915050610ab5565b505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610b9e61116c565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610c0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c05906131da565b60405180910390fd5b610c17816111ea565b50565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c8d5750610c8c82611642565b5b9050919050565b610c9d81611724565b610cdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd390612f7c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610d5a8361079c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610dac8361079c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610dee5750610ded8185610b02565b5b80610e2c57508373ffffffffffffffffffffffffffffffffffffffff16610e148461049b565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610e558261079c565b73ffffffffffffffffffffffffffffffffffffffff1614610eab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea29061326c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f12906132fe565b60405180910390fd5b610f288383836001611765565b8273ffffffffffffffffffffffffffffffffffffffff16610f488261079c565b73ffffffffffffffffffffffffffffffffffffffff1614610f9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f959061326c565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461112a8383836001611777565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b611174610cdf565b73ffffffffffffffffffffffffffffffffffffffff166111926108ef565b73ffffffffffffffffffffffffffffffffffffffff16146111e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111df9061336a565b60405180910390fd5b565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561131f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611316906133d6565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161141091906125a7565b60405180910390a3505050565b611428848484610e35565b6114348484848461177d565b611473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146a90613468565b60405180910390fd5b50505050565b606061148482610c94565b6000600a600084815260200190815260200160002080546114a490612bf5565b80601f01602080910402602001604051908101604052809291908181526020018280546114d090612bf5565b801561151d5780601f106114f25761010080835404028352916020019161151d565b820191906000526020600020905b81548152906001019060200180831161150057829003601f168201915b50505050509050600061152e611914565b9050600081511415611544578192505050611587565b6000825111156115795780826040516020016115619291906134c4565b60405160208183030381529060405292505050611587565b6115828461192b565b925050505b919050565b600081600001549050919050565b6001816000016000828254019250508190555050565b6115ca828260405180602001604052806000815250611993565b5050565b6115d782611724565b611616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160d9061355a565b60405180910390fd5b80600a6000848152602001908152602001600020908051906020019061163d929190612450565b505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061170d57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061171d575061171c826119ee565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166117468361112f565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b61177184848484611a58565b50505050565b50505050565b600061179e8473ffffffffffffffffffffffffffffffffffffffff16611bb8565b15611907578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026117c7610cdf565b8786866040518563ffffffff1660e01b81526004016117e994939291906135cf565b602060405180830381600087803b15801561180357600080fd5b505af192505050801561183457506040513d601f19601f820116820180604052508101906118319190613630565b60015b6118b7573d8060008114611864576040519150601f19603f3d011682016040523d82523d6000602084013e611869565b606091505b506000815114156118af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118a690613468565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061190c565b600190505b949350505050565b606060405180602001604052806000815250905090565b606061193682610c94565b6000611940611914565b90506000815111611960576040518060200160405280600081525061198b565b8061196a84611bdb565b60405160200161197b9291906134c4565b6040516020818303038152906040525b915050919050565b61199d8383611cb3565b6119aa600084848461177d565b6119e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e090613468565b60405180910390fd5b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611a6484848484611ed1565b6001811115611aa8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9f906136cf565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415611af057611aeb81611ff7565b611b2f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611b2e57611b2d8582612040565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611b7257611b6d816121ad565b611bb1565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611bb057611baf848261227e565b5b5b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606060006001611bea846122fd565b01905060008167ffffffffffffffff811115611c0957611c086128c8565b5b6040519080825280601f01601f191660200182016040528015611c3b5781602001600182028036833780820191505090505b509050600082602001820190505b600115611ca8578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611c9257611c916136ef565b5b0494506000851415611ca357611ca8565b611c49565b819350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1a9061376a565b60405180910390fd5b611d2c81611724565b15611d6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d63906137d6565b60405180910390fd5b611d7a600083836001611765565b611d8381611724565b15611dc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dba906137d6565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611ecd600083836001611777565b5050565b6001811115611ff157600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611f655780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f5d91906137f6565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611ff05780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611fe8919061305d565b925050819055505b5b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161204d84610823565b61205791906137f6565b905060006007600084815260200190815260200160002054905081811461213c576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016008805490506121c191906137f6565b90506000600960008481526020019081526020016000205490506000600883815481106121f1576121f0612f01565b5b90600052602060002001549050806008838154811061221357612212612f01565b5b9060005260206000200181905550816009600083815260200190815260200160002081905550600960008581526020019081526020016000206000905560088054806122625761226161382a565b5b6001900381819060005260206000200160009055905550505050565b600061228983610823565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061235b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612351576123506136ef565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612398576d04ee2d6d415b85acef8100000000838161238e5761238d6136ef565b5b0492506020810190505b662386f26fc1000083106123c757662386f26fc1000083816123bd576123bc6136ef565b5b0492506010810190505b6305f5e10083106123f0576305f5e10083816123e6576123e56136ef565b5b0492506008810190505b612710831061241557612710838161240b5761240a6136ef565b5b0492506004810190505b60648310612438576064838161242e5761242d6136ef565b5b0492506002810190505b600a8310612447576001810190505b80915050919050565b82805461245c90612bf5565b90600052602060002090601f01602090048101928261247e57600085556124c5565b82601f1061249757805160ff19168380011785556124c5565b828001600101855582156124c5579182015b828111156124c45782518255916020019190600101906124a9565b5b5090506124d291906124d6565b5090565b5b808211156124ef5760008160009055506001016124d7565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61253c81612507565b811461254757600080fd5b50565b60008135905061255981612533565b92915050565b600060208284031215612575576125746124fd565b5b60006125838482850161254a565b91505092915050565b60008115159050919050565b6125a18161258c565b82525050565b60006020820190506125bc6000830184612598565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156125fc5780820151818401526020810190506125e1565b8381111561260b576000848401525b50505050565b6000601f19601f8301169050919050565b600061262d826125c2565b61263781856125cd565b93506126478185602086016125de565b61265081612611565b840191505092915050565b600060208201905081810360008301526126758184612622565b905092915050565b6000819050919050565b6126908161267d565b811461269b57600080fd5b50565b6000813590506126ad81612687565b92915050565b6000602082840312156126c9576126c86124fd565b5b60006126d78482850161269e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061270b826126e0565b9050919050565b61271b81612700565b82525050565b60006020820190506127366000830184612712565b92915050565b61274581612700565b811461275057600080fd5b50565b6000813590506127628161273c565b92915050565b6000806040838503121561277f5761277e6124fd565b5b600061278d85828601612753565b925050602061279e8582860161269e565b9150509250929050565b6127b18161267d565b82525050565b60006020820190506127cc60008301846127a8565b92915050565b6000806000606084860312156127eb576127ea6124fd565b5b60006127f986828701612753565b935050602061280a86828701612753565b925050604061281b8682870161269e565b9150509250925092565b60006020828403121561283b5761283a6124fd565b5b600061284984828501612753565b91505092915050565b61285b8161258c565b811461286657600080fd5b50565b60008135905061287881612852565b92915050565b60008060408385031215612895576128946124fd565b5b60006128a385828601612753565b92505060206128b485828601612869565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61290082612611565b810181811067ffffffffffffffff8211171561291f5761291e6128c8565b5b80604052505050565b60006129326124f3565b905061293e82826128f7565b919050565b600067ffffffffffffffff82111561295e5761295d6128c8565b5b61296782612611565b9050602081019050919050565b82818337600083830152505050565b600061299661299184612943565b612928565b9050828152602081018484840111156129b2576129b16128c3565b5b6129bd848285612974565b509392505050565b600082601f8301126129da576129d96128be565b5b81356129ea848260208601612983565b91505092915050565b60008060008060808587031215612a0d57612a0c6124fd565b5b6000612a1b87828801612753565b9450506020612a2c87828801612753565b9350506040612a3d8782880161269e565b925050606085013567ffffffffffffffff811115612a5e57612a5d612502565b5b612a6a878288016129c5565b91505092959194509250565b600067ffffffffffffffff821115612a9157612a906128c8565b5b612a9a82612611565b9050602081019050919050565b6000612aba612ab584612a76565b612928565b905082815260208101848484011115612ad657612ad56128c3565b5b612ae1848285612974565b509392505050565b600082601f830112612afe57612afd6128be565b5b8135612b0e848260208601612aa7565b91505092915050565b600080600060608486031215612b3057612b2f6124fd565b5b6000612b3e86828701612753565b9350506020612b4f8682870161269e565b925050604084013567ffffffffffffffff811115612b7057612b6f612502565b5b612b7c86828701612ae9565b9150509250925092565b60008060408385031215612b9d57612b9c6124fd565b5b6000612bab85828601612753565b9250506020612bbc85828601612753565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612c0d57607f821691505b60208210811415612c2157612c20612bc6565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000612c836021836125cd565b9150612c8e82612c27565b604082019050919050565b60006020820190508181036000830152612cb281612c76565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612d15603d836125cd565b9150612d2082612cb9565b604082019050919050565b60006020820190508181036000830152612d4481612d08565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000612da7602d836125cd565b9150612db282612d4b565b604082019050919050565b60006020820190508181036000830152612dd681612d9a565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000612e39602b836125cd565b9150612e4482612ddd565b604082019050919050565b60006020820190508181036000830152612e6881612e2c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000612ecb602c836125cd565b9150612ed682612e6f565b604082019050919050565b60006020820190508181036000830152612efa81612ebe565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000612f666018836125cd565b9150612f7182612f30565b602082019050919050565b60006020820190508181036000830152612f9581612f59565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612ff86029836125cd565b915061300382612f9c565b604082019050919050565b6000602082019050818103600083015261302781612feb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006130688261267d565b91506130738361267d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156130a8576130a761302e565b5b828201905092915050565b7f457863656564656420746f74616c20737570706c790000000000000000000000600082015250565b60006130e96015836125cd565b91506130f4826130b3565b602082019050919050565b60006020820190508181036000830152613118816130dc565b9050919050565b600061312a8261267d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561315d5761315c61302e565b5b600182019050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006131c46026836125cd565b91506131cf82613168565b604082019050919050565b600060208201905081810360008301526131f3816131b7565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006132566025836125cd565b9150613261826131fa565b604082019050919050565b6000602082019050818103600083015261328581613249565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006132e86024836125cd565b91506132f38261328c565b604082019050919050565b60006020820190508181036000830152613317816132db565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006133546020836125cd565b915061335f8261331e565b602082019050919050565b6000602082019050818103600083015261338381613347565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b60006133c06019836125cd565b91506133cb8261338a565b602082019050919050565b600060208201905081810360008301526133ef816133b3565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006134526032836125cd565b915061345d826133f6565b604082019050919050565b6000602082019050818103600083015261348181613445565b9050919050565b600081905092915050565b600061349e826125c2565b6134a88185613488565b93506134b88185602086016125de565b80840191505092915050565b60006134d08285613493565b91506134dc8284613493565b91508190509392505050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000613544602e836125cd565b915061354f826134e8565b604082019050919050565b6000602082019050818103600083015261357381613537565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006135a18261357a565b6135ab8185613585565b93506135bb8185602086016125de565b6135c481612611565b840191505092915050565b60006080820190506135e46000830187612712565b6135f16020830186612712565b6135fe60408301856127a8565b81810360608301526136108184613596565b905095945050505050565b60008151905061362a81612533565b92915050565b600060208284031215613646576136456124fd565b5b60006136548482850161361b565b91505092915050565b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b60006136b96035836125cd565b91506136c48261365d565b604082019050919050565b600060208201905081810360008301526136e8816136ac565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006137546020836125cd565b915061375f8261371e565b602082019050919050565b6000602082019050818103600083015261378381613747565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006137c0601c836125cd565b91506137cb8261378a565b602082019050919050565b600060208201905081810360008301526137ef816137b3565b9050919050565b60006138018261267d565b915061380c8361267d565b92508282101561381f5761381e61302e565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220784b14ad0a25d1807ec643b31a6671c3bdb9054ecbfb023ecfe7784a19aa3d3a64736f6c63430008090033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061012c5760003560e01c806370a08231116100ad578063b88d4fde11610071578063b88d4fde14610343578063c87b56dd1461035f578063cd279c7c1461038f578063e985e9c5146103ab578063f2fde38b146103db5761012c565b806370a08231146102b1578063715018a6146102e15780638da5cb5b146102eb57806395d89b4114610309578063a22cb465146103275761012c565b806323b872dd116100f457806323b872dd146101e95780632f745c591461020557806342842e0e146102355780634f6ccce7146102515780636352211e146102815761012c565b806301ffc9a71461013157806306fdde0314610161578063081812fc1461017f578063095ea7b3146101af57806318160ddd146101cb575b600080fd5b61014b6004803603810190610146919061255f565b6103f7565b60405161015891906125a7565b60405180910390f35b610169610409565b604051610176919061265b565b60405180910390f35b610199600480360381019061019491906126b3565b61049b565b6040516101a69190612721565b60405180910390f35b6101c960048036038101906101c49190612768565b6104e1565b005b6101d36105f9565b6040516101e091906127b7565b60405180910390f35b61020360048036038101906101fe91906127d2565b610606565b005b61021f600480360381019061021a9190612768565b610666565b60405161022c91906127b7565b60405180910390f35b61024f600480360381019061024a91906127d2565b61070b565b005b61026b600480360381019061026691906126b3565b61072b565b60405161027891906127b7565b60405180910390f35b61029b600480360381019061029691906126b3565b61079c565b6040516102a89190612721565b60405180910390f35b6102cb60048036038101906102c69190612825565b610823565b6040516102d891906127b7565b60405180910390f35b6102e96108db565b005b6102f36108ef565b6040516103009190612721565b60405180910390f35b610311610919565b60405161031e919061265b565b60405180910390f35b610341600480360381019061033c919061287e565b6109ab565b005b61035d600480360381019061035891906129f3565b6109c1565b005b610379600480360381019061037491906126b3565b610a23565b604051610386919061265b565b60405180910390f35b6103a960048036038101906103a49190612b17565b610a35565b005b6103c560048036038101906103c09190612b86565b610b02565b6040516103d291906125a7565b60405180910390f35b6103f560048036038101906103f09190612825565b610b96565b005b600061040282610c1a565b9050919050565b60606000805461041890612bf5565b80601f016020809104026020016040519081016040528092919081815260200182805461044490612bf5565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b5050505050905090565b60006104a682610c94565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006104ec8261079c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561055d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161055490612c99565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661057c610cdf565b73ffffffffffffffffffffffffffffffffffffffff1614806105ab57506105aa816105a5610cdf565b610b02565b5b6105ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e190612d2b565b60405180910390fd5b6105f48383610ce7565b505050565b6000600880549050905090565b610617610611610cdf565b82610da0565b610656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064d90612dbd565b60405180910390fd5b610661838383610e35565b505050565b600061067183610823565b82106106b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a990612e4f565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610726838383604051806020016040528060008152506109c1565b505050565b60006107356105f9565b8210610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076d90612ee1565b60405180910390fd5b6008828154811061078a57610789612f01565b5b90600052602060002001549050919050565b6000806107a88361112f565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561081a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081190612f7c565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610894576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088b9061300e565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6108e361116c565b6108ed60006111ea565b565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461092890612bf5565b80601f016020809104026020016040519081016040528092919081815260200182805461095490612bf5565b80156109a15780601f10610976576101008083540402835291602001916109a1565b820191906000526020600020905b81548152906001019060200180831161098457829003601f168201915b5050505050905090565b6109bd6109b6610cdf565b83836112b0565b5050565b6109d26109cc610cdf565b83610da0565b610a11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0890612dbd565b60405180910390fd5b610a1d8484848461141d565b50505050565b6060610a2e82611479565b9050919050565b610a3d61116c565b6000610a476105f9565b90506000610a55600c61158c565b9050610a61600c61159a565b620186a08483610a71919061305d565b1115610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa9906130ff565b60405180910390fd5b60005b84811015610afa57610ad2868285610acd919061305d565b6115b0565b610ae78184610ae1919061305d565b856115ce565b8080610af29061311f565b915050610ab5565b505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610b9e61116c565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610c0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c05906131da565b60405180910390fd5b610c17816111ea565b50565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c8d5750610c8c82611642565b5b9050919050565b610c9d81611724565b610cdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd390612f7c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610d5a8361079c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610dac8361079c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610dee5750610ded8185610b02565b5b80610e2c57508373ffffffffffffffffffffffffffffffffffffffff16610e148461049b565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610e558261079c565b73ffffffffffffffffffffffffffffffffffffffff1614610eab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea29061326c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f12906132fe565b60405180910390fd5b610f288383836001611765565b8273ffffffffffffffffffffffffffffffffffffffff16610f488261079c565b73ffffffffffffffffffffffffffffffffffffffff1614610f9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f959061326c565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461112a8383836001611777565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b611174610cdf565b73ffffffffffffffffffffffffffffffffffffffff166111926108ef565b73ffffffffffffffffffffffffffffffffffffffff16146111e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111df9061336a565b60405180910390fd5b565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561131f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611316906133d6565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161141091906125a7565b60405180910390a3505050565b611428848484610e35565b6114348484848461177d565b611473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146a90613468565b60405180910390fd5b50505050565b606061148482610c94565b6000600a600084815260200190815260200160002080546114a490612bf5565b80601f01602080910402602001604051908101604052809291908181526020018280546114d090612bf5565b801561151d5780601f106114f25761010080835404028352916020019161151d565b820191906000526020600020905b81548152906001019060200180831161150057829003601f168201915b50505050509050600061152e611914565b9050600081511415611544578192505050611587565b6000825111156115795780826040516020016115619291906134c4565b60405160208183030381529060405292505050611587565b6115828461192b565b925050505b919050565b600081600001549050919050565b6001816000016000828254019250508190555050565b6115ca828260405180602001604052806000815250611993565b5050565b6115d782611724565b611616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160d9061355a565b60405180910390fd5b80600a6000848152602001908152602001600020908051906020019061163d929190612450565b505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061170d57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061171d575061171c826119ee565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166117468361112f565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b61177184848484611a58565b50505050565b50505050565b600061179e8473ffffffffffffffffffffffffffffffffffffffff16611bb8565b15611907578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026117c7610cdf565b8786866040518563ffffffff1660e01b81526004016117e994939291906135cf565b602060405180830381600087803b15801561180357600080fd5b505af192505050801561183457506040513d601f19601f820116820180604052508101906118319190613630565b60015b6118b7573d8060008114611864576040519150601f19603f3d011682016040523d82523d6000602084013e611869565b606091505b506000815114156118af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118a690613468565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061190c565b600190505b949350505050565b606060405180602001604052806000815250905090565b606061193682610c94565b6000611940611914565b90506000815111611960576040518060200160405280600081525061198b565b8061196a84611bdb565b60405160200161197b9291906134c4565b6040516020818303038152906040525b915050919050565b61199d8383611cb3565b6119aa600084848461177d565b6119e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e090613468565b60405180910390fd5b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611a6484848484611ed1565b6001811115611aa8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9f906136cf565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415611af057611aeb81611ff7565b611b2f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611b2e57611b2d8582612040565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611b7257611b6d816121ad565b611bb1565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611bb057611baf848261227e565b5b5b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606060006001611bea846122fd565b01905060008167ffffffffffffffff811115611c0957611c086128c8565b5b6040519080825280601f01601f191660200182016040528015611c3b5781602001600182028036833780820191505090505b509050600082602001820190505b600115611ca8578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611c9257611c916136ef565b5b0494506000851415611ca357611ca8565b611c49565b819350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1a9061376a565b60405180910390fd5b611d2c81611724565b15611d6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d63906137d6565b60405180910390fd5b611d7a600083836001611765565b611d8381611724565b15611dc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dba906137d6565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611ecd600083836001611777565b5050565b6001811115611ff157600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611f655780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f5d91906137f6565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611ff05780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611fe8919061305d565b925050819055505b5b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161204d84610823565b61205791906137f6565b905060006007600084815260200190815260200160002054905081811461213c576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016008805490506121c191906137f6565b90506000600960008481526020019081526020016000205490506000600883815481106121f1576121f0612f01565b5b90600052602060002001549050806008838154811061221357612212612f01565b5b9060005260206000200181905550816009600083815260200190815260200160002081905550600960008581526020019081526020016000206000905560088054806122625761226161382a565b5b6001900381819060005260206000200160009055905550505050565b600061228983610823565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061235b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612351576123506136ef565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612398576d04ee2d6d415b85acef8100000000838161238e5761238d6136ef565b5b0492506020810190505b662386f26fc1000083106123c757662386f26fc1000083816123bd576123bc6136ef565b5b0492506010810190505b6305f5e10083106123f0576305f5e10083816123e6576123e56136ef565b5b0492506008810190505b612710831061241557612710838161240b5761240a6136ef565b5b0492506004810190505b60648310612438576064838161242e5761242d6136ef565b5b0492506002810190505b600a8310612447576001810190505b80915050919050565b82805461245c90612bf5565b90600052602060002090601f01602090048101928261247e57600085556124c5565b82601f1061249757805160ff19168380011785556124c5565b828001600101855582156124c5579182015b828111156124c45782518255916020019190600101906124a9565b5b5090506124d291906124d6565b5090565b5b808211156124ef5760008160009055506001016124d7565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61253c81612507565b811461254757600080fd5b50565b60008135905061255981612533565b92915050565b600060208284031215612575576125746124fd565b5b60006125838482850161254a565b91505092915050565b60008115159050919050565b6125a18161258c565b82525050565b60006020820190506125bc6000830184612598565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156125fc5780820151818401526020810190506125e1565b8381111561260b576000848401525b50505050565b6000601f19601f8301169050919050565b600061262d826125c2565b61263781856125cd565b93506126478185602086016125de565b61265081612611565b840191505092915050565b600060208201905081810360008301526126758184612622565b905092915050565b6000819050919050565b6126908161267d565b811461269b57600080fd5b50565b6000813590506126ad81612687565b92915050565b6000602082840312156126c9576126c86124fd565b5b60006126d78482850161269e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061270b826126e0565b9050919050565b61271b81612700565b82525050565b60006020820190506127366000830184612712565b92915050565b61274581612700565b811461275057600080fd5b50565b6000813590506127628161273c565b92915050565b6000806040838503121561277f5761277e6124fd565b5b600061278d85828601612753565b925050602061279e8582860161269e565b9150509250929050565b6127b18161267d565b82525050565b60006020820190506127cc60008301846127a8565b92915050565b6000806000606084860312156127eb576127ea6124fd565b5b60006127f986828701612753565b935050602061280a86828701612753565b925050604061281b8682870161269e565b9150509250925092565b60006020828403121561283b5761283a6124fd565b5b600061284984828501612753565b91505092915050565b61285b8161258c565b811461286657600080fd5b50565b60008135905061287881612852565b92915050565b60008060408385031215612895576128946124fd565b5b60006128a385828601612753565b92505060206128b485828601612869565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61290082612611565b810181811067ffffffffffffffff8211171561291f5761291e6128c8565b5b80604052505050565b60006129326124f3565b905061293e82826128f7565b919050565b600067ffffffffffffffff82111561295e5761295d6128c8565b5b61296782612611565b9050602081019050919050565b82818337600083830152505050565b600061299661299184612943565b612928565b9050828152602081018484840111156129b2576129b16128c3565b5b6129bd848285612974565b509392505050565b600082601f8301126129da576129d96128be565b5b81356129ea848260208601612983565b91505092915050565b60008060008060808587031215612a0d57612a0c6124fd565b5b6000612a1b87828801612753565b9450506020612a2c87828801612753565b9350506040612a3d8782880161269e565b925050606085013567ffffffffffffffff811115612a5e57612a5d612502565b5b612a6a878288016129c5565b91505092959194509250565b600067ffffffffffffffff821115612a9157612a906128c8565b5b612a9a82612611565b9050602081019050919050565b6000612aba612ab584612a76565b612928565b905082815260208101848484011115612ad657612ad56128c3565b5b612ae1848285612974565b509392505050565b600082601f830112612afe57612afd6128be565b5b8135612b0e848260208601612aa7565b91505092915050565b600080600060608486031215612b3057612b2f6124fd565b5b6000612b3e86828701612753565b9350506020612b4f8682870161269e565b925050604084013567ffffffffffffffff811115612b7057612b6f612502565b5b612b7c86828701612ae9565b9150509250925092565b60008060408385031215612b9d57612b9c6124fd565b5b6000612bab85828601612753565b9250506020612bbc85828601612753565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612c0d57607f821691505b60208210811415612c2157612c20612bc6565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000612c836021836125cd565b9150612c8e82612c27565b604082019050919050565b60006020820190508181036000830152612cb281612c76565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612d15603d836125cd565b9150612d2082612cb9565b604082019050919050565b60006020820190508181036000830152612d4481612d08565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000612da7602d836125cd565b9150612db282612d4b565b604082019050919050565b60006020820190508181036000830152612dd681612d9a565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000612e39602b836125cd565b9150612e4482612ddd565b604082019050919050565b60006020820190508181036000830152612e6881612e2c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000612ecb602c836125cd565b9150612ed682612e6f565b604082019050919050565b60006020820190508181036000830152612efa81612ebe565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000612f666018836125cd565b9150612f7182612f30565b602082019050919050565b60006020820190508181036000830152612f9581612f59565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612ff86029836125cd565b915061300382612f9c565b604082019050919050565b6000602082019050818103600083015261302781612feb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006130688261267d565b91506130738361267d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156130a8576130a761302e565b5b828201905092915050565b7f457863656564656420746f74616c20737570706c790000000000000000000000600082015250565b60006130e96015836125cd565b91506130f4826130b3565b602082019050919050565b60006020820190508181036000830152613118816130dc565b9050919050565b600061312a8261267d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561315d5761315c61302e565b5b600182019050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006131c46026836125cd565b91506131cf82613168565b604082019050919050565b600060208201905081810360008301526131f3816131b7565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006132566025836125cd565b9150613261826131fa565b604082019050919050565b6000602082019050818103600083015261328581613249565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006132e86024836125cd565b91506132f38261328c565b604082019050919050565b60006020820190508181036000830152613317816132db565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006133546020836125cd565b915061335f8261331e565b602082019050919050565b6000602082019050818103600083015261338381613347565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b60006133c06019836125cd565b91506133cb8261338a565b602082019050919050565b600060208201905081810360008301526133ef816133b3565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006134526032836125cd565b915061345d826133f6565b604082019050919050565b6000602082019050818103600083015261348181613445565b9050919050565b600081905092915050565b600061349e826125c2565b6134a88185613488565b93506134b88185602086016125de565b80840191505092915050565b60006134d08285613493565b91506134dc8284613493565b91508190509392505050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000613544602e836125cd565b915061354f826134e8565b604082019050919050565b6000602082019050818103600083015261357381613537565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006135a18261357a565b6135ab8185613585565b93506135bb8185602086016125de565b6135c481612611565b840191505092915050565b60006080820190506135e46000830187612712565b6135f16020830186612712565b6135fe60408301856127a8565b81810360608301526136108184613596565b905095945050505050565b60008151905061362a81612533565b92915050565b600060208284031215613646576136456124fd565b5b60006136548482850161361b565b91505092915050565b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b60006136b96035836125cd565b91506136c48261365d565b604082019050919050565b600060208201905081810360008301526136e8816136ac565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006137546020836125cd565b915061375f8261371e565b602082019050919050565b6000602082019050818103600083015261378381613747565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006137c0601c836125cd565b91506137cb8261378a565b602082019050919050565b600060208201905081810360008301526137ef816137b3565b9050919050565b60006138018261267d565b915061380c8361267d565b92508282101561381f5761381e61302e565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220784b14ad0a25d1807ec643b31a6671c3bdb9054ecbfb023ecfe7784a19aa3d3a64736f6c63430008090033

Deployed Bytecode Sourcemap

65866:1510:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67161:212;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41967:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43479:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42997:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60506:113;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44179:335;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60174:256;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44585:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60696:233;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41677:223;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41408:207;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19390:103;;;:::i;:::-;;18742:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42136:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43722:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44841:322;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66957:196;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66099:415;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43948:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19648:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67161:212;67300:4;67329:36;67353:11;67329:23;:36::i;:::-;67322:43;;67161:212;;;:::o;41967:100::-;42021:13;42054:5;42047:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41967:100;:::o;43479:171::-;43555:7;43575:23;43590:7;43575:14;:23::i;:::-;43618:15;:24;43634:7;43618:24;;;;;;;;;;;;;;;;;;;;;43611:31;;43479:171;;;:::o;42997:416::-;43078:13;43094:23;43109:7;43094:14;:23::i;:::-;43078:39;;43142:5;43136:11;;:2;:11;;;;43128:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;43236:5;43220:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;43245:37;43262:5;43269:12;:10;:12::i;:::-;43245:16;:37::i;:::-;43220:62;43198:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;43384:21;43393:2;43397:7;43384:8;:21::i;:::-;43067:346;42997:416;;:::o;60506:113::-;60567:7;60594:10;:17;;;;60587:24;;60506:113;:::o;44179:335::-;44374:41;44393:12;:10;:12::i;:::-;44407:7;44374:18;:41::i;:::-;44366:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;44478:28;44488:4;44494:2;44498:7;44478:9;:28::i;:::-;44179:335;;;:::o;60174:256::-;60271:7;60307:23;60324:5;60307:16;:23::i;:::-;60299:5;:31;60291:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;60396:12;:19;60409:5;60396:19;;;;;;;;;;;;;;;:26;60416:5;60396:26;;;;;;;;;;;;60389:33;;60174:256;;;;:::o;44585:185::-;44723:39;44740:4;44746:2;44750:7;44723:39;;;;;;;;;;;;:16;:39::i;:::-;44585:185;;;:::o;60696:233::-;60771:7;60807:30;:28;:30::i;:::-;60799:5;:38;60791:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;60904:10;60915:5;60904:17;;;;;;;;:::i;:::-;;;;;;;;;;60897:24;;60696:233;;;:::o;41677:223::-;41749:7;41769:13;41785:17;41794:7;41785:8;:17::i;:::-;41769:33;;41838:1;41821:19;;:5;:19;;;;41813:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;41887:5;41880:12;;;41677:223;;;:::o;41408:207::-;41480:7;41525:1;41508:19;;:5;:19;;;;41500:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;41591:9;:16;41601:5;41591:16;;;;;;;;;;;;;;;;41584:23;;41408:207;;;:::o;19390:103::-;18628:13;:11;:13::i;:::-;19455:30:::1;19482:1;19455:18;:30::i;:::-;19390:103::o:0;18742:87::-;18788:7;18815:6;;;;;;;;;;;18808:13;;18742:87;:::o;42136:104::-;42192:13;42225:7;42218:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42136:104;:::o;43722:155::-;43817:52;43836:12;:10;:12::i;:::-;43850:8;43860;43817:18;:52::i;:::-;43722:155;;:::o;44841:322::-;45015:41;45034:12;:10;:12::i;:::-;45048:7;45015:18;:41::i;:::-;45007:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;45117:38;45131:4;45137:2;45141:7;45150:4;45117:13;:38::i;:::-;44841:322;;;;:::o;66957:196::-;67084:13;67122:23;67137:7;67122:14;:23::i;:::-;67115:30;;66957:196;;;:::o;66099:415::-;18628:13;:11;:13::i;:::-;66189:14:::1;66206:13;:11;:13::i;:::-;66189:30;;66230:15;66248:25;:15;:23;:25::i;:::-;66230:43;;66284:27;:15;:25;:27::i;:::-;66346:6;66339:3;66330:6;:12;;;;:::i;:::-;:22;;66322:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;66394:9;66389:118;66409:3;66405:1;:7;66389:118;;;66430:25;66440:2;66453:1;66444:6;:10;;;;:::i;:::-;66430:9;:25::i;:::-;66466:29;66488:1;66479:6;:10;;;;:::i;:::-;66491:3;66466:12;:29::i;:::-;66414:3;;;;;:::i;:::-;;;;66389:118;;;;66178:336;;66099:415:::0;;;:::o;43948:164::-;44045:4;44069:18;:25;44088:5;44069:25;;;;;;;;;;;;;;;:35;44095:8;44069:35;;;;;;;;;;;;;;;;;;;;;;;;;44062:42;;43948:164;;;;:::o;19648:201::-;18628:13;:11;:13::i;:::-;19757:1:::1;19737:22;;:8;:22;;;;19729:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;19813:28;19832:8;19813:18;:28::i;:::-;19648:201:::0;:::o;59866:224::-;59968:4;60007:35;59992:50;;;:11;:50;;;;:90;;;;60046:36;60070:11;60046:23;:36::i;:::-;59992:90;59985:97;;59866:224;;;:::o;53298:135::-;53380:16;53388:7;53380;:16::i;:::-;53372:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;53298:135;:::o;17293:98::-;17346:7;17373:10;17366:17;;17293:98;:::o;52577:174::-;52679:2;52652:15;:24;52668:7;52652:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;52735:7;52731:2;52697:46;;52706:23;52721:7;52706:14;:23::i;:::-;52697:46;;;;;;;;;;;;52577:174;;:::o;47196:264::-;47289:4;47306:13;47322:23;47337:7;47322:14;:23::i;:::-;47306:39;;47375:5;47364:16;;:7;:16;;;:52;;;;47384:32;47401:5;47408:7;47384:16;:32::i;:::-;47364:52;:87;;;;47444:7;47420:31;;:20;47432:7;47420:11;:20::i;:::-;:31;;;47364:87;47356:96;;;47196:264;;;;:::o;51195:1263::-;51354:4;51327:31;;:23;51342:7;51327:14;:23::i;:::-;:31;;;51319:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;51433:1;51419:16;;:2;:16;;;;51411:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;51489:42;51510:4;51516:2;51520:7;51529:1;51489:20;:42::i;:::-;51661:4;51634:31;;:23;51649:7;51634:14;:23::i;:::-;:31;;;51626:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;51779:15;:24;51795:7;51779:24;;;;;;;;;;;;51772:31;;;;;;;;;;;52274:1;52255:9;:15;52265:4;52255:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;52307:1;52290:9;:13;52300:2;52290:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;52349:2;52330:7;:16;52338:7;52330:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;52388:7;52384:2;52369:27;;52378:4;52369:27;;;;;;;;;;;;52409:41;52429:4;52435:2;52439:7;52448:1;52409:19;:41::i;:::-;51195:1263;;;:::o;46471:117::-;46537:7;46564;:16;46572:7;46564:16;;;;;;;;;;;;;;;;;;;;;46557:23;;46471:117;;;:::o;18907:132::-;18982:12;:10;:12::i;:::-;18971:23;;:7;:5;:7::i;:::-;:23;;;18963:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;18907:132::o;20009:191::-;20083:16;20102:6;;;;;;;;;;;20083:25;;20128:8;20119:6;;:17;;;;;;;;;;;;;;;;;;20183:8;20152:40;;20173:8;20152:40;;;;;;;;;;;;20072:128;20009:191;:::o;52894:315::-;53049:8;53040:17;;:5;:17;;;;53032:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;53136:8;53098:18;:25;53117:5;53098:25;;;;;;;;;;;;;;;:35;53124:8;53098:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;53182:8;53160:41;;53175:5;53160:41;;;53192:8;53160:41;;;;;;:::i;:::-;;;;;;;;52894:315;;;:::o;46044:313::-;46200:28;46210:4;46216:2;46220:7;46200:9;:28::i;:::-;46247:47;46270:4;46276:2;46280:7;46289:4;46247:22;:47::i;:::-;46239:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;46044:313;;;;:::o;57405:624::-;57478:13;57504:23;57519:7;57504:14;:23::i;:::-;57540;57566:10;:19;57577:7;57566:19;;;;;;;;;;;57540:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57596:18;57617:10;:8;:10::i;:::-;57596:31;;57725:1;57709:4;57703:18;:23;57699:72;;;57750:9;57743:16;;;;;;57699:72;57901:1;57881:9;57875:23;:27;57871:108;;;57950:4;57956:9;57933:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57919:48;;;;;;57871:108;57998:23;58013:7;57998:14;:23::i;:::-;57991:30;;;;57405:624;;;;:::o;872:114::-;937:7;964;:14;;;957:21;;872:114;;;:::o;994:127::-;1101:1;1083:7;:14;;;:19;;;;;;;;;;;994:127;:::o;47802:110::-;47878:26;47888:2;47892:7;47878:26;;;;;;;;;;;;:9;:26::i;:::-;47802:110;;:::o;58185:217::-;58285:16;58293:7;58285;:16::i;:::-;58277:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;58385:9;58363:10;:19;58374:7;58363:19;;;;;;;;;;;:31;;;;;;;;;;;;:::i;:::-;;58185:217;;:::o;41039:305::-;41141:4;41193:25;41178:40;;;:11;:40;;;;:105;;;;41250:33;41235:48;;;:11;:48;;;;41178:105;:158;;;;41300:36;41324:11;41300:23;:36::i;:::-;41178:158;41158:178;;41039:305;;;:::o;46901:128::-;46966:4;47019:1;46990:31;;:17;46999:7;46990:8;:17::i;:::-;:31;;;;46983:38;;46901:128;;;:::o;66592:234::-;66762:56;66789:4;66795:2;66799:7;66808:9;66762:26;:56::i;:::-;66592:234;;;;:::o;56714:158::-;;;;;:::o;53997:853::-;54151:4;54172:15;:2;:13;;;:15::i;:::-;54168:675;;;54224:2;54208:36;;;54245:12;:10;:12::i;:::-;54259:4;54265:7;54274:4;54208:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;54204:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54466:1;54449:6;:13;:18;54445:328;;;54492:60;;;;;;;;;;:::i;:::-;;;;;;;;54445:328;54723:6;54717:13;54708:6;54704:2;54700:15;54693:38;54204:584;54340:41;;;54330:51;;;:6;:51;;;;54323:58;;;;;54168:675;54827:4;54820:11;;53997:853;;;;;;;:::o;42841:94::-;42892:13;42918:9;;;;;;;;;;;;;;42841:94;:::o;42311:281::-;42384:13;42410:23;42425:7;42410:14;:23::i;:::-;42446:21;42470:10;:8;:10::i;:::-;42446:34;;42522:1;42504:7;42498:21;:25;:86;;;;;;;;;;;;;;;;;42550:7;42559:18;:7;:16;:18::i;:::-;42533:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;42498:86;42491:93;;;42311:281;;;:::o;48139:319::-;48268:18;48274:2;48278:7;48268:5;:18::i;:::-;48319:53;48350:1;48354:2;48358:7;48367:4;48319:22;:53::i;:::-;48297:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;48139:319;;;:::o;32471:157::-;32556:4;32595:25;32580:40;;;:11;:40;;;;32573:47;;32471:157;;;:::o;61003:915::-;61180:61;61207:4;61213:2;61217:12;61231:9;61180:26;:61::i;:::-;61270:1;61258:9;:13;61254:222;;;61401:63;;;;;;;;;;:::i;:::-;;;;;;;;61254:222;61488:15;61506:12;61488:30;;61551:1;61535:18;;:4;:18;;;61531:187;;;61570:40;61602:7;61570:31;:40::i;:::-;61531:187;;;61640:2;61632:10;;:4;:10;;;61628:90;;61659:47;61692:4;61698:7;61659:32;:47::i;:::-;61628:90;61531:187;61746:1;61732:16;;:2;:16;;;61728:183;;;61765:45;61802:7;61765:36;:45::i;:::-;61728:183;;;61838:4;61832:10;;:2;:10;;;61828:83;;61859:40;61887:2;61891:7;61859:27;:40::i;:::-;61828:83;61728:183;61169:749;61003:915;;;;:::o;21440:326::-;21500:4;21757:1;21735:7;:19;;;:23;21728:30;;21440:326;;;:::o;14720:716::-;14776:13;14827:14;14864:1;14844:17;14855:5;14844:10;:17::i;:::-;:21;14827:38;;14880:20;14914:6;14903:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14880:41;;14936:11;15065:6;15061:2;15057:15;15049:6;15045:28;15038:35;;15102:288;15109:4;15102:288;;;15134:5;;;;;;;;15276:8;15271:2;15264:5;15260:14;15255:30;15250:3;15242:44;15332:2;15323:11;;;;;;:::i;:::-;;;;;15366:1;15357:5;:10;15353:21;;;15369:5;;15353:21;15102:288;;;15411:6;15404:13;;;;;14720:716;;;:::o;48794:942::-;48888:1;48874:16;;:2;:16;;;;48866:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;48947:16;48955:7;48947;:16::i;:::-;48946:17;48938:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;49009:48;49038:1;49042:2;49046:7;49055:1;49009:20;:48::i;:::-;49156:16;49164:7;49156;:16::i;:::-;49155:17;49147:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;49571:1;49554:9;:13;49564:2;49554:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;49615:2;49596:7;:16;49604:7;49596:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;49660:7;49656:2;49635:33;;49652:1;49635:33;;;;;;;;;;;;49681:47;49709:1;49713:2;49717:7;49726:1;49681:19;:47::i;:::-;48794:942;;:::o;55582:410::-;55772:1;55760:9;:13;55756:229;;;55810:1;55794:18;;:4;:18;;;55790:87;;55852:9;55833;:15;55843:4;55833:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;55790:87;55909:1;55895:16;;:2;:16;;;55891:83;;55949:9;55932;:13;55942:2;55932:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;55891:83;55756:229;55582:410;;;;:::o;62641:164::-;62745:10;:17;;;;62718:15;:24;62734:7;62718:24;;;;;;;;;;;:44;;;;62773:10;62789:7;62773:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62641:164;:::o;63432:988::-;63698:22;63748:1;63723:22;63740:4;63723:16;:22::i;:::-;:26;;;;:::i;:::-;63698:51;;63760:18;63781:17;:26;63799:7;63781:26;;;;;;;;;;;;63760:47;;63928:14;63914:10;:28;63910:328;;63959:19;63981:12;:18;63994:4;63981:18;;;;;;;;;;;;;;;:34;64000:14;63981:34;;;;;;;;;;;;63959:56;;64065:11;64032:12;:18;64045:4;64032:18;;;;;;;;;;;;;;;:30;64051:10;64032:30;;;;;;;;;;;:44;;;;64182:10;64149:17;:30;64167:11;64149:30;;;;;;;;;;;:43;;;;63944:294;63910:328;64334:17;:26;64352:7;64334:26;;;;;;;;;;;64327:33;;;64378:12;:18;64391:4;64378:18;;;;;;;;;;;;;;;:34;64397:14;64378:34;;;;;;;;;;;64371:41;;;63513:907;;63432:988;;:::o;64715:1079::-;64968:22;65013:1;64993:10;:17;;;;:21;;;;:::i;:::-;64968:46;;65025:18;65046:15;:24;65062:7;65046:24;;;;;;;;;;;;65025:45;;65397:19;65419:10;65430:14;65419:26;;;;;;;;:::i;:::-;;;;;;;;;;65397:48;;65483:11;65458:10;65469;65458:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;65594:10;65563:15;:28;65579:11;65563:28;;;;;;;;;;;:41;;;;65735:15;:24;65751:7;65735:24;;;;;;;;;;;65728:31;;;65770:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;64786:1008;;;64715:1079;:::o;62219:221::-;62304:14;62321:20;62338:2;62321:16;:20::i;:::-;62304:37;;62379:7;62352:12;:16;62365:2;62352:16;;;;;;;;;;;;;;;:24;62369:6;62352:24;;;;;;;;;;;:34;;;;62426:6;62397:17;:26;62415:7;62397:26;;;;;;;;;;;:35;;;;62293:147;62219:221;;:::o;11586:922::-;11639:7;11659:14;11676:1;11659:18;;11726:6;11717:5;:15;11713:102;;11762:6;11753:15;;;;;;:::i;:::-;;;;;11797:2;11787:12;;;;11713:102;11842:6;11833:5;:15;11829:102;;11878:6;11869:15;;;;;;:::i;:::-;;;;;11913:2;11903:12;;;;11829:102;11958:6;11949:5;:15;11945:102;;11994:6;11985:15;;;;;;:::i;:::-;;;;;12029:2;12019:12;;;;11945:102;12074:5;12065;:14;12061:99;;12109:5;12100:14;;;;;;:::i;:::-;;;;;12143:1;12133:11;;;;12061:99;12187:5;12178;:14;12174:99;;12222:5;12213:14;;;;;;:::i;:::-;;;;;12256:1;12246:11;;;;12174:99;12300:5;12291;:14;12287:99;;12335:5;12326:14;;;;;;:::i;:::-;;;;;12369:1;12359:11;;;;12287:99;12413:5;12404;:14;12400:66;;12449:1;12439:11;;;;12400:66;12494:6;12487:13;;;11586:922;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:118::-;5025:24;5043:5;5025:24;:::i;:::-;5020:3;5013:37;4938:118;;:::o;5062:222::-;5155:4;5193:2;5182:9;5178:18;5170:26;;5206:71;5274:1;5263:9;5259:17;5250:6;5206:71;:::i;:::-;5062:222;;;;:::o;5290:619::-;5367:6;5375;5383;5432:2;5420:9;5411:7;5407:23;5403:32;5400:119;;;5438:79;;:::i;:::-;5400:119;5558:1;5583:53;5628:7;5619:6;5608:9;5604:22;5583:53;:::i;:::-;5573:63;;5529:117;5685:2;5711:53;5756:7;5747:6;5736:9;5732:22;5711:53;:::i;:::-;5701:63;;5656:118;5813:2;5839:53;5884:7;5875:6;5864:9;5860:22;5839:53;:::i;:::-;5829:63;;5784:118;5290:619;;;;;:::o;5915:329::-;5974:6;6023:2;6011:9;6002:7;5998:23;5994:32;5991:119;;;6029:79;;:::i;:::-;5991:119;6149:1;6174:53;6219:7;6210:6;6199:9;6195:22;6174:53;:::i;:::-;6164:63;;6120:117;5915:329;;;;:::o;6250:116::-;6320:21;6335:5;6320:21;:::i;:::-;6313:5;6310:32;6300:60;;6356:1;6353;6346:12;6300:60;6250:116;:::o;6372:133::-;6415:5;6453:6;6440:20;6431:29;;6469:30;6493:5;6469:30;:::i;:::-;6372:133;;;;:::o;6511:468::-;6576:6;6584;6633:2;6621:9;6612:7;6608:23;6604:32;6601:119;;;6639:79;;:::i;:::-;6601:119;6759:1;6784:53;6829:7;6820:6;6809:9;6805:22;6784:53;:::i;:::-;6774:63;;6730:117;6886:2;6912:50;6954:7;6945:6;6934:9;6930:22;6912:50;:::i;:::-;6902:60;;6857:115;6511:468;;;;;:::o;6985:117::-;7094:1;7091;7084:12;7108:117;7217:1;7214;7207:12;7231:180;7279:77;7276:1;7269:88;7376:4;7373:1;7366:15;7400:4;7397:1;7390:15;7417:281;7500:27;7522:4;7500:27;:::i;:::-;7492:6;7488:40;7630:6;7618:10;7615:22;7594:18;7582:10;7579:34;7576:62;7573:88;;;7641:18;;:::i;:::-;7573:88;7681:10;7677:2;7670:22;7460:238;7417:281;;:::o;7704:129::-;7738:6;7765:20;;:::i;:::-;7755:30;;7794:33;7822:4;7814:6;7794:33;:::i;:::-;7704:129;;;:::o;7839:307::-;7900:4;7990:18;7982:6;7979:30;7976:56;;;8012:18;;:::i;:::-;7976:56;8050:29;8072:6;8050:29;:::i;:::-;8042:37;;8134:4;8128;8124:15;8116:23;;7839:307;;;:::o;8152:154::-;8236:6;8231:3;8226;8213:30;8298:1;8289:6;8284:3;8280:16;8273:27;8152:154;;;:::o;8312:410::-;8389:5;8414:65;8430:48;8471:6;8430:48;:::i;:::-;8414:65;:::i;:::-;8405:74;;8502:6;8495:5;8488:21;8540:4;8533:5;8529:16;8578:3;8569:6;8564:3;8560:16;8557:25;8554:112;;;8585:79;;:::i;:::-;8554:112;8675:41;8709:6;8704:3;8699;8675:41;:::i;:::-;8395:327;8312:410;;;;;:::o;8741:338::-;8796:5;8845:3;8838:4;8830:6;8826:17;8822:27;8812:122;;8853:79;;:::i;:::-;8812:122;8970:6;8957:20;8995:78;9069:3;9061:6;9054:4;9046:6;9042:17;8995:78;:::i;:::-;8986:87;;8802:277;8741:338;;;;:::o;9085:943::-;9180:6;9188;9196;9204;9253:3;9241:9;9232:7;9228:23;9224:33;9221:120;;;9260:79;;:::i;:::-;9221:120;9380:1;9405:53;9450:7;9441:6;9430:9;9426:22;9405:53;:::i;:::-;9395:63;;9351:117;9507:2;9533:53;9578:7;9569:6;9558:9;9554:22;9533:53;:::i;:::-;9523:63;;9478:118;9635:2;9661:53;9706:7;9697:6;9686:9;9682:22;9661:53;:::i;:::-;9651:63;;9606:118;9791:2;9780:9;9776:18;9763:32;9822:18;9814:6;9811:30;9808:117;;;9844:79;;:::i;:::-;9808:117;9949:62;10003:7;9994:6;9983:9;9979:22;9949:62;:::i;:::-;9939:72;;9734:287;9085:943;;;;;;;:::o;10034:308::-;10096:4;10186:18;10178:6;10175:30;10172:56;;;10208:18;;:::i;:::-;10172:56;10246:29;10268:6;10246:29;:::i;:::-;10238:37;;10330:4;10324;10320:15;10312:23;;10034:308;;;:::o;10348:412::-;10426:5;10451:66;10467:49;10509:6;10467:49;:::i;:::-;10451:66;:::i;:::-;10442:75;;10540:6;10533:5;10526:21;10578:4;10571:5;10567:16;10616:3;10607:6;10602:3;10598:16;10595:25;10592:112;;;10623:79;;:::i;:::-;10592:112;10713:41;10747:6;10742:3;10737;10713:41;:::i;:::-;10432:328;10348:412;;;;;:::o;10780:340::-;10836:5;10885:3;10878:4;10870:6;10866:17;10862:27;10852:122;;10893:79;;:::i;:::-;10852:122;11010:6;10997:20;11035:79;11110:3;11102:6;11095:4;11087:6;11083:17;11035:79;:::i;:::-;11026:88;;10842:278;10780:340;;;;:::o;11126:799::-;11213:6;11221;11229;11278:2;11266:9;11257:7;11253:23;11249:32;11246:119;;;11284:79;;:::i;:::-;11246:119;11404:1;11429:53;11474:7;11465:6;11454:9;11450:22;11429:53;:::i;:::-;11419:63;;11375:117;11531:2;11557:53;11602:7;11593:6;11582:9;11578:22;11557:53;:::i;:::-;11547:63;;11502:118;11687:2;11676:9;11672:18;11659:32;11718:18;11710:6;11707:30;11704:117;;;11740:79;;:::i;:::-;11704:117;11845:63;11900:7;11891:6;11880:9;11876:22;11845:63;:::i;:::-;11835:73;;11630:288;11126:799;;;;;:::o;11931:474::-;11999:6;12007;12056:2;12044:9;12035:7;12031:23;12027:32;12024:119;;;12062:79;;:::i;:::-;12024:119;12182:1;12207:53;12252:7;12243:6;12232:9;12228:22;12207:53;:::i;:::-;12197:63;;12153:117;12309:2;12335:53;12380:7;12371:6;12360:9;12356:22;12335:53;:::i;:::-;12325:63;;12280:118;11931:474;;;;;:::o;12411:180::-;12459:77;12456:1;12449:88;12556:4;12553:1;12546:15;12580:4;12577:1;12570:15;12597:320;12641:6;12678:1;12672:4;12668:12;12658:22;;12725:1;12719:4;12715:12;12746:18;12736:81;;12802:4;12794:6;12790:17;12780:27;;12736:81;12864:2;12856:6;12853:14;12833:18;12830:38;12827:84;;;12883:18;;:::i;:::-;12827:84;12648:269;12597:320;;;:::o;12923:220::-;13063:34;13059:1;13051:6;13047:14;13040:58;13132:3;13127:2;13119:6;13115:15;13108:28;12923:220;:::o;13149:366::-;13291:3;13312:67;13376:2;13371:3;13312:67;:::i;:::-;13305:74;;13388:93;13477:3;13388:93;:::i;:::-;13506:2;13501:3;13497:12;13490:19;;13149:366;;;:::o;13521:419::-;13687:4;13725:2;13714:9;13710:18;13702:26;;13774:9;13768:4;13764:20;13760:1;13749:9;13745:17;13738:47;13802:131;13928:4;13802:131;:::i;:::-;13794:139;;13521:419;;;:::o;13946:248::-;14086:34;14082:1;14074:6;14070:14;14063:58;14155:31;14150:2;14142:6;14138:15;14131:56;13946:248;:::o;14200:366::-;14342:3;14363:67;14427:2;14422:3;14363:67;:::i;:::-;14356:74;;14439:93;14528:3;14439:93;:::i;:::-;14557:2;14552:3;14548:12;14541:19;;14200:366;;;:::o;14572:419::-;14738:4;14776:2;14765:9;14761:18;14753:26;;14825:9;14819:4;14815:20;14811:1;14800:9;14796:17;14789:47;14853:131;14979:4;14853:131;:::i;:::-;14845:139;;14572:419;;;:::o;14997:232::-;15137:34;15133:1;15125:6;15121:14;15114:58;15206:15;15201:2;15193:6;15189:15;15182:40;14997:232;:::o;15235:366::-;15377:3;15398:67;15462:2;15457:3;15398:67;:::i;:::-;15391:74;;15474:93;15563:3;15474:93;:::i;:::-;15592:2;15587:3;15583:12;15576:19;;15235:366;;;:::o;15607:419::-;15773:4;15811:2;15800:9;15796:18;15788:26;;15860:9;15854:4;15850:20;15846:1;15835:9;15831:17;15824:47;15888:131;16014:4;15888:131;:::i;:::-;15880:139;;15607:419;;;:::o;16032:230::-;16172:34;16168:1;16160:6;16156:14;16149:58;16241:13;16236:2;16228:6;16224:15;16217:38;16032:230;:::o;16268:366::-;16410:3;16431:67;16495:2;16490:3;16431:67;:::i;:::-;16424:74;;16507:93;16596:3;16507:93;:::i;:::-;16625:2;16620:3;16616:12;16609:19;;16268:366;;;:::o;16640:419::-;16806:4;16844:2;16833:9;16829:18;16821:26;;16893:9;16887:4;16883:20;16879:1;16868:9;16864:17;16857:47;16921:131;17047:4;16921:131;:::i;:::-;16913:139;;16640:419;;;:::o;17065:231::-;17205:34;17201:1;17193:6;17189:14;17182:58;17274:14;17269:2;17261:6;17257:15;17250:39;17065:231;:::o;17302:366::-;17444:3;17465:67;17529:2;17524:3;17465:67;:::i;:::-;17458:74;;17541:93;17630:3;17541:93;:::i;:::-;17659:2;17654:3;17650:12;17643:19;;17302:366;;;:::o;17674:419::-;17840:4;17878:2;17867:9;17863:18;17855:26;;17927:9;17921:4;17917:20;17913:1;17902:9;17898:17;17891:47;17955:131;18081:4;17955:131;:::i;:::-;17947:139;;17674:419;;;:::o;18099:180::-;18147:77;18144:1;18137:88;18244:4;18241:1;18234:15;18268:4;18265:1;18258:15;18285:174;18425:26;18421:1;18413:6;18409:14;18402:50;18285:174;:::o;18465:366::-;18607:3;18628:67;18692:2;18687:3;18628:67;:::i;:::-;18621:74;;18704:93;18793:3;18704:93;:::i;:::-;18822:2;18817:3;18813:12;18806:19;;18465:366;;;:::o;18837:419::-;19003:4;19041:2;19030:9;19026:18;19018:26;;19090:9;19084:4;19080:20;19076:1;19065:9;19061:17;19054:47;19118:131;19244:4;19118:131;:::i;:::-;19110:139;;18837:419;;;:::o;19262:228::-;19402:34;19398:1;19390:6;19386:14;19379:58;19471:11;19466:2;19458:6;19454:15;19447:36;19262:228;:::o;19496:366::-;19638:3;19659:67;19723:2;19718:3;19659:67;:::i;:::-;19652:74;;19735:93;19824:3;19735:93;:::i;:::-;19853:2;19848:3;19844:12;19837:19;;19496:366;;;:::o;19868:419::-;20034:4;20072:2;20061:9;20057:18;20049:26;;20121:9;20115:4;20111:20;20107:1;20096:9;20092:17;20085:47;20149:131;20275:4;20149:131;:::i;:::-;20141:139;;19868:419;;;:::o;20293:180::-;20341:77;20338:1;20331:88;20438:4;20435:1;20428:15;20462:4;20459:1;20452:15;20479:305;20519:3;20538:20;20556:1;20538:20;:::i;:::-;20533:25;;20572:20;20590:1;20572:20;:::i;:::-;20567:25;;20726:1;20658:66;20654:74;20651:1;20648:81;20645:107;;;20732:18;;:::i;:::-;20645:107;20776:1;20773;20769:9;20762:16;;20479:305;;;;:::o;20790:171::-;20930:23;20926:1;20918:6;20914:14;20907:47;20790:171;:::o;20967:366::-;21109:3;21130:67;21194:2;21189:3;21130:67;:::i;:::-;21123:74;;21206:93;21295:3;21206:93;:::i;:::-;21324:2;21319:3;21315:12;21308:19;;20967:366;;;:::o;21339:419::-;21505:4;21543:2;21532:9;21528:18;21520:26;;21592:9;21586:4;21582:20;21578:1;21567:9;21563:17;21556:47;21620:131;21746:4;21620:131;:::i;:::-;21612:139;;21339:419;;;:::o;21764:233::-;21803:3;21826:24;21844:5;21826:24;:::i;:::-;21817:33;;21872:66;21865:5;21862:77;21859:103;;;21942:18;;:::i;:::-;21859:103;21989:1;21982:5;21978:13;21971:20;;21764:233;;;:::o;22003:225::-;22143:34;22139:1;22131:6;22127:14;22120:58;22212:8;22207:2;22199:6;22195:15;22188:33;22003:225;:::o;22234:366::-;22376:3;22397:67;22461:2;22456:3;22397:67;:::i;:::-;22390:74;;22473:93;22562:3;22473:93;:::i;:::-;22591:2;22586:3;22582:12;22575:19;;22234:366;;;:::o;22606:419::-;22772:4;22810:2;22799:9;22795:18;22787:26;;22859:9;22853:4;22849:20;22845:1;22834:9;22830:17;22823:47;22887:131;23013:4;22887:131;:::i;:::-;22879:139;;22606:419;;;:::o;23031:224::-;23171:34;23167:1;23159:6;23155:14;23148:58;23240:7;23235:2;23227:6;23223:15;23216:32;23031:224;:::o;23261:366::-;23403:3;23424:67;23488:2;23483:3;23424:67;:::i;:::-;23417:74;;23500:93;23589:3;23500:93;:::i;:::-;23618:2;23613:3;23609:12;23602:19;;23261:366;;;:::o;23633:419::-;23799:4;23837:2;23826:9;23822:18;23814:26;;23886:9;23880:4;23876:20;23872:1;23861:9;23857:17;23850:47;23914:131;24040:4;23914:131;:::i;:::-;23906:139;;23633:419;;;:::o;24058:223::-;24198:34;24194:1;24186:6;24182:14;24175:58;24267:6;24262:2;24254:6;24250:15;24243:31;24058:223;:::o;24287:366::-;24429:3;24450:67;24514:2;24509:3;24450:67;:::i;:::-;24443:74;;24526:93;24615:3;24526:93;:::i;:::-;24644:2;24639:3;24635:12;24628:19;;24287:366;;;:::o;24659:419::-;24825:4;24863:2;24852:9;24848:18;24840:26;;24912:9;24906:4;24902:20;24898:1;24887:9;24883:17;24876:47;24940:131;25066:4;24940:131;:::i;:::-;24932:139;;24659:419;;;:::o;25084:182::-;25224:34;25220:1;25212:6;25208:14;25201:58;25084:182;:::o;25272:366::-;25414:3;25435:67;25499:2;25494:3;25435:67;:::i;:::-;25428:74;;25511:93;25600:3;25511:93;:::i;:::-;25629:2;25624:3;25620:12;25613:19;;25272:366;;;:::o;25644:419::-;25810:4;25848:2;25837:9;25833:18;25825:26;;25897:9;25891:4;25887:20;25883:1;25872:9;25868:17;25861:47;25925:131;26051:4;25925:131;:::i;:::-;25917:139;;25644:419;;;:::o;26069:175::-;26209:27;26205:1;26197:6;26193:14;26186:51;26069:175;:::o;26250:366::-;26392:3;26413:67;26477:2;26472:3;26413:67;:::i;:::-;26406:74;;26489:93;26578:3;26489:93;:::i;:::-;26607:2;26602:3;26598:12;26591:19;;26250:366;;;:::o;26622:419::-;26788:4;26826:2;26815:9;26811:18;26803:26;;26875:9;26869:4;26865:20;26861:1;26850:9;26846:17;26839:47;26903:131;27029:4;26903:131;:::i;:::-;26895:139;;26622:419;;;:::o;27047:237::-;27187:34;27183:1;27175:6;27171:14;27164:58;27256:20;27251:2;27243:6;27239:15;27232:45;27047:237;:::o;27290:366::-;27432:3;27453:67;27517:2;27512:3;27453:67;:::i;:::-;27446:74;;27529:93;27618:3;27529:93;:::i;:::-;27647:2;27642:3;27638:12;27631:19;;27290:366;;;:::o;27662:419::-;27828:4;27866:2;27855:9;27851:18;27843:26;;27915:9;27909:4;27905:20;27901:1;27890:9;27886:17;27879:47;27943:131;28069:4;27943:131;:::i;:::-;27935:139;;27662:419;;;:::o;28087:148::-;28189:11;28226:3;28211:18;;28087:148;;;;:::o;28241:377::-;28347:3;28375:39;28408:5;28375:39;:::i;:::-;28430:89;28512:6;28507:3;28430:89;:::i;:::-;28423:96;;28528:52;28573:6;28568:3;28561:4;28554:5;28550:16;28528:52;:::i;:::-;28605:6;28600:3;28596:16;28589:23;;28351:267;28241:377;;;;:::o;28624:435::-;28804:3;28826:95;28917:3;28908:6;28826:95;:::i;:::-;28819:102;;28938:95;29029:3;29020:6;28938:95;:::i;:::-;28931:102;;29050:3;29043:10;;28624:435;;;;;:::o;29065:233::-;29205:34;29201:1;29193:6;29189:14;29182:58;29274:16;29269:2;29261:6;29257:15;29250:41;29065:233;:::o;29304:366::-;29446:3;29467:67;29531:2;29526:3;29467:67;:::i;:::-;29460:74;;29543:93;29632:3;29543:93;:::i;:::-;29661:2;29656:3;29652:12;29645:19;;29304:366;;;:::o;29676:419::-;29842:4;29880:2;29869:9;29865:18;29857:26;;29929:9;29923:4;29919:20;29915:1;29904:9;29900:17;29893:47;29957:131;30083:4;29957:131;:::i;:::-;29949:139;;29676:419;;;:::o;30101:98::-;30152:6;30186:5;30180:12;30170:22;;30101:98;;;:::o;30205:168::-;30288:11;30322:6;30317:3;30310:19;30362:4;30357:3;30353:14;30338:29;;30205:168;;;;:::o;30379:360::-;30465:3;30493:38;30525:5;30493:38;:::i;:::-;30547:70;30610:6;30605:3;30547:70;:::i;:::-;30540:77;;30626:52;30671:6;30666:3;30659:4;30652:5;30648:16;30626:52;:::i;:::-;30703:29;30725:6;30703:29;:::i;:::-;30698:3;30694:39;30687:46;;30469:270;30379:360;;;;:::o;30745:640::-;30940:4;30978:3;30967:9;30963:19;30955:27;;30992:71;31060:1;31049:9;31045:17;31036:6;30992:71;:::i;:::-;31073:72;31141:2;31130:9;31126:18;31117:6;31073:72;:::i;:::-;31155;31223:2;31212:9;31208:18;31199:6;31155:72;:::i;:::-;31274:9;31268:4;31264:20;31259:2;31248:9;31244:18;31237:48;31302:76;31373:4;31364:6;31302:76;:::i;:::-;31294:84;;30745:640;;;;;;;:::o;31391:141::-;31447:5;31478:6;31472:13;31463:22;;31494:32;31520:5;31494:32;:::i;:::-;31391:141;;;;:::o;31538:349::-;31607:6;31656:2;31644:9;31635:7;31631:23;31627:32;31624:119;;;31662:79;;:::i;:::-;31624:119;31782:1;31807:63;31862:7;31853:6;31842:9;31838:22;31807:63;:::i;:::-;31797:73;;31753:127;31538:349;;;;:::o;31893:240::-;32033:34;32029:1;32021:6;32017:14;32010:58;32102:23;32097:2;32089:6;32085:15;32078:48;31893:240;:::o;32139:366::-;32281:3;32302:67;32366:2;32361:3;32302:67;:::i;:::-;32295:74;;32378:93;32467:3;32378:93;:::i;:::-;32496:2;32491:3;32487:12;32480:19;;32139:366;;;:::o;32511:419::-;32677:4;32715:2;32704:9;32700:18;32692:26;;32764:9;32758:4;32754:20;32750:1;32739:9;32735:17;32728:47;32792:131;32918:4;32792:131;:::i;:::-;32784:139;;32511:419;;;:::o;32936:180::-;32984:77;32981:1;32974:88;33081:4;33078:1;33071:15;33105:4;33102:1;33095:15;33122:182;33262:34;33258:1;33250:6;33246:14;33239:58;33122:182;:::o;33310:366::-;33452:3;33473:67;33537:2;33532:3;33473:67;:::i;:::-;33466:74;;33549:93;33638:3;33549:93;:::i;:::-;33667:2;33662:3;33658:12;33651:19;;33310:366;;;:::o;33682:419::-;33848:4;33886:2;33875:9;33871:18;33863:26;;33935:9;33929:4;33925:20;33921:1;33910:9;33906:17;33899:47;33963:131;34089:4;33963:131;:::i;:::-;33955:139;;33682:419;;;:::o;34107:178::-;34247:30;34243:1;34235:6;34231:14;34224:54;34107:178;:::o;34291:366::-;34433:3;34454:67;34518:2;34513:3;34454:67;:::i;:::-;34447:74;;34530:93;34619:3;34530:93;:::i;:::-;34648:2;34643:3;34639:12;34632:19;;34291:366;;;:::o;34663:419::-;34829:4;34867:2;34856:9;34852:18;34844:26;;34916:9;34910:4;34906:20;34902:1;34891:9;34887:17;34880:47;34944:131;35070:4;34944:131;:::i;:::-;34936:139;;34663:419;;;:::o;35088:191::-;35128:4;35148:20;35166:1;35148:20;:::i;:::-;35143:25;;35182:20;35200:1;35182:20;:::i;:::-;35177:25;;35221:1;35218;35215:8;35212:34;;;35226:18;;:::i;:::-;35212:34;35271:1;35268;35264:9;35256:17;;35088:191;;;;:::o;35285:180::-;35333:77;35330:1;35323:88;35430:4;35427:1;35420:15;35454:4;35451:1;35444:15

Swarm Source

ipfs://784b14ad0a25d1807ec643b31a6671c3bdb9054ecbfb023ecfe7784a19aa3d3a
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.