ETH Price: $3,372.82 (-3.26%)

Token

CGLampPass (CGLP)
 

Overview

Max Total Supply

65 CGLP

Holders

54

Total Transfers

-

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
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
CryptoGains

Compiler Version
v0.8.14+commit.80d49f37

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-03-12
*/

// File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

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


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

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

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

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

// File: @openzeppelin/contracts/utils/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;
            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/access/Ownable2Step.sol


// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides 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} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

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

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() external {
        address sender = _msgSender();
        require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
        _transferOwnership(sender);
    }
}

// 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/ERC20/utils/SafeERC20.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;




/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

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



pragma solidity 0.8.14;






error Unavailable();
error MintIsPaused();
error MintingWrongAmount();
error ExceedsMaxSupply();
error WrongToken();
error USDCsameAddressUSDT();

contract CryptoGains is ERC721Enumerable, Ownable2Step, ReentrancyGuard {
    /// @audit by Asparh Damyanov
    /// @audit the buy with USDC and USDT function can be merged into one single buyWithToken funciton,
    // that accepts the address of the desired token and there should be a check
    // for addresses that are not whitelisted, this can be implemented via a mapping of
    // whitelisted (address => bool)
    // @audit Implement two step ownership transfer with Ownable2Step
    /// @audit USDC and USDT can be private with view functions, as well as other params
    /// @audit baseUri is public, it can be changed to private - however the client requested it remains public

    /**
     * @notice a Simple Smart contract holding a NFT collection type "Pass"
     * @notice audited and function implementations changed by @author Asparuh Damyanov
     * @dev Ownable sets Owner to msg.sender
     */

    using SafeERC20 for IERC20;

    using Strings for uint256;

    using Counters for Counters.Counter;

    Counters.Counter private _tokenIds;

    /// @notice sets the public address of USDC
    IERC20 public usdc;

    /// @notice sets the public address of USDT
    IERC20 public usdt;

    /// @notice store the whitelisted token addresses
    mapping(IERC20 => bool) public whitelistedTokens;

    // if base uri is public then it can be viewed by everyone
    string public baseURI;
    string public baseExtension = ".json";

    /// @notice added price change to be dynamically set by a function
    uint256 public usdcPrice;
    uint256 public usdtPrice;

    // for the contracts = 300 600 150
    /// @notice added maxSupply change to be dynamically set by a function
    uint256 public maxSupply = 300;
    uint256 public maxMintAmount = 5;

    /// @notice added paused to be set by a function
    bool public paused = true;

    /**
     * // FOR TESTING: CryptoGains,CG,ipfs/QmZdCwu88xKngFXMHS6x7RZXd2EvgyMSxyaFHor4F5Etm3/,0x07865c6E87B9F70255377e024ace6630C1Eaa37F,0xC2C527C0CACF457746Bd31B2a698Fe89de2b6d49
     * // FOR TESTING: 
     * @param _name CryptoGains
     * @param _symbol  CG
     * @param _initBaseURI  Image URI CID: QmXR2hrWZZGRJTHVZRat1gMmZ29pPrp3jsW4Ev1QEaZSs5
            CID QmZdCwu88xKngFXMHS6x7RZXd2EvgyMSxyaFHor4F5Etm3
        @param _usdc the address to be set for USDC
        @param _usdt the address to be set for USDT

        For mainnet:
     */
    constructor(
        string memory _name,
        string memory _symbol,
        string memory _initBaseURI,
        address _usdc,
        address _usdt
    ) ERC721(_name, _symbol) {
        setBaseURI(_initBaseURI);
        usdc = IERC20(_usdc);
        usdt = IERC20(_usdt);
        whitelistedTokens[usdt] = true;
        whitelistedTokens[usdc] = true;
        if (usdc == usdt) revert Unavailable();
        usdcPrice = 1800 * 10 ** 6; // 1800 USDC (6 decimal places) - 5 million in decimals = 50$
        usdtPrice = 1800 * 10 ** 6; // 1800 USDT (6 decimal places)
    }

    /// @notice Indexes Mints
    event Minted(address indexed to, uint256 indexed price);

    /// @dev check if _token is != usdc, usdt , check if token address in = to 1 of them
    function mint(IERC20 _token, uint256 _mintAmount) external nonReentrant {
        // revert if paused
        if (paused) revert MintIsPaused();
        // revert if usdc and usdt tokens are set as the same address
        // to prevent double spending from the user
        if (usdc == usdt) revert USDCsameAddressUSDT();
        // revert if token is not usdc or usdt
        if (whitelistedTokens[_token] != true) revert WrongToken();
        // revert if mintAmount is wrong value
        if (_mintAmount > maxMintAmount || _mintAmount == 0)
            revert MintingWrongAmount();
        // revert if exceeds max mint balance
        if (balanceOf(msg.sender) + _mintAmount > maxMintAmount)
            revert MintingWrongAmount();

        // check if it returns the right balance
        uint256 _supply = totalSupply();
        if (_supply + _mintAmount >= maxSupply) revert ExceedsMaxSupply();

        /// @notice this forloop was in the original contract implementation
        /// @dev for loops are not recommended in solidity, however give the fact that only 2 arguments are passed its not critical
        /// @dev consider removing the for loop
        for (uint256 i = 1; i <= _mintAmount; i++) {
            // this mints to msg.sender a var called supply, which is equal to totalSupply() + i
            // which on first iteration is 1, on next is 2 => which is a total of 3
            // this takes _to and _tokenId
            // better take in a tokenId variable
            _safeMint(msg.sender, _supply + i);
            _tokenIds.increment();
        }

        /// @dev check how is the price different in USDC vs USDT
        if (msg.sender != owner()) {
            if (_token == usdt) {
                uint256 _fee = usdtPrice * _mintAmount;
                usdt.safeTransferFrom(msg.sender, address(this), _fee);
                // emit minted event
                emit Minted(msg.sender, _fee);
            }
            if (_token == usdc) {
                uint256 _fee = usdcPrice * _mintAmount;
                usdc.safeTransferFrom(msg.sender, address(this), _fee);
                // emit minted event
                emit Minted(msg.sender, _fee);
            }
        }
    }

    /// @notice Use this function to withrdaw any stuck or unnecessary ether in the contract
    function withdraw() external onlyOwner {
        // send all of the remaining balance to owner
        (bool success, ) = (payable(owner())).call{
            value: address(this).balance
        }("");
        require(success);
    }


    /// @notice able to withdraw both USDC and USDT
    function withdrawToken(IERC20 _token) external onlyOwner {
        if (whitelistedTokens[_token] != true) revert WrongToken();

        _token.safeTransfer(
            msg.sender,
            _token.balanceOf(address(this))
        );
    }

    /// @notice returns the tokenId count
    function count() public view returns (uint256) {
        return _tokenIds.current();
    }

    /// @notice this function was in the original contract implementation
    // wants to return the tokenIds owned by a user
    // client wants to keep it
    function checkTokensOwned(
        address _owner
    ) public view returns (uint256[] memory) {
        // caches the owners tokenCount
        uint256 ownerTokenCount = balanceOf(_owner);

        uint256[] memory tokenIds = new uint256[](ownerTokenCount);
        for (uint256 i; i < ownerTokenCount; i++) {
            tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
        }
        return tokenIds;
    }

    /// @notice this function was in the original contract implementation
    function tokenURI(
        uint256 tokenId
    ) public view virtual override returns (string memory) {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );
        // can be calldata, but doesnt matter since its a view function
        string memory currentBaseURI = _baseURI();

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

    /// @notice this function was in the original contract implementation
    function setmaxMintAmount(uint256 _newmaxMintAmount) external onlyOwner {
        maxMintAmount = _newmaxMintAmount;
    }

    /// @notice this function was in the original contract implementation
    function setBaseURI(string memory _newBaseURI) public onlyOwner {
        baseURI = _newBaseURI;
    }

    /// @notice this function was in the original contract implementation
    function setBaseExtension(
        string memory _newBaseExtension
    ) public onlyOwner {
        baseExtension = _newBaseExtension;
    }

    /// @notice function to dynamically pause and unpause - simply pass in true or false
    function setPause(bool _paused) external onlyOwner {
        paused = _paused;
    }

    /// @notice function to dynamically change supply
    function changeSupply(uint256 _supply) external onlyOwner {
        maxSupply = _supply;
    }

    /// @notice function to dynamically change price
    function changePriceUSDC(uint256 _price) external onlyOwner {
        usdcPrice = _price;
    }

    function changePriceUSDT(uint256 _price) external onlyOwner {
        usdtPrice = _price;
    }

    /// @notice function to change USDC address
    function changeUSDC(IERC20 _usdc) external onlyOwner {
        // checks owner prone error of setting both usdc and usdt as the same address
        if (_usdc == usdt) revert USDCsameAddressUSDT();
        whitelistedTokens[usdc] = false;
        whitelistedTokens[_usdc] = true;
        usdc = _usdc;
    }

    /// @notice function to change USDT address
    function changeUSDT(IERC20 _usdt) external onlyOwner {
        // checks owner prone error of setting both usdc and usdt as the same address
        if (_usdt == usdc) revert USDCsameAddressUSDT();
        whitelistedTokens[usdt] = false;
        whitelistedTokens[_usdt] = true;
        usdt = _usdt;
    }

    /// @notice this function was required by the original contract
    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }
  
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_initBaseURI","type":"string"},{"internalType":"address","name":"_usdc","type":"address"},{"internalType":"address","name":"_usdt","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ExceedsMaxSupply","type":"error"},{"inputs":[],"name":"MintIsPaused","type":"error"},{"inputs":[],"name":"MintingWrongAmount","type":"error"},{"inputs":[],"name":"USDCsameAddressUSDT","type":"error"},{"inputs":[],"name":"Unavailable","type":"error"},{"inputs":[],"name":"WrongToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"price","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"changePriceUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"changePriceUSDT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"name":"changeSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_usdc","type":"address"}],"name":"changeUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_usdt","type":"address"}],"name":"changeUSDT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"checkTokensOwned","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","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":"maxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newmaxMintAmount","type":"uint256"}],"name":"setmaxMintAmount","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"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdcPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdtPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"name":"whitelistedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060400160405280600581526020017f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060129080519060200190620000519291906200054e565b5061012c60155560056016556001601760006101000a81548160ff0219169083151502179055503480156200008557600080fd5b5060405162005caf38038062005caf8339818101604052810190620000ab919062000800565b84848160009080519060200190620000c59291906200054e565b508060019080519060200190620000de9291906200054e565b50505062000101620000f56200035b60201b60201c565b6200036360201b60201c565b6001600c819055506200011a83620003a160201b60201c565b81600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160106000600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600160106000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036200033a576040517fa3b8915f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b636b49d200601381905550636b49d2006014819055505050505050620009cc565b600033905090565b600b60006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556200039e81620003cd60201b62001e6c1760201c565b50565b620003b16200049360201b60201c565b8060119080519060200190620003c99291906200054e565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620004a36200035b60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620004c96200052460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000522576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005199062000946565b60405180910390fd5b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b8280546200055c9062000997565b90600052602060002090601f016020900481019282620005805760008555620005cc565b82601f106200059b57805160ff1916838001178555620005cc565b82800160010185558215620005cc579182015b82811115620005cb578251825591602001919060010190620005ae565b5b509050620005db9190620005df565b5090565b5b80821115620005fa576000816000905550600101620005e0565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b62000667826200061c565b810181811067ffffffffffffffff821117156200068957620006886200062d565b5b80604052505050565b60006200069e620005fe565b9050620006ac82826200065c565b919050565b600067ffffffffffffffff821115620006cf57620006ce6200062d565b5b620006da826200061c565b9050602081019050919050565b60005b8381101562000707578082015181840152602081019050620006ea565b8381111562000717576000848401525b50505050565b6000620007346200072e84620006b1565b62000692565b90508281526020810184848401111562000753576200075262000617565b5b62000760848285620006e7565b509392505050565b600082601f83011262000780576200077f62000612565b5b8151620007928482602086016200071d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620007c8826200079b565b9050919050565b620007da81620007bb565b8114620007e657600080fd5b50565b600081519050620007fa81620007cf565b92915050565b600080600080600060a086880312156200081f576200081e62000608565b5b600086015167ffffffffffffffff81111562000840576200083f6200060d565b5b6200084e8882890162000768565b955050602086015167ffffffffffffffff8111156200087257620008716200060d565b5b620008808882890162000768565b945050604086015167ffffffffffffffff811115620008a457620008a36200060d565b5b620008b28882890162000768565b9350506060620008c588828901620007e9565b9250506080620008d888828901620007e9565b9150509295509295909350565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006200092e602083620008e5565b91506200093b82620008f6565b602082019050919050565b6000602082019050818103600083015262000961816200091f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620009b057607f821691505b602082108103620009c657620009c562000968565b5b50919050565b6152d380620009dc6000396000f3fe608060405234801561001057600080fd5b506004361061027f5760003560e01c80636c0360eb1161015c578063b88d4fde116100ce578063dacee34711610087578063dacee3471461074a578063daf9c21014610768578063e136f65f14610798578063e30c3978146107b6578063e985e9c5146107d4578063f2fde38b146108045761027f565b8063b88d4fde1461068a578063bedb86fb146106a6578063c6682862146106c2578063c87b56dd146106e0578063d5abeb0114610710578063da3ef23f1461072e5761027f565b80637f6e36d4116101205780637f6e36d4146105ca57806389476069146105e65780638da5cb5b146106025780639253ed041461062057806395d89b4114610650578063a22cb4651461066e5761027f565b80636c0360eb1461054c57806370a082311461056a578063715018a61461059a57806379ba5097146105a45780637f00c7a6146105ae5761027f565b80633410fc44116101f557806342842e0e116101b957806342842e0e1461047a5780634782e407146104965780634f6ccce7146104b257806355f804b3146104e25780635c975abb146104fe5780636352211e1461051c5761027f565b80633410fc44146103fe57806339a7919f1461041a5780633ccfd60b146104365780633e413bee1461044057806340c10f191461045e5761027f565b806318160ddd1161024757806318160ddd1461033c5780631ff415d91461035a578063239c70ae1461037657806323b872dd146103945780632f48ab7d146103b05780632f745c59146103ce5761027f565b806301ffc9a71461028457806306661abd146102b457806306fdde03146102d2578063081812fc146102f0578063095ea7b314610320575b600080fd5b61029e6004803603810190610299919061399c565b610820565b6040516102ab91906139e4565b60405180910390f35b6102bc61089a565b6040516102c99190613a18565b60405180910390f35b6102da6108ab565b6040516102e79190613acc565b60405180910390f35b61030a60048036038101906103059190613b1a565b61093d565b6040516103179190613b88565b60405180910390f35b61033a60048036038101906103359190613bcf565b610983565b005b610344610a9a565b6040516103519190613a18565b60405180910390f35b610374600480360381019061036f9190613c4d565b610aa7565b005b61037e610c4c565b60405161038b9190613a18565b60405180910390f35b6103ae60048036038101906103a99190613c7a565b610c52565b005b6103b8610cb2565b6040516103c59190613d2c565b60405180910390f35b6103e860048036038101906103e39190613bcf565b610cd8565b6040516103f59190613a18565b60405180910390f35b61041860048036038101906104139190613b1a565b610d7d565b005b610434600480360381019061042f9190613b1a565b610d8f565b005b61043e610da1565b005b610448610e29565b6040516104559190613d2c565b60405180910390f35b61047860048036038101906104739190613d47565b610e4f565b005b610494600480360381019061048f9190613c7a565b61133a565b005b6104b060048036038101906104ab9190613c4d565b61135a565b005b6104cc60048036038101906104c79190613b1a565b6114ff565b6040516104d99190613a18565b60405180910390f35b6104fc60048036038101906104f79190613ebc565b611570565b005b610506611592565b60405161051391906139e4565b60405180910390f35b61053660048036038101906105319190613b1a565b6115a5565b6040516105439190613b88565b60405180910390f35b61055461162b565b6040516105619190613acc565b60405180910390f35b610584600480360381019061057f9190613f05565b6116b9565b6040516105919190613a18565b60405180910390f35b6105a2611770565b005b6105ac611784565b005b6105c860048036038101906105c39190613b1a565b611811565b005b6105e460048036038101906105df9190613b1a565b611823565b005b61060060048036038101906105fb9190613c4d565b611835565b005b61060a61196e565b6040516106179190613b88565b60405180910390f35b61063a60048036038101906106359190613f05565b611998565b6040516106479190613ff0565b60405180910390f35b610658611a46565b6040516106659190613acc565b60405180910390f35b6106886004803603810190610683919061403e565b611ad8565b005b6106a4600480360381019061069f919061411f565b611aee565b005b6106c060048036038101906106bb91906141a2565b611b50565b005b6106ca611b75565b6040516106d79190613acc565b60405180910390f35b6106fa60048036038101906106f59190613b1a565b611c03565b6040516107079190613acc565b60405180910390f35b610718611cad565b6040516107259190613a18565b60405180910390f35b61074860048036038101906107439190613ebc565b611cb3565b005b610752611cd5565b60405161075f9190613a18565b60405180910390f35b610782600480360381019061077d9190613c4d565b611cdb565b60405161078f91906139e4565b60405180910390f35b6107a0611cfb565b6040516107ad9190613a18565b60405180910390f35b6107be611d01565b6040516107cb9190613b88565b60405180910390f35b6107ee60048036038101906107e991906141cf565b611d2b565b6040516107fb91906139e4565b60405180910390f35b61081e60048036038101906108199190613f05565b611dbf565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610893575061089282611f32565b5b9050919050565b60006108a6600d612014565b905090565b6060600080546108ba9061423e565b80601f01602080910402602001604051908101604052809291908181526020018280546108e69061423e565b80156109335780601f1061090857610100808354040283529160200191610933565b820191906000526020600020905b81548152906001019060200180831161091657829003601f168201915b5050505050905090565b600061094882612022565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061098e826115a5565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f5906142e1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a1d61206d565b73ffffffffffffffffffffffffffffffffffffffff161480610a4c5750610a4b81610a4661206d565b611d2b565b5b610a8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8290614373565b60405180910390fd5b610a958383612075565b505050565b6000600880549050905090565b610aaf61212e565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b36576040517f9957f83800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060106000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60165481565b610c63610c5d61206d565b826121ac565b610ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9990614405565b60405180910390fd5b610cad838383612241565b505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610ce3836116b9565b8210610d24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1b90614497565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610d8561212e565b8060148190555050565b610d9761212e565b8060158190555050565b610da961212e565b6000610db361196e565b73ffffffffffffffffffffffffffffffffffffffff1647604051610dd6906144e8565b60006040518083038185875af1925050503d8060008114610e13576040519150601f19603f3d011682016040523d82523d6000602084013e610e18565b606091505b5050905080610e2657600080fd5b50565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610e5761253a565b601760009054906101000a900460ff1615610e9e576040517f58fc318200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610f47576040517f9957f83800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60011515601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514610fd1576040517fa0f3feea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654811180610fe15750600081145b15611018576040517ffae9feb900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60165481611025336116b9565b61102f919061452c565b1115611067576040517ffae9feb900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611071610a9a565b90506015548282611082919061452c565b106110b9576040517fc30436e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600190505b8281116110f9576110dc3382846110d7919061452c565b612589565b6110e6600d6125a7565b80806110f190614582565b9150506110c0565b5061110261196e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132d57600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112305760008260145461119991906145ca565b90506111ea333083600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166125bd909392919063ffffffff16565b803373ffffffffffffffffffffffffffffffffffffffff167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe60405160405180910390a3505b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361132c5760008260135461129591906145ca565b90506112e6333083600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166125bd909392919063ffffffff16565b803373ffffffffffffffffffffffffffffffffffffffff167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe60405160405180910390a3505b5b50611336612646565b5050565b61135583838360405180602001604052806000815250611aee565b505050565b61136261212e565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113e9576040517f9957f83800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060106000600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611509610a9a565b821061154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154190614696565b60405180910390fd5b6008828154811061155e5761155d6146b6565b5b90600052602060002001549050919050565b61157861212e565b806011908051906020019061158e92919061388d565b5050565b601760009054906101000a900460ff1681565b6000806115b183612650565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611622576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161990614731565b60405180910390fd5b80915050919050565b601180546116389061423e565b80601f01602080910402602001604051908101604052809291908181526020018280546116649061423e565b80156116b15780601f10611686576101008083540402835291602001916116b1565b820191906000526020600020905b81548152906001019060200180831161169457829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611729576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611720906147c3565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61177861212e565b611782600061268d565b565b600061178e61206d565b90508073ffffffffffffffffffffffffffffffffffffffff166117af611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611805576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117fc90614855565b60405180910390fd5b61180e8161268d565b50565b61181961212e565b8060168190555050565b61182b61212e565b8060138190555050565b61183d61212e565b60011515601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146118c7576040517fa0f3feea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61196b338273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016119049190613b88565b602060405180830381865afa158015611921573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611945919061488a565b8373ffffffffffffffffffffffffffffffffffffffff166126be9092919063ffffffff16565b50565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060006119a5836116b9565b905060008167ffffffffffffffff8111156119c3576119c2613d91565b5b6040519080825280602002602001820160405280156119f15781602001602082028036833780820191505090505b50905060005b82811015611a3b57611a098582610cd8565b828281518110611a1c57611a1b6146b6565b5b6020026020010181815250508080611a3390614582565b9150506119f7565b508092505050919050565b606060018054611a559061423e565b80601f0160208091040260200160405190810160405280929190818152602001828054611a819061423e565b8015611ace5780601f10611aa357610100808354040283529160200191611ace565b820191906000526020600020905b815481529060010190602001808311611ab157829003601f168201915b5050505050905090565b611aea611ae361206d565b8383612744565b5050565b611aff611af961206d565b836121ac565b611b3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3590614405565b60405180910390fd5b611b4a848484846128b0565b50505050565b611b5861212e565b80601760006101000a81548160ff02191690831515021790555050565b60128054611b829061423e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bae9061423e565b8015611bfb5780601f10611bd057610100808354040283529160200191611bfb565b820191906000526020600020905b815481529060010190602001808311611bde57829003601f168201915b505050505081565b6060611c0e8261290c565b611c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4490614929565b60405180910390fd5b6000611c5761294d565b90506000815111611c775760405180602001604052806000815250611ca5565b80611c81846129df565b6012604051602001611c9593929190614a19565b6040516020818303038152906040525b915050919050565b60155481565b611cbb61212e565b8060129080519060200190611cd192919061388d565b5050565b60135481565b60106020528060005260406000206000915054906101000a900460ff1681565b60145481565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611dc761212e565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16611e2761196e565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611ffd57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061200d575061200c82612aad565b5b9050919050565b600081600001549050919050565b61202b8161290c565b61206a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161206190614731565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166120e8836115a5565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61213661206d565b73ffffffffffffffffffffffffffffffffffffffff1661215461196e565b73ffffffffffffffffffffffffffffffffffffffff16146121aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121a190614a96565b60405180910390fd5b565b6000806121b8836115a5565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806121fa57506121f98185611d2b565b5b8061223857508373ffffffffffffffffffffffffffffffffffffffff166122208461093d565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612261826115a5565b73ffffffffffffffffffffffffffffffffffffffff16146122b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122ae90614b28565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612326576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231d90614bba565b60405180910390fd5b6123338383836001612b17565b8273ffffffffffffffffffffffffffffffffffffffff16612353826115a5565b73ffffffffffffffffffffffffffffffffffffffff16146123a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a090614b28565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46125358383836001612c75565b505050565b6002600c540361257f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257690614c26565b60405180910390fd5b6002600c81905550565b6125a3828260405180602001604052806000815250612c7b565b5050565b6001816000016000828254019250508190555050565b612640846323b872dd60e01b8585856040516024016125de93929190614c46565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612cd6565b50505050565b6001600c81905550565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600b60006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556126bb81611e6c565b50565b61273f8363a9059cbb60e01b84846040516024016126dd929190614c7d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612cd6565b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036127b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a990614cf2565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516128a391906139e4565b60405180910390a3505050565b6128bb848484612241565b6128c784848484612d9d565b612906576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128fd90614d84565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff1661292e83612650565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60606011805461295c9061423e565b80601f01602080910402602001604051908101604052809291908181526020018280546129889061423e565b80156129d55780601f106129aa576101008083540402835291602001916129d5565b820191906000526020600020905b8154815290600101906020018083116129b857829003601f168201915b5050505050905090565b6060600060016129ee84612f24565b01905060008167ffffffffffffffff811115612a0d57612a0c613d91565b5b6040519080825280601f01601f191660200182016040528015612a3f5781602001600182028036833780820191505090505b509050600082602001820190505b600115612aa2578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612a9657612a95614da4565b5b04945060008503612a4d575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612b2384848484613077565b6001811115612b67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b5e90614e45565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612bae57612ba98161319d565b612bed565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612bec57612beb85826131e6565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612c2f57612c2a81613353565b612c6e565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612c6d57612c6c8482613424565b5b5b5050505050565b50505050565b612c8583836134a3565b612c926000848484612d9d565b612cd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cc890614d84565b60405180910390fd5b505050565b6000612d38826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166136c09092919063ffffffff16565b9050600081511115612d985780806020019051810190612d589190614e7a565b612d97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d8e90614f19565b60405180910390fd5b5b505050565b6000612dbe8473ffffffffffffffffffffffffffffffffffffffff166136d8565b15612f17578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612de761206d565b8786866040518563ffffffff1660e01b8152600401612e099493929190614f8e565b6020604051808303816000875af1925050508015612e4557506040513d601f19601f82011682018060405250810190612e429190614fef565b60015b612ec7573d8060008114612e75576040519150601f19603f3d011682016040523d82523d6000602084013e612e7a565b606091505b506000815103612ebf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eb690614d84565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612f1c565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612f82577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612f7857612f77614da4565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612fbf576d04ee2d6d415b85acef81000000008381612fb557612fb4614da4565b5b0492506020810190505b662386f26fc100008310612fee57662386f26fc100008381612fe457612fe3614da4565b5b0492506010810190505b6305f5e1008310613017576305f5e100838161300d5761300c614da4565b5b0492506008810190505b612710831061303c57612710838161303257613031614da4565b5b0492506004810190505b6064831061305f576064838161305557613054614da4565b5b0492506002810190505b600a831061306e576001810190505b80915050919050565b600181111561319757600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461310b5780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613103919061501c565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146131965780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461318e919061452c565b925050819055505b5b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016131f3846116b9565b6131fd919061501c565b90506000600760008481526020019081526020016000205490508181146132e2576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050613367919061501c565b9050600060096000848152602001908152602001600020549050600060088381548110613397576133966146b6565b5b9060005260206000200154905080600883815481106133b9576133b86146b6565b5b90600052602060002001819055508160096000838152602001908152602001600020819055506009600085815260200190815260200160002060009055600880548061340857613407615050565b5b6001900381819060005260206000200160009055905550505050565b600061342f836116b9565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613512576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613509906150cb565b60405180910390fd5b61351b8161290c565b1561355b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161355290615137565b60405180910390fd5b613569600083836001612b17565b6135728161290c565b156135b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135a990615137565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46136bc600083836001612c75565b5050565b60606136cf84846000856136fb565b90509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606082471015613740576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613737906151c9565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613769919061521a565b60006040518083038185875af1925050503d80600081146137a6576040519150601f19603f3d011682016040523d82523d6000602084013e6137ab565b606091505b50915091506137bc878383876137c8565b92505050949350505050565b6060831561382a576000835103613822576137e2856136d8565b613821576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138189061527d565b60405180910390fd5b5b829050613835565b613834838361383d565b5b949350505050565b6000825111156138505781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138849190613acc565b60405180910390fd5b8280546138999061423e565b90600052602060002090601f0160209004810192826138bb5760008555613902565b82601f106138d457805160ff1916838001178555613902565b82800160010185558215613902579182015b828111156139015782518255916020019190600101906138e6565b5b50905061390f9190613913565b5090565b5b8082111561392c576000816000905550600101613914565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61397981613944565b811461398457600080fd5b50565b60008135905061399681613970565b92915050565b6000602082840312156139b2576139b161393a565b5b60006139c084828501613987565b91505092915050565b60008115159050919050565b6139de816139c9565b82525050565b60006020820190506139f960008301846139d5565b92915050565b6000819050919050565b613a12816139ff565b82525050565b6000602082019050613a2d6000830184613a09565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613a6d578082015181840152602081019050613a52565b83811115613a7c576000848401525b50505050565b6000601f19601f8301169050919050565b6000613a9e82613a33565b613aa88185613a3e565b9350613ab8818560208601613a4f565b613ac181613a82565b840191505092915050565b60006020820190508181036000830152613ae68184613a93565b905092915050565b613af7816139ff565b8114613b0257600080fd5b50565b600081359050613b1481613aee565b92915050565b600060208284031215613b3057613b2f61393a565b5b6000613b3e84828501613b05565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613b7282613b47565b9050919050565b613b8281613b67565b82525050565b6000602082019050613b9d6000830184613b79565b92915050565b613bac81613b67565b8114613bb757600080fd5b50565b600081359050613bc981613ba3565b92915050565b60008060408385031215613be657613be561393a565b5b6000613bf485828601613bba565b9250506020613c0585828601613b05565b9150509250929050565b6000613c1a82613b67565b9050919050565b613c2a81613c0f565b8114613c3557600080fd5b50565b600081359050613c4781613c21565b92915050565b600060208284031215613c6357613c6261393a565b5b6000613c7184828501613c38565b91505092915050565b600080600060608486031215613c9357613c9261393a565b5b6000613ca186828701613bba565b9350506020613cb286828701613bba565b9250506040613cc386828701613b05565b9150509250925092565b6000819050919050565b6000613cf2613ced613ce884613b47565b613ccd565b613b47565b9050919050565b6000613d0482613cd7565b9050919050565b6000613d1682613cf9565b9050919050565b613d2681613d0b565b82525050565b6000602082019050613d416000830184613d1d565b92915050565b60008060408385031215613d5e57613d5d61393a565b5b6000613d6c85828601613c38565b9250506020613d7d85828601613b05565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613dc982613a82565b810181811067ffffffffffffffff82111715613de857613de7613d91565b5b80604052505050565b6000613dfb613930565b9050613e078282613dc0565b919050565b600067ffffffffffffffff821115613e2757613e26613d91565b5b613e3082613a82565b9050602081019050919050565b82818337600083830152505050565b6000613e5f613e5a84613e0c565b613df1565b905082815260208101848484011115613e7b57613e7a613d8c565b5b613e86848285613e3d565b509392505050565b600082601f830112613ea357613ea2613d87565b5b8135613eb3848260208601613e4c565b91505092915050565b600060208284031215613ed257613ed161393a565b5b600082013567ffffffffffffffff811115613ef057613eef61393f565b5b613efc84828501613e8e565b91505092915050565b600060208284031215613f1b57613f1a61393a565b5b6000613f2984828501613bba565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613f67816139ff565b82525050565b6000613f798383613f5e565b60208301905092915050565b6000602082019050919050565b6000613f9d82613f32565b613fa78185613f3d565b9350613fb283613f4e565b8060005b83811015613fe3578151613fca8882613f6d565b9750613fd583613f85565b925050600181019050613fb6565b5085935050505092915050565b6000602082019050818103600083015261400a8184613f92565b905092915050565b61401b816139c9565b811461402657600080fd5b50565b60008135905061403881614012565b92915050565b600080604083850312156140555761405461393a565b5b600061406385828601613bba565b925050602061407485828601614029565b9150509250929050565b600067ffffffffffffffff82111561409957614098613d91565b5b6140a282613a82565b9050602081019050919050565b60006140c26140bd8461407e565b613df1565b9050828152602081018484840111156140de576140dd613d8c565b5b6140e9848285613e3d565b509392505050565b600082601f83011261410657614105613d87565b5b81356141168482602086016140af565b91505092915050565b600080600080608085870312156141395761413861393a565b5b600061414787828801613bba565b945050602061415887828801613bba565b935050604061416987828801613b05565b925050606085013567ffffffffffffffff81111561418a5761418961393f565b5b614196878288016140f1565b91505092959194509250565b6000602082840312156141b8576141b761393a565b5b60006141c684828501614029565b91505092915050565b600080604083850312156141e6576141e561393a565b5b60006141f485828601613bba565b925050602061420585828601613bba565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061425657607f821691505b6020821081036142695761426861420f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006142cb602183613a3e565b91506142d68261426f565b604082019050919050565b600060208201905081810360008301526142fa816142be565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b600061435d603d83613a3e565b915061436882614301565b604082019050919050565b6000602082019050818103600083015261438c81614350565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b60006143ef602d83613a3e565b91506143fa82614393565b604082019050919050565b6000602082019050818103600083015261441e816143e2565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000614481602b83613a3e565b915061448c82614425565b604082019050919050565b600060208201905081810360008301526144b081614474565b9050919050565b600081905092915050565b50565b60006144d26000836144b7565b91506144dd826144c2565b600082019050919050565b60006144f3826144c5565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614537826139ff565b9150614542836139ff565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614577576145766144fd565b5b828201905092915050565b600061458d826139ff565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145bf576145be6144fd565b5b600182019050919050565b60006145d5826139ff565b91506145e0836139ff565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614619576146186144fd565b5b828202905092915050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614680602c83613a3e565b915061468b82614624565b604082019050919050565b600060208201905081810360008301526146af81614673565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b600061471b601883613a3e565b9150614726826146e5565b602082019050919050565b6000602082019050818103600083015261474a8161470e565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006147ad602983613a3e565b91506147b882614751565b604082019050919050565b600060208201905081810360008301526147dc816147a0565b9050919050565b7f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060008201527f6e6577206f776e65720000000000000000000000000000000000000000000000602082015250565b600061483f602983613a3e565b915061484a826147e3565b604082019050919050565b6000602082019050818103600083015261486e81614832565b9050919050565b60008151905061488481613aee565b92915050565b6000602082840312156148a05761489f61393a565b5b60006148ae84828501614875565b91505092915050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614913602f83613a3e565b915061491e826148b7565b604082019050919050565b6000602082019050818103600083015261494281614906565b9050919050565b600081905092915050565b600061495f82613a33565b6149698185614949565b9350614979818560208601613a4f565b80840191505092915050565b60008190508160005260206000209050919050565b600081546149a78161423e565b6149b18186614949565b945060018216600081146149cc57600181146149dd57614a10565b60ff19831686528186019350614a10565b6149e685614985565b60005b83811015614a08578154818901526001820191506020810190506149e9565b838801955050505b50505092915050565b6000614a258286614954565b9150614a318285614954565b9150614a3d828461499a565b9150819050949350505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614a80602083613a3e565b9150614a8b82614a4a565b602082019050919050565b60006020820190508181036000830152614aaf81614a73565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000614b12602583613a3e565b9150614b1d82614ab6565b604082019050919050565b60006020820190508181036000830152614b4181614b05565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614ba4602483613a3e565b9150614baf82614b48565b604082019050919050565b60006020820190508181036000830152614bd381614b97565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614c10601f83613a3e565b9150614c1b82614bda565b602082019050919050565b60006020820190508181036000830152614c3f81614c03565b9050919050565b6000606082019050614c5b6000830186613b79565b614c686020830185613b79565b614c756040830184613a09565b949350505050565b6000604082019050614c926000830185613b79565b614c9f6020830184613a09565b9392505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614cdc601983613a3e565b9150614ce782614ca6565b602082019050919050565b60006020820190508181036000830152614d0b81614ccf565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000614d6e603283613a3e565b9150614d7982614d12565b604082019050919050565b60006020820190508181036000830152614d9d81614d61565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b6000614e2f603583613a3e565b9150614e3a82614dd3565b604082019050919050565b60006020820190508181036000830152614e5e81614e22565b9050919050565b600081519050614e7481614012565b92915050565b600060208284031215614e9057614e8f61393a565b5b6000614e9e84828501614e65565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614f03602a83613a3e565b9150614f0e82614ea7565b604082019050919050565b60006020820190508181036000830152614f3281614ef6565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614f6082614f39565b614f6a8185614f44565b9350614f7a818560208601613a4f565b614f8381613a82565b840191505092915050565b6000608082019050614fa36000830187613b79565b614fb06020830186613b79565b614fbd6040830185613a09565b8181036060830152614fcf8184614f55565b905095945050505050565b600081519050614fe981613970565b92915050565b6000602082840312156150055761500461393a565b5b600061501384828501614fda565b91505092915050565b6000615027826139ff565b9150615032836139ff565b925082821015615045576150446144fd565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006150b5602083613a3e565b91506150c08261507f565b602082019050919050565b600060208201905081810360008301526150e4816150a8565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615121601c83613a3e565b915061512c826150eb565b602082019050919050565b6000602082019050818103600083015261515081615114565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006151b3602683613a3e565b91506151be82615157565b604082019050919050565b600060208201905081810360008301526151e2816151a6565b9050919050565b60006151f482614f39565b6151fe81856144b7565b935061520e818560208601613a4f565b80840191505092915050565b600061522682846151e9565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615267601d83613a3e565b915061527282615231565b602082019050919050565b600060208201905081810360008301526152968161525a565b905091905056fea2646970667358221220cfc07caf5a309a85f04fef8f0a446964baae1b89008cd0ee246d5d5e76efbb2a64736f6c634300080e003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000000a43474c616d705061737300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000443474c50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034697066732f516d6144673269543455634d767a53797a426d6942666543587a33643365536a6e4771654574465161436f4561532f000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061027f5760003560e01c80636c0360eb1161015c578063b88d4fde116100ce578063dacee34711610087578063dacee3471461074a578063daf9c21014610768578063e136f65f14610798578063e30c3978146107b6578063e985e9c5146107d4578063f2fde38b146108045761027f565b8063b88d4fde1461068a578063bedb86fb146106a6578063c6682862146106c2578063c87b56dd146106e0578063d5abeb0114610710578063da3ef23f1461072e5761027f565b80637f6e36d4116101205780637f6e36d4146105ca57806389476069146105e65780638da5cb5b146106025780639253ed041461062057806395d89b4114610650578063a22cb4651461066e5761027f565b80636c0360eb1461054c57806370a082311461056a578063715018a61461059a57806379ba5097146105a45780637f00c7a6146105ae5761027f565b80633410fc44116101f557806342842e0e116101b957806342842e0e1461047a5780634782e407146104965780634f6ccce7146104b257806355f804b3146104e25780635c975abb146104fe5780636352211e1461051c5761027f565b80633410fc44146103fe57806339a7919f1461041a5780633ccfd60b146104365780633e413bee1461044057806340c10f191461045e5761027f565b806318160ddd1161024757806318160ddd1461033c5780631ff415d91461035a578063239c70ae1461037657806323b872dd146103945780632f48ab7d146103b05780632f745c59146103ce5761027f565b806301ffc9a71461028457806306661abd146102b457806306fdde03146102d2578063081812fc146102f0578063095ea7b314610320575b600080fd5b61029e6004803603810190610299919061399c565b610820565b6040516102ab91906139e4565b60405180910390f35b6102bc61089a565b6040516102c99190613a18565b60405180910390f35b6102da6108ab565b6040516102e79190613acc565b60405180910390f35b61030a60048036038101906103059190613b1a565b61093d565b6040516103179190613b88565b60405180910390f35b61033a60048036038101906103359190613bcf565b610983565b005b610344610a9a565b6040516103519190613a18565b60405180910390f35b610374600480360381019061036f9190613c4d565b610aa7565b005b61037e610c4c565b60405161038b9190613a18565b60405180910390f35b6103ae60048036038101906103a99190613c7a565b610c52565b005b6103b8610cb2565b6040516103c59190613d2c565b60405180910390f35b6103e860048036038101906103e39190613bcf565b610cd8565b6040516103f59190613a18565b60405180910390f35b61041860048036038101906104139190613b1a565b610d7d565b005b610434600480360381019061042f9190613b1a565b610d8f565b005b61043e610da1565b005b610448610e29565b6040516104559190613d2c565b60405180910390f35b61047860048036038101906104739190613d47565b610e4f565b005b610494600480360381019061048f9190613c7a565b61133a565b005b6104b060048036038101906104ab9190613c4d565b61135a565b005b6104cc60048036038101906104c79190613b1a565b6114ff565b6040516104d99190613a18565b60405180910390f35b6104fc60048036038101906104f79190613ebc565b611570565b005b610506611592565b60405161051391906139e4565b60405180910390f35b61053660048036038101906105319190613b1a565b6115a5565b6040516105439190613b88565b60405180910390f35b61055461162b565b6040516105619190613acc565b60405180910390f35b610584600480360381019061057f9190613f05565b6116b9565b6040516105919190613a18565b60405180910390f35b6105a2611770565b005b6105ac611784565b005b6105c860048036038101906105c39190613b1a565b611811565b005b6105e460048036038101906105df9190613b1a565b611823565b005b61060060048036038101906105fb9190613c4d565b611835565b005b61060a61196e565b6040516106179190613b88565b60405180910390f35b61063a60048036038101906106359190613f05565b611998565b6040516106479190613ff0565b60405180910390f35b610658611a46565b6040516106659190613acc565b60405180910390f35b6106886004803603810190610683919061403e565b611ad8565b005b6106a4600480360381019061069f919061411f565b611aee565b005b6106c060048036038101906106bb91906141a2565b611b50565b005b6106ca611b75565b6040516106d79190613acc565b60405180910390f35b6106fa60048036038101906106f59190613b1a565b611c03565b6040516107079190613acc565b60405180910390f35b610718611cad565b6040516107259190613a18565b60405180910390f35b61074860048036038101906107439190613ebc565b611cb3565b005b610752611cd5565b60405161075f9190613a18565b60405180910390f35b610782600480360381019061077d9190613c4d565b611cdb565b60405161078f91906139e4565b60405180910390f35b6107a0611cfb565b6040516107ad9190613a18565b60405180910390f35b6107be611d01565b6040516107cb9190613b88565b60405180910390f35b6107ee60048036038101906107e991906141cf565b611d2b565b6040516107fb91906139e4565b60405180910390f35b61081e60048036038101906108199190613f05565b611dbf565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610893575061089282611f32565b5b9050919050565b60006108a6600d612014565b905090565b6060600080546108ba9061423e565b80601f01602080910402602001604051908101604052809291908181526020018280546108e69061423e565b80156109335780601f1061090857610100808354040283529160200191610933565b820191906000526020600020905b81548152906001019060200180831161091657829003601f168201915b5050505050905090565b600061094882612022565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061098e826115a5565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f5906142e1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a1d61206d565b73ffffffffffffffffffffffffffffffffffffffff161480610a4c5750610a4b81610a4661206d565b611d2b565b5b610a8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8290614373565b60405180910390fd5b610a958383612075565b505050565b6000600880549050905090565b610aaf61212e565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b36576040517f9957f83800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060106000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60165481565b610c63610c5d61206d565b826121ac565b610ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9990614405565b60405180910390fd5b610cad838383612241565b505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610ce3836116b9565b8210610d24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1b90614497565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610d8561212e565b8060148190555050565b610d9761212e565b8060158190555050565b610da961212e565b6000610db361196e565b73ffffffffffffffffffffffffffffffffffffffff1647604051610dd6906144e8565b60006040518083038185875af1925050503d8060008114610e13576040519150601f19603f3d011682016040523d82523d6000602084013e610e18565b606091505b5050905080610e2657600080fd5b50565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610e5761253a565b601760009054906101000a900460ff1615610e9e576040517f58fc318200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610f47576040517f9957f83800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60011515601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514610fd1576040517fa0f3feea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654811180610fe15750600081145b15611018576040517ffae9feb900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60165481611025336116b9565b61102f919061452c565b1115611067576040517ffae9feb900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611071610a9a565b90506015548282611082919061452c565b106110b9576040517fc30436e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600190505b8281116110f9576110dc3382846110d7919061452c565b612589565b6110e6600d6125a7565b80806110f190614582565b9150506110c0565b5061110261196e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132d57600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112305760008260145461119991906145ca565b90506111ea333083600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166125bd909392919063ffffffff16565b803373ffffffffffffffffffffffffffffffffffffffff167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe60405160405180910390a3505b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361132c5760008260135461129591906145ca565b90506112e6333083600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166125bd909392919063ffffffff16565b803373ffffffffffffffffffffffffffffffffffffffff167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe60405160405180910390a3505b5b50611336612646565b5050565b61135583838360405180602001604052806000815250611aee565b505050565b61136261212e565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113e9576040517f9957f83800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060106000600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611509610a9a565b821061154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154190614696565b60405180910390fd5b6008828154811061155e5761155d6146b6565b5b90600052602060002001549050919050565b61157861212e565b806011908051906020019061158e92919061388d565b5050565b601760009054906101000a900460ff1681565b6000806115b183612650565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611622576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161990614731565b60405180910390fd5b80915050919050565b601180546116389061423e565b80601f01602080910402602001604051908101604052809291908181526020018280546116649061423e565b80156116b15780601f10611686576101008083540402835291602001916116b1565b820191906000526020600020905b81548152906001019060200180831161169457829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611729576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611720906147c3565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61177861212e565b611782600061268d565b565b600061178e61206d565b90508073ffffffffffffffffffffffffffffffffffffffff166117af611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611805576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117fc90614855565b60405180910390fd5b61180e8161268d565b50565b61181961212e565b8060168190555050565b61182b61212e565b8060138190555050565b61183d61212e565b60011515601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146118c7576040517fa0f3feea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61196b338273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016119049190613b88565b602060405180830381865afa158015611921573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611945919061488a565b8373ffffffffffffffffffffffffffffffffffffffff166126be9092919063ffffffff16565b50565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060006119a5836116b9565b905060008167ffffffffffffffff8111156119c3576119c2613d91565b5b6040519080825280602002602001820160405280156119f15781602001602082028036833780820191505090505b50905060005b82811015611a3b57611a098582610cd8565b828281518110611a1c57611a1b6146b6565b5b6020026020010181815250508080611a3390614582565b9150506119f7565b508092505050919050565b606060018054611a559061423e565b80601f0160208091040260200160405190810160405280929190818152602001828054611a819061423e565b8015611ace5780601f10611aa357610100808354040283529160200191611ace565b820191906000526020600020905b815481529060010190602001808311611ab157829003601f168201915b5050505050905090565b611aea611ae361206d565b8383612744565b5050565b611aff611af961206d565b836121ac565b611b3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3590614405565b60405180910390fd5b611b4a848484846128b0565b50505050565b611b5861212e565b80601760006101000a81548160ff02191690831515021790555050565b60128054611b829061423e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bae9061423e565b8015611bfb5780601f10611bd057610100808354040283529160200191611bfb565b820191906000526020600020905b815481529060010190602001808311611bde57829003601f168201915b505050505081565b6060611c0e8261290c565b611c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4490614929565b60405180910390fd5b6000611c5761294d565b90506000815111611c775760405180602001604052806000815250611ca5565b80611c81846129df565b6012604051602001611c9593929190614a19565b6040516020818303038152906040525b915050919050565b60155481565b611cbb61212e565b8060129080519060200190611cd192919061388d565b5050565b60135481565b60106020528060005260406000206000915054906101000a900460ff1681565b60145481565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611dc761212e565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16611e2761196e565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611ffd57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061200d575061200c82612aad565b5b9050919050565b600081600001549050919050565b61202b8161290c565b61206a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161206190614731565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166120e8836115a5565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61213661206d565b73ffffffffffffffffffffffffffffffffffffffff1661215461196e565b73ffffffffffffffffffffffffffffffffffffffff16146121aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121a190614a96565b60405180910390fd5b565b6000806121b8836115a5565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806121fa57506121f98185611d2b565b5b8061223857508373ffffffffffffffffffffffffffffffffffffffff166122208461093d565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612261826115a5565b73ffffffffffffffffffffffffffffffffffffffff16146122b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122ae90614b28565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612326576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231d90614bba565b60405180910390fd5b6123338383836001612b17565b8273ffffffffffffffffffffffffffffffffffffffff16612353826115a5565b73ffffffffffffffffffffffffffffffffffffffff16146123a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a090614b28565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46125358383836001612c75565b505050565b6002600c540361257f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257690614c26565b60405180910390fd5b6002600c81905550565b6125a3828260405180602001604052806000815250612c7b565b5050565b6001816000016000828254019250508190555050565b612640846323b872dd60e01b8585856040516024016125de93929190614c46565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612cd6565b50505050565b6001600c81905550565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600b60006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556126bb81611e6c565b50565b61273f8363a9059cbb60e01b84846040516024016126dd929190614c7d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612cd6565b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036127b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a990614cf2565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516128a391906139e4565b60405180910390a3505050565b6128bb848484612241565b6128c784848484612d9d565b612906576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128fd90614d84565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff1661292e83612650565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60606011805461295c9061423e565b80601f01602080910402602001604051908101604052809291908181526020018280546129889061423e565b80156129d55780601f106129aa576101008083540402835291602001916129d5565b820191906000526020600020905b8154815290600101906020018083116129b857829003601f168201915b5050505050905090565b6060600060016129ee84612f24565b01905060008167ffffffffffffffff811115612a0d57612a0c613d91565b5b6040519080825280601f01601f191660200182016040528015612a3f5781602001600182028036833780820191505090505b509050600082602001820190505b600115612aa2578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612a9657612a95614da4565b5b04945060008503612a4d575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612b2384848484613077565b6001811115612b67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b5e90614e45565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612bae57612ba98161319d565b612bed565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612bec57612beb85826131e6565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612c2f57612c2a81613353565b612c6e565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612c6d57612c6c8482613424565b5b5b5050505050565b50505050565b612c8583836134a3565b612c926000848484612d9d565b612cd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cc890614d84565b60405180910390fd5b505050565b6000612d38826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166136c09092919063ffffffff16565b9050600081511115612d985780806020019051810190612d589190614e7a565b612d97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d8e90614f19565b60405180910390fd5b5b505050565b6000612dbe8473ffffffffffffffffffffffffffffffffffffffff166136d8565b15612f17578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612de761206d565b8786866040518563ffffffff1660e01b8152600401612e099493929190614f8e565b6020604051808303816000875af1925050508015612e4557506040513d601f19601f82011682018060405250810190612e429190614fef565b60015b612ec7573d8060008114612e75576040519150601f19603f3d011682016040523d82523d6000602084013e612e7a565b606091505b506000815103612ebf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eb690614d84565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612f1c565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612f82577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612f7857612f77614da4565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612fbf576d04ee2d6d415b85acef81000000008381612fb557612fb4614da4565b5b0492506020810190505b662386f26fc100008310612fee57662386f26fc100008381612fe457612fe3614da4565b5b0492506010810190505b6305f5e1008310613017576305f5e100838161300d5761300c614da4565b5b0492506008810190505b612710831061303c57612710838161303257613031614da4565b5b0492506004810190505b6064831061305f576064838161305557613054614da4565b5b0492506002810190505b600a831061306e576001810190505b80915050919050565b600181111561319757600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461310b5780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613103919061501c565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146131965780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461318e919061452c565b925050819055505b5b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016131f3846116b9565b6131fd919061501c565b90506000600760008481526020019081526020016000205490508181146132e2576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050613367919061501c565b9050600060096000848152602001908152602001600020549050600060088381548110613397576133966146b6565b5b9060005260206000200154905080600883815481106133b9576133b86146b6565b5b90600052602060002001819055508160096000838152602001908152602001600020819055506009600085815260200190815260200160002060009055600880548061340857613407615050565b5b6001900381819060005260206000200160009055905550505050565b600061342f836116b9565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613512576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613509906150cb565b60405180910390fd5b61351b8161290c565b1561355b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161355290615137565b60405180910390fd5b613569600083836001612b17565b6135728161290c565b156135b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135a990615137565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46136bc600083836001612c75565b5050565b60606136cf84846000856136fb565b90509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606082471015613740576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613737906151c9565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613769919061521a565b60006040518083038185875af1925050503d80600081146137a6576040519150601f19603f3d011682016040523d82523d6000602084013e6137ab565b606091505b50915091506137bc878383876137c8565b92505050949350505050565b6060831561382a576000835103613822576137e2856136d8565b613821576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138189061527d565b60405180910390fd5b5b829050613835565b613834838361383d565b5b949350505050565b6000825111156138505781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138849190613acc565b60405180910390fd5b8280546138999061423e565b90600052602060002090601f0160209004810192826138bb5760008555613902565b82601f106138d457805160ff1916838001178555613902565b82800160010185558215613902579182015b828111156139015782518255916020019190600101906138e6565b5b50905061390f9190613913565b5090565b5b8082111561392c576000816000905550600101613914565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61397981613944565b811461398457600080fd5b50565b60008135905061399681613970565b92915050565b6000602082840312156139b2576139b161393a565b5b60006139c084828501613987565b91505092915050565b60008115159050919050565b6139de816139c9565b82525050565b60006020820190506139f960008301846139d5565b92915050565b6000819050919050565b613a12816139ff565b82525050565b6000602082019050613a2d6000830184613a09565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613a6d578082015181840152602081019050613a52565b83811115613a7c576000848401525b50505050565b6000601f19601f8301169050919050565b6000613a9e82613a33565b613aa88185613a3e565b9350613ab8818560208601613a4f565b613ac181613a82565b840191505092915050565b60006020820190508181036000830152613ae68184613a93565b905092915050565b613af7816139ff565b8114613b0257600080fd5b50565b600081359050613b1481613aee565b92915050565b600060208284031215613b3057613b2f61393a565b5b6000613b3e84828501613b05565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613b7282613b47565b9050919050565b613b8281613b67565b82525050565b6000602082019050613b9d6000830184613b79565b92915050565b613bac81613b67565b8114613bb757600080fd5b50565b600081359050613bc981613ba3565b92915050565b60008060408385031215613be657613be561393a565b5b6000613bf485828601613bba565b9250506020613c0585828601613b05565b9150509250929050565b6000613c1a82613b67565b9050919050565b613c2a81613c0f565b8114613c3557600080fd5b50565b600081359050613c4781613c21565b92915050565b600060208284031215613c6357613c6261393a565b5b6000613c7184828501613c38565b91505092915050565b600080600060608486031215613c9357613c9261393a565b5b6000613ca186828701613bba565b9350506020613cb286828701613bba565b9250506040613cc386828701613b05565b9150509250925092565b6000819050919050565b6000613cf2613ced613ce884613b47565b613ccd565b613b47565b9050919050565b6000613d0482613cd7565b9050919050565b6000613d1682613cf9565b9050919050565b613d2681613d0b565b82525050565b6000602082019050613d416000830184613d1d565b92915050565b60008060408385031215613d5e57613d5d61393a565b5b6000613d6c85828601613c38565b9250506020613d7d85828601613b05565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613dc982613a82565b810181811067ffffffffffffffff82111715613de857613de7613d91565b5b80604052505050565b6000613dfb613930565b9050613e078282613dc0565b919050565b600067ffffffffffffffff821115613e2757613e26613d91565b5b613e3082613a82565b9050602081019050919050565b82818337600083830152505050565b6000613e5f613e5a84613e0c565b613df1565b905082815260208101848484011115613e7b57613e7a613d8c565b5b613e86848285613e3d565b509392505050565b600082601f830112613ea357613ea2613d87565b5b8135613eb3848260208601613e4c565b91505092915050565b600060208284031215613ed257613ed161393a565b5b600082013567ffffffffffffffff811115613ef057613eef61393f565b5b613efc84828501613e8e565b91505092915050565b600060208284031215613f1b57613f1a61393a565b5b6000613f2984828501613bba565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613f67816139ff565b82525050565b6000613f798383613f5e565b60208301905092915050565b6000602082019050919050565b6000613f9d82613f32565b613fa78185613f3d565b9350613fb283613f4e565b8060005b83811015613fe3578151613fca8882613f6d565b9750613fd583613f85565b925050600181019050613fb6565b5085935050505092915050565b6000602082019050818103600083015261400a8184613f92565b905092915050565b61401b816139c9565b811461402657600080fd5b50565b60008135905061403881614012565b92915050565b600080604083850312156140555761405461393a565b5b600061406385828601613bba565b925050602061407485828601614029565b9150509250929050565b600067ffffffffffffffff82111561409957614098613d91565b5b6140a282613a82565b9050602081019050919050565b60006140c26140bd8461407e565b613df1565b9050828152602081018484840111156140de576140dd613d8c565b5b6140e9848285613e3d565b509392505050565b600082601f83011261410657614105613d87565b5b81356141168482602086016140af565b91505092915050565b600080600080608085870312156141395761413861393a565b5b600061414787828801613bba565b945050602061415887828801613bba565b935050604061416987828801613b05565b925050606085013567ffffffffffffffff81111561418a5761418961393f565b5b614196878288016140f1565b91505092959194509250565b6000602082840312156141b8576141b761393a565b5b60006141c684828501614029565b91505092915050565b600080604083850312156141e6576141e561393a565b5b60006141f485828601613bba565b925050602061420585828601613bba565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061425657607f821691505b6020821081036142695761426861420f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006142cb602183613a3e565b91506142d68261426f565b604082019050919050565b600060208201905081810360008301526142fa816142be565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b600061435d603d83613a3e565b915061436882614301565b604082019050919050565b6000602082019050818103600083015261438c81614350565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b60006143ef602d83613a3e565b91506143fa82614393565b604082019050919050565b6000602082019050818103600083015261441e816143e2565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000614481602b83613a3e565b915061448c82614425565b604082019050919050565b600060208201905081810360008301526144b081614474565b9050919050565b600081905092915050565b50565b60006144d26000836144b7565b91506144dd826144c2565b600082019050919050565b60006144f3826144c5565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614537826139ff565b9150614542836139ff565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614577576145766144fd565b5b828201905092915050565b600061458d826139ff565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145bf576145be6144fd565b5b600182019050919050565b60006145d5826139ff565b91506145e0836139ff565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614619576146186144fd565b5b828202905092915050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614680602c83613a3e565b915061468b82614624565b604082019050919050565b600060208201905081810360008301526146af81614673565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b600061471b601883613a3e565b9150614726826146e5565b602082019050919050565b6000602082019050818103600083015261474a8161470e565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006147ad602983613a3e565b91506147b882614751565b604082019050919050565b600060208201905081810360008301526147dc816147a0565b9050919050565b7f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060008201527f6e6577206f776e65720000000000000000000000000000000000000000000000602082015250565b600061483f602983613a3e565b915061484a826147e3565b604082019050919050565b6000602082019050818103600083015261486e81614832565b9050919050565b60008151905061488481613aee565b92915050565b6000602082840312156148a05761489f61393a565b5b60006148ae84828501614875565b91505092915050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614913602f83613a3e565b915061491e826148b7565b604082019050919050565b6000602082019050818103600083015261494281614906565b9050919050565b600081905092915050565b600061495f82613a33565b6149698185614949565b9350614979818560208601613a4f565b80840191505092915050565b60008190508160005260206000209050919050565b600081546149a78161423e565b6149b18186614949565b945060018216600081146149cc57600181146149dd57614a10565b60ff19831686528186019350614a10565b6149e685614985565b60005b83811015614a08578154818901526001820191506020810190506149e9565b838801955050505b50505092915050565b6000614a258286614954565b9150614a318285614954565b9150614a3d828461499a565b9150819050949350505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614a80602083613a3e565b9150614a8b82614a4a565b602082019050919050565b60006020820190508181036000830152614aaf81614a73565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000614b12602583613a3e565b9150614b1d82614ab6565b604082019050919050565b60006020820190508181036000830152614b4181614b05565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614ba4602483613a3e565b9150614baf82614b48565b604082019050919050565b60006020820190508181036000830152614bd381614b97565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614c10601f83613a3e565b9150614c1b82614bda565b602082019050919050565b60006020820190508181036000830152614c3f81614c03565b9050919050565b6000606082019050614c5b6000830186613b79565b614c686020830185613b79565b614c756040830184613a09565b949350505050565b6000604082019050614c926000830185613b79565b614c9f6020830184613a09565b9392505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614cdc601983613a3e565b9150614ce782614ca6565b602082019050919050565b60006020820190508181036000830152614d0b81614ccf565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000614d6e603283613a3e565b9150614d7982614d12565b604082019050919050565b60006020820190508181036000830152614d9d81614d61565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b6000614e2f603583613a3e565b9150614e3a82614dd3565b604082019050919050565b60006020820190508181036000830152614e5e81614e22565b9050919050565b600081519050614e7481614012565b92915050565b600060208284031215614e9057614e8f61393a565b5b6000614e9e84828501614e65565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614f03602a83613a3e565b9150614f0e82614ea7565b604082019050919050565b60006020820190508181036000830152614f3281614ef6565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614f6082614f39565b614f6a8185614f44565b9350614f7a818560208601613a4f565b614f8381613a82565b840191505092915050565b6000608082019050614fa36000830187613b79565b614fb06020830186613b79565b614fbd6040830185613a09565b8181036060830152614fcf8184614f55565b905095945050505050565b600081519050614fe981613970565b92915050565b6000602082840312156150055761500461393a565b5b600061501384828501614fda565b91505092915050565b6000615027826139ff565b9150615032836139ff565b925082821015615045576150446144fd565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006150b5602083613a3e565b91506150c08261507f565b602082019050919050565b600060208201905081810360008301526150e4816150a8565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615121601c83613a3e565b915061512c826150eb565b602082019050919050565b6000602082019050818103600083015261515081615114565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006151b3602683613a3e565b91506151be82615157565b604082019050919050565b600060208201905081810360008301526151e2816151a6565b9050919050565b60006151f482614f39565b6151fe81856144b7565b935061520e818560208601613a4f565b80840191505092915050565b600061522682846151e9565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615267601d83613a3e565b915061527282615231565b602082019050919050565b600060208201905081810360008301526152968161525a565b905091905056fea2646970667358221220cfc07caf5a309a85f04fef8f0a446964baae1b89008cd0ee246d5d5e76efbb2a64736f6c634300080e0033

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

00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000000a43474c616d705061737300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000443474c50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034697066732f516d6144673269543455634d767a53797a426d6942666543587a33643365536a6e4771654574465161436f4561532f000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): CGLampPass
Arg [1] : _symbol (string): CGLP
Arg [2] : _initBaseURI (string): ipfs/QmaDg2iT4UcMvzSyzBmiBfeCXz3d3eSjnGqeEtFQaCoEaS/
Arg [3] : _usdc (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [4] : _usdt (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7

-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [3] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [4] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [6] : 43474c616d705061737300000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 43474c5000000000000000000000000000000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000034
Arg [10] : 697066732f516d6144673269543455634d767a53797a426d6942666543587a33
Arg [11] : 643365536a6e4771654574465161436f4561532f000000000000000000000000


Deployed Bytecode Sourcemap

78827:9839:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72655:224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85062:92;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56717:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58229:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57747:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73295:113;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87791:313;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80610:32;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58929:335;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80044:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72963:256;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87637:97;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87374:96;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84460:240;;;:::i;:::-;;79968:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82091:2267;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59335:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88161:313;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73485:233;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86796:104;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80705:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56427:223;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80247:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56158:207;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27630:103;;;:::i;:::-;;30236:210;;;:::i;:::-;;86589:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87532:97;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84763:248;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;26982:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85322:420;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56886:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58472:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59591:322;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87225:86;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80275:37;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85825:681;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80573:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86983:144;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80393:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80126:48;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80424:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29324:101;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58698:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29624:181;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72655:224;72757:4;72796:35;72781:50;;;:11;:50;;;;:90;;;;72835:36;72859:11;72835:23;:36::i;:::-;72781:90;72774:97;;72655:224;;;:::o;85062:92::-;85100:7;85127:19;:9;:17;:19::i;:::-;85120:26;;85062:92;:::o;56717:100::-;56771:13;56804:5;56797:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56717:100;:::o;58229:171::-;58305:7;58325:23;58340:7;58325:14;:23::i;:::-;58368:15;:24;58384:7;58368:24;;;;;;;;;;;;;;;;;;;;;58361:31;;58229:171;;;:::o;57747:416::-;57828:13;57844:23;57859:7;57844:14;:23::i;:::-;57828:39;;57892:5;57886:11;;:2;:11;;;57878:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;57986:5;57970:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;57995:37;58012:5;58019:12;:10;:12::i;:::-;57995:16;:37::i;:::-;57970:62;57948:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;58134:21;58143:2;58147:7;58134:8;:21::i;:::-;57817:346;57747:416;;:::o;73295:113::-;73356:7;73383:10;:17;;;;73376:24;;73295:113;:::o;87791:313::-;26868:13;:11;:13::i;:::-;87955:4:::1;;;;;;;;;;;87946:13;;:5;:13;;::::0;87942:47:::1;;87968:21;;;;;;;;;;;;;;87942:47;88026:5;88000:17;:23;88018:4;;;;;;;;;;;88000:23;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;88069:4;88042:17;:24;88060:5;88042:24;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;88091:5;88084:4;;:12;;;;;;;;;;;;;;;;;;87791:313:::0;:::o;80610:32::-;;;;:::o;58929:335::-;59124:41;59143:12;:10;:12::i;:::-;59157:7;59124:18;:41::i;:::-;59116:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;59228:28;59238:4;59244:2;59248:7;59228:9;:28::i;:::-;58929:335;;;:::o;80044:18::-;;;;;;;;;;;;;:::o;72963:256::-;73060:7;73096:23;73113:5;73096:16;:23::i;:::-;73088:5;:31;73080:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;73185:12;:19;73198:5;73185:19;;;;;;;;;;;;;;;:26;73205:5;73185:26;;;;;;;;;;;;73178:33;;72963:256;;;;:::o;87637:97::-;26868:13;:11;:13::i;:::-;87720:6:::1;87708:9;:18;;;;87637:97:::0;:::o;87374:96::-;26868:13;:11;:13::i;:::-;87455:7:::1;87443:9;:19;;;;87374:96:::0;:::o;84460:240::-;26868:13;:11;:13::i;:::-;84566:12:::1;84593:7;:5;:7::i;:::-;84584:23;;84629:21;84584:81;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84565:100;;;84684:7;84676:16;;;::::0;::::1;;84499:201;84460:240::o:0;79968:18::-;;;;;;;;;;;;;:::o;82091:2267::-;7589:21;:19;:21::i;:::-;82207:6:::1;;;;;;;;;;;82203:33;;;82222:14;;;;;;;;;;;;;;82203:33;82383:4;;;;;;;;;;;82375:12;;:4;;;;;;;;;;;:12;;::::0;82371:46:::1;;82396:21;;;;;;;;;;;;;;82371:46;82509:4;82480:33;;:17;:25;82498:6;82480:25;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;82476:58;;82522:12;;;;;;;;;;;;;;82476:58;82611:13;;82597:11;:27;:47;;;;82643:1;82628:11;:16;82597:47;82593:93;;;82666:20;;;;;;;;;;;;;;82593:93;82786:13;;82772:11;82748:21;82758:10;82748:9;:21::i;:::-;:35;;;;:::i;:::-;:51;82744:97;;;82821:20;;;;;;;;;;;;;;82744:97;82904:15;82922:13;:11;:13::i;:::-;82904:31;;82975:9;;82960:11;82950:7;:21;;;;:::i;:::-;:34;82946:65;;82993:18;;;;;;;;;;;;;;82946:65;83289:9;83301:1;83289:13;;83284:417;83309:11;83304:1;:16;83284:417;;83619:34;83629:10;83651:1;83641:7;:11;;;;:::i;:::-;83619:9;:34::i;:::-;83668:21;:9;:19;:21::i;:::-;83322:3;;;;;:::i;:::-;;;;83284:417;;;;83798:7;:5;:7::i;:::-;83784:21;;:10;:21;;;83780:571;;83836:4;;;;;;;;;;;83826:14;;:6;:14;;::::0;83822:252:::1;;83861:12;83888:11;83876:9;;:23;;;;:::i;:::-;83861:38;;83918:54;83940:10;83960:4;83967;83918;;;;;;;;;;;:21;;;;:54;;;;;;:::i;:::-;84053:4;84041:10;84034:24;;;;;;;;;;;;83842:232;83822:252;84102:4;;;;;;;;;;;84092:14;;:6;:14;;::::0;84088:252:::1;;84127:12;84154:11;84142:9;;:23;;;;:::i;:::-;84127:38;;84184:54;84206:10;84226:4;84233;84184;;;;;;;;;;;:21;;;;:54;;;;;;:::i;:::-;84319:4;84307:10;84300:24;;;;;;;;;;;;84108:232;84088:252;83780:571;82163:2195;7633:20:::0;:18;:20::i;:::-;82091:2267;;:::o;59335:185::-;59473:39;59490:4;59496:2;59500:7;59473:39;;;;;;;;;;;;:16;:39::i;:::-;59335:185;;;:::o;88161:313::-;26868:13;:11;:13::i;:::-;88325:4:::1;;;;;;;;;;;88316:13;;:5;:13;;::::0;88312:47:::1;;88338:21;;;;;;;;;;;;;;88312:47;88396:5;88370:17;:23;88388:4;;;;;;;;;;;88370:23;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;88439:4;88412:17;:24;88430:5;88412:24;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;88461:5;88454:4;;:12;;;;;;;;;;;;;;;;;;88161:313:::0;:::o;73485:233::-;73560:7;73596:30;:28;:30::i;:::-;73588:5;:38;73580:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;73693:10;73704:5;73693:17;;;;;;;;:::i;:::-;;;;;;;;;;73686:24;;73485:233;;;:::o;86796:104::-;26868:13;:11;:13::i;:::-;86881:11:::1;86871:7;:21;;;;;;;;;;;;:::i;:::-;;86796:104:::0;:::o;80705:25::-;;;;;;;;;;;;;:::o;56427:223::-;56499:7;56519:13;56535:17;56544:7;56535:8;:17::i;:::-;56519:33;;56588:1;56571:19;;:5;:19;;;56563:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;56637:5;56630:12;;;56427:223;;;:::o;80247:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;56158:207::-;56230:7;56275:1;56258:19;;:5;:19;;;56250:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;56341:9;:16;56351:5;56341:16;;;;;;;;;;;;;;;;56334:23;;56158:207;;;:::o;27630:103::-;26868:13;:11;:13::i;:::-;27695:30:::1;27722:1;27695:18;:30::i;:::-;27630:103::o:0;30236:210::-;30283:14;30300:12;:10;:12::i;:::-;30283:29;;30349:6;30331:24;;:14;:12;:14::i;:::-;:24;;;30323:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;30412:26;30431:6;30412:18;:26::i;:::-;30272:174;30236:210::o;86589:124::-;26868:13;:11;:13::i;:::-;86688:17:::1;86672:13;:33;;;;86589:124:::0;:::o;87532:97::-;26868:13;:11;:13::i;:::-;87615:6:::1;87603:9;:18;;;;87532:97:::0;:::o;84763:248::-;26868:13;:11;:13::i;:::-;84864:4:::1;84835:33;;:17;:25;84853:6;84835:25;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;84831:58;;84877:12;;;;;;;;;;;;;;84831:58;84902:101;84936:10;84961:6;:16;;;84986:4;84961:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;84902:6;:19;;;;:101;;;;;:::i;:::-;84763:248:::0;:::o;26982:87::-;27028:7;27055:6;;;;;;;;;;;27048:13;;26982:87;:::o;85322:420::-;85401:16;85471:23;85497:17;85507:6;85497:9;:17::i;:::-;85471:43;;85527:25;85569:15;85555:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85527:58;;85601:9;85596:113;85616:15;85612:1;:19;85596:113;;;85667:30;85687:6;85695:1;85667:19;:30::i;:::-;85653:8;85662:1;85653:11;;;;;;;;:::i;:::-;;;;;;;:44;;;;;85633:3;;;;;:::i;:::-;;;;85596:113;;;;85726:8;85719:15;;;;85322:420;;;:::o;56886:104::-;56942:13;56975:7;56968:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56886:104;:::o;58472:155::-;58567:52;58586:12;:10;:12::i;:::-;58600:8;58610;58567:18;:52::i;:::-;58472:155;;:::o;59591:322::-;59765:41;59784:12;:10;:12::i;:::-;59798:7;59765:18;:41::i;:::-;59757:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;59867:38;59881:4;59887:2;59891:7;59900:4;59867:13;:38::i;:::-;59591:322;;;;:::o;87225:86::-;26868:13;:11;:13::i;:::-;87296:7:::1;87287:6;;:16;;;;;;;;;;;;;;;;;;87225:86:::0;:::o;80275:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;85825:681::-;85914:13;85962:16;85970:7;85962;:16::i;:::-;85940:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;86137:28;86168:10;:8;:10::i;:::-;86137:41;;86242:1;86217:14;86211:28;:32;:287;;;;;;;;;;;;;;;;;86335:14;86376:18;:7;:16;:18::i;:::-;86421:13;86292:165;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;86211:287;86191:307;;;85825:681;;;:::o;80573:30::-;;;;:::o;86983:144::-;26868:13;:11;:13::i;:::-;87102:17:::1;87086:13;:33;;;;;;;;;;;;:::i;:::-;;86983:144:::0;:::o;80393:24::-;;;;:::o;80126:48::-;;;;;;;;;;;;;;;;;;;;;;:::o;80424:24::-;;;;:::o;29324:101::-;29377:7;29404:13;;;;;;;;;;;29397:20;;29324:101;:::o;58698:164::-;58795:4;58819:18;:25;58838:5;58819:25;;;;;;;;;;;;;;;:35;58845:8;58819:35;;;;;;;;;;;;;;;;;;;;;;;;;58812:42;;58698:164;;;;:::o;29624:181::-;26868:13;:11;:13::i;:::-;29730:8:::1;29714:13;;:24;;;;;;;;;;;;;;;;;;29788:8;29754:43;;29779:7;:5;:7::i;:::-;29754:43;;;;;;;;;;;;29624:181:::0;:::o;28249:191::-;28323:16;28342:6;;;;;;;;;;;28323:25;;28368:8;28359:6;;:17;;;;;;;;;;;;;;;;;;28423:8;28392:40;;28413:8;28392:40;;;;;;;;;;;;28312:128;28249:191;:::o;55789:305::-;55891:4;55943:25;55928:40;;;:11;:40;;;;:105;;;;56000:33;55985:48;;;:11;:48;;;;55928:105;:158;;;;56050:36;56074:11;56050:23;:36::i;:::-;55928:158;55908:178;;55789:305;;;:::o;9062:114::-;9127:7;9154;:14;;;9147:21;;9062:114;;;:::o;68048:135::-;68130:16;68138:7;68130;:16::i;:::-;68122:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;68048:135;:::o;25533:98::-;25586:7;25613:10;25606:17;;25533:98;:::o;67327:174::-;67429:2;67402:15;:24;67418:7;67402:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;67485:7;67481:2;67447:46;;67456:23;67471:7;67456:14;:23::i;:::-;67447:46;;;;;;;;;;;;67327:174;;:::o;27147:132::-;27222:12;:10;:12::i;:::-;27211:23;;:7;:5;:7::i;:::-;:23;;;27203:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;27147:132::o;61946:264::-;62039:4;62056:13;62072:23;62087:7;62072:14;:23::i;:::-;62056:39;;62125:5;62114:16;;:7;:16;;;:52;;;;62134:32;62151:5;62158:7;62134:16;:32::i;:::-;62114:52;:87;;;;62194:7;62170:31;;:20;62182:7;62170:11;:20::i;:::-;:31;;;62114:87;62106:96;;;61946:264;;;;:::o;65945:1263::-;66104:4;66077:31;;:23;66092:7;66077:14;:23::i;:::-;:31;;;66069:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;66183:1;66169:16;;:2;:16;;;66161:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;66239:42;66260:4;66266:2;66270:7;66279:1;66239:20;:42::i;:::-;66411:4;66384:31;;:23;66399:7;66384:14;:23::i;:::-;:31;;;66376:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;66529:15;:24;66545:7;66529:24;;;;;;;;;;;;66522:31;;;;;;;;;;;67024:1;67005:9;:15;67015:4;67005:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;67057:1;67040:9;:13;67050:2;67040:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;67099:2;67080:7;:16;67088:7;67080:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;67138:7;67134:2;67119:27;;67128:4;67119:27;;;;;;;;;;;;67159:41;67179:4;67185:2;67189:7;67198:1;67159:19;:41::i;:::-;65945:1263;;;:::o;7669:293::-;7071:1;7803:7;;:19;7795:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7071:1;7936:7;:18;;;;7669:293::o;62552:110::-;62628:26;62638:2;62642:7;62628:26;;;;;;;;;;;;:9;:26::i;:::-;62552:110;;:::o;9184:127::-;9291:1;9273:7;:14;;;:19;;;;;;;;;;;9184:127;:::o;40814:248::-;40958:96;40978:5;41008:27;;;41037:4;41043:2;41047:5;40985:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40958:19;:96::i;:::-;40814:248;;;;:::o;7970:213::-;7027:1;8153:7;:22;;;;7970:213::o;61221:117::-;61287:7;61314;:16;61322:7;61314:16;;;;;;;;;;;;;;;;;;;;;61307:23;;61221:117;;;:::o;29995:156::-;30085:13;;30078:20;;;;;;;;;;;30109:34;30134:8;30109:24;:34::i;:::-;29995:156;:::o;40595:211::-;40712:86;40732:5;40762:23;;;40787:2;40791:5;40739:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40712:19;:86::i;:::-;40595:211;;;:::o;67644:315::-;67799:8;67790:17;;:5;:17;;;67782:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;67886:8;67848:18;:25;67867:5;67848:25;;;;;;;;;;;;;;;:35;67874:8;67848:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;67932:8;67910:41;;67925:5;67910:41;;;67942:8;67910:41;;;;;;:::i;:::-;;;;;;;;67644:315;;;:::o;60794:313::-;60950:28;60960:4;60966:2;60970:7;60950:9;:28::i;:::-;60997:47;61020:4;61026:2;61030:7;61039:4;60997:22;:47::i;:::-;60989:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;60794:313;;;;:::o;61651:128::-;61716:4;61769:1;61740:31;;:17;61749:7;61740:8;:17::i;:::-;:31;;;;61733:38;;61651:128;;;:::o;88551:108::-;88611:13;88644:7;88637:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88551:108;:::o;22960:716::-;23016:13;23067:14;23104:1;23084:17;23095:5;23084:10;:17::i;:::-;:21;23067:38;;23120:20;23154:6;23143:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23120:41;;23176:11;23305:6;23301:2;23297:15;23289:6;23285:28;23278:35;;23342:288;23349:4;23342:288;;;23374:5;;;;;;;;23516:8;23511:2;23504:5;23500:14;23495:30;23490:3;23482:44;23572:2;23563:11;;;;;;:::i;:::-;;;;;23606:1;23597:5;:10;23342:288;23593:21;23342:288;23651:6;23644:13;;;;;22960:716;;;:::o;47221:157::-;47306:4;47345:25;47330:40;;;:11;:40;;;;47323:47;;47221:157;;;:::o;73792:915::-;73969:61;73996:4;74002:2;74006:12;74020:9;73969:26;:61::i;:::-;74059:1;74047:9;:13;74043:222;;;74190:63;;;;;;;;;;:::i;:::-;;;;;;;;74043:222;74277:15;74295:12;74277:30;;74340:1;74324:18;;:4;:18;;;74320:187;;74359:40;74391:7;74359:31;:40::i;:::-;74320:187;;;74429:2;74421:10;;:4;:10;;;74417:90;;74448:47;74481:4;74487:7;74448:32;:47::i;:::-;74417:90;74320:187;74535:1;74521:16;;:2;:16;;;74517:183;;74554:45;74591:7;74554:36;:45::i;:::-;74517:183;;;74627:4;74621:10;;:2;:10;;;74617:83;;74648:40;74676:2;74680:7;74648:27;:40::i;:::-;74617:83;74517:183;73958:749;73792:915;;;;:::o;71464:158::-;;;;;:::o;62889:319::-;63018:18;63024:2;63028:7;63018:5;:18::i;:::-;63069:53;63100:1;63104:2;63108:7;63117:4;63069:22;:53::i;:::-;63047:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;62889:319;;;:::o;43662:716::-;44086:23;44112:69;44140:4;44112:69;;;;;;;;;;;;;;;;;44120:5;44112:27;;;;:69;;;;;:::i;:::-;44086:95;;44216:1;44196:10;:17;:21;44192:179;;;44293:10;44282:30;;;;;;;;;;;;:::i;:::-;44274:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;44192:179;43732:646;43662:716;;:::o;68747:853::-;68901:4;68922:15;:2;:13;;;:15::i;:::-;68918:675;;;68974:2;68958:36;;;68995:12;:10;:12::i;:::-;69009:4;69015:7;69024:4;68958:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;68954:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69216:1;69199:6;:13;:18;69195:328;;69242:60;;;;;;;;;;:::i;:::-;;;;;;;;69195:328;69473:6;69467:13;69458:6;69454:2;69450:15;69443:38;68954:584;69090:41;;;69080:51;;;:6;:51;;;;69073:58;;;;;68918:675;69577:4;69570:11;;68747:853;;;;;;;:::o;19826:922::-;19879:7;19899:14;19916:1;19899:18;;19966:6;19957:5;:15;19953:102;;20002:6;19993:15;;;;;;:::i;:::-;;;;;20037:2;20027:12;;;;19953:102;20082:6;20073:5;:15;20069:102;;20118:6;20109:15;;;;;;:::i;:::-;;;;;20153:2;20143:12;;;;20069:102;20198:6;20189:5;:15;20185:102;;20234:6;20225:15;;;;;;:::i;:::-;;;;;20269:2;20259:12;;;;20185:102;20314:5;20305;:14;20301:99;;20349:5;20340:14;;;;;;:::i;:::-;;;;;20383:1;20373:11;;;;20301:99;20427:5;20418;:14;20414:99;;20462:5;20453:14;;;;;;:::i;:::-;;;;;20496:1;20486:11;;;;20414:99;20540:5;20531;:14;20527:99;;20575:5;20566:14;;;;;;:::i;:::-;;;;;20609:1;20599:11;;;;20527:99;20653:5;20644;:14;20640:66;;20689:1;20679:11;;;;20640:66;20734:6;20727:13;;;19826:922;;;:::o;70332:410::-;70522:1;70510:9;:13;70506:229;;;70560:1;70544:18;;:4;:18;;;70540:87;;70602:9;70583;:15;70593:4;70583:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;70540:87;70659:1;70645:16;;:2;:16;;;70641:83;;70699:9;70682;:13;70692:2;70682:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;70641:83;70506:229;70332:410;;;;:::o;75430:164::-;75534:10;:17;;;;75507:15;:24;75523:7;75507:24;;;;;;;;;;;:44;;;;75562:10;75578:7;75562:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75430:164;:::o;76221:988::-;76487:22;76537:1;76512:22;76529:4;76512:16;:22::i;:::-;:26;;;;:::i;:::-;76487:51;;76549:18;76570:17;:26;76588:7;76570:26;;;;;;;;;;;;76549:47;;76717:14;76703:10;:28;76699:328;;76748:19;76770:12;:18;76783:4;76770:18;;;;;;;;;;;;;;;:34;76789:14;76770:34;;;;;;;;;;;;76748:56;;76854:11;76821:12;:18;76834:4;76821:18;;;;;;;;;;;;;;;:30;76840:10;76821:30;;;;;;;;;;;:44;;;;76971:10;76938:17;:30;76956:11;76938:30;;;;;;;;;;;:43;;;;76733:294;76699:328;77123:17;:26;77141:7;77123:26;;;;;;;;;;;77116:33;;;77167:12;:18;77180:4;77167:18;;;;;;;;;;;;;;;:34;77186:14;77167:34;;;;;;;;;;;77160:41;;;76302:907;;76221:988;;:::o;77504:1079::-;77757:22;77802:1;77782:10;:17;;;;:21;;;;:::i;:::-;77757:46;;77814:18;77835:15;:24;77851:7;77835:24;;;;;;;;;;;;77814:45;;78186:19;78208:10;78219:14;78208:26;;;;;;;;:::i;:::-;;;;;;;;;;78186:48;;78272:11;78247:10;78258;78247:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;78383:10;78352:15;:28;78368:11;78352:28;;;;;;;;;;;:41;;;;78524:15;:24;78540:7;78524:24;;;;;;;;;;;78517:31;;;78559:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;77575:1008;;;77504:1079;:::o;75008:221::-;75093:14;75110:20;75127:2;75110:16;:20::i;:::-;75093:37;;75168:7;75141:12;:16;75154:2;75141:16;;;;;;;;;;;;;;;:24;75158:6;75141:24;;;;;;;;;;;:34;;;;75215:6;75186:17;:26;75204:7;75186:26;;;;;;;;;;;:35;;;;75082:147;75008:221;;:::o;63544:942::-;63638:1;63624:16;;:2;:16;;;63616:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;63697:16;63705:7;63697;:16::i;:::-;63696:17;63688:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;63759:48;63788:1;63792:2;63796:7;63805:1;63759:20;:48::i;:::-;63906:16;63914:7;63906;:16::i;:::-;63905:17;63897:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;64321:1;64304:9;:13;64314:2;64304:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;64365:2;64346:7;:16;64354:7;64346:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;64410:7;64406:2;64385:33;;64402:1;64385:33;;;;;;;;;;;;64431:47;64459:1;64463:2;64467:7;64476:1;64431:19;:47::i;:::-;63544:942;;:::o;34443:229::-;34580:12;34612:52;34634:6;34642:4;34648:1;34651:12;34612:21;:52::i;:::-;34605:59;;34443:229;;;;;:::o;31686:326::-;31746:4;32003:1;31981:7;:19;;;:23;31974:30;;31686:326;;;:::o;35563:455::-;35733:12;35791:5;35766:21;:30;;35758:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;35851:12;35865:23;35892:6;:11;;35911:5;35918:4;35892:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35850:73;;;;35941:69;35968:6;35976:7;35985:10;35997:12;35941:26;:69::i;:::-;35934:76;;;;35563:455;;;;;;:::o;38136:644::-;38321:12;38350:7;38346:427;;;38399:1;38378:10;:17;:22;38374:290;;38596:18;38607:6;38596:10;:18::i;:::-;38588:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;38374:290;38685:10;38678:17;;;;38346:427;38728:33;38736:10;38748:12;38728:7;:33::i;:::-;38136:644;;;;;;;:::o;39322:552::-;39503:1;39483:10;:17;:21;39479:388;;;39715:10;39709:17;39772:15;39759:10;39755:2;39751:19;39744:44;39479:388;39842:12;39835:20;;;;;;;;;;;:::i;:::-;;;;;;;;-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:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:118::-;1688:24;1706:5;1688:24;:::i;:::-;1683:3;1676:37;1601:118;;:::o;1725:222::-;1818:4;1856:2;1845:9;1841:18;1833:26;;1869:71;1937:1;1926:9;1922:17;1913:6;1869:71;:::i;:::-;1725:222;;;;:::o;1953:99::-;2005:6;2039:5;2033:12;2023:22;;1953:99;;;:::o;2058:169::-;2142:11;2176:6;2171:3;2164:19;2216:4;2211:3;2207:14;2192:29;;2058:169;;;;:::o;2233:307::-;2301:1;2311:113;2325:6;2322:1;2319:13;2311:113;;;2410:1;2405:3;2401:11;2395:18;2391:1;2386:3;2382:11;2375:39;2347:2;2344:1;2340:10;2335:15;;2311:113;;;2442:6;2439:1;2436:13;2433:101;;;2522:1;2513:6;2508:3;2504:16;2497:27;2433:101;2282:258;2233:307;;;:::o;2546:102::-;2587:6;2638:2;2634:7;2629:2;2622:5;2618:14;2614:28;2604:38;;2546:102;;;:::o;2654:364::-;2742:3;2770:39;2803:5;2770:39;:::i;:::-;2825:71;2889:6;2884:3;2825:71;:::i;:::-;2818:78;;2905:52;2950:6;2945:3;2938:4;2931:5;2927:16;2905:52;:::i;:::-;2982:29;3004:6;2982:29;:::i;:::-;2977:3;2973:39;2966:46;;2746:272;2654:364;;;;:::o;3024:313::-;3137:4;3175:2;3164:9;3160:18;3152:26;;3224:9;3218:4;3214:20;3210:1;3199:9;3195:17;3188:47;3252:78;3325:4;3316:6;3252:78;:::i;:::-;3244:86;;3024:313;;;;:::o;3343:122::-;3416:24;3434:5;3416:24;:::i;:::-;3409:5;3406:35;3396:63;;3455:1;3452;3445:12;3396:63;3343:122;:::o;3471:139::-;3517:5;3555:6;3542:20;3533:29;;3571:33;3598:5;3571:33;:::i;:::-;3471:139;;;;:::o;3616:329::-;3675:6;3724:2;3712:9;3703:7;3699:23;3695:32;3692:119;;;3730:79;;:::i;:::-;3692:119;3850:1;3875:53;3920:7;3911:6;3900:9;3896:22;3875:53;:::i;:::-;3865:63;;3821:117;3616:329;;;;:::o;3951:126::-;3988:7;4028:42;4021:5;4017:54;4006:65;;3951:126;;;:::o;4083:96::-;4120:7;4149:24;4167:5;4149:24;:::i;:::-;4138:35;;4083:96;;;:::o;4185:118::-;4272:24;4290:5;4272:24;:::i;:::-;4267:3;4260:37;4185:118;;:::o;4309:222::-;4402:4;4440:2;4429:9;4425:18;4417:26;;4453:71;4521:1;4510:9;4506:17;4497:6;4453:71;:::i;:::-;4309:222;;;;:::o;4537:122::-;4610:24;4628:5;4610:24;:::i;:::-;4603:5;4600:35;4590:63;;4649:1;4646;4639:12;4590:63;4537:122;:::o;4665:139::-;4711:5;4749:6;4736:20;4727:29;;4765:33;4792:5;4765:33;:::i;:::-;4665:139;;;;:::o;4810:474::-;4878:6;4886;4935:2;4923:9;4914:7;4910:23;4906:32;4903:119;;;4941:79;;:::i;:::-;4903:119;5061:1;5086:53;5131:7;5122:6;5111:9;5107:22;5086:53;:::i;:::-;5076:63;;5032:117;5188:2;5214:53;5259:7;5250:6;5239:9;5235:22;5214:53;:::i;:::-;5204:63;;5159:118;4810:474;;;;;:::o;5290:110::-;5341:7;5370:24;5388:5;5370:24;:::i;:::-;5359:35;;5290:110;;;:::o;5406:150::-;5493:38;5525:5;5493:38;:::i;:::-;5486:5;5483:49;5473:77;;5546:1;5543;5536:12;5473:77;5406:150;:::o;5562:167::-;5622:5;5660:6;5647:20;5638:29;;5676:47;5717:5;5676:47;:::i;:::-;5562:167;;;;:::o;5735:357::-;5808:6;5857:2;5845:9;5836:7;5832:23;5828:32;5825:119;;;5863:79;;:::i;:::-;5825:119;5983:1;6008:67;6067:7;6058:6;6047:9;6043:22;6008:67;:::i;:::-;5998:77;;5954:131;5735:357;;;;:::o;6098:619::-;6175:6;6183;6191;6240:2;6228:9;6219:7;6215:23;6211:32;6208:119;;;6246:79;;:::i;:::-;6208:119;6366:1;6391:53;6436:7;6427:6;6416:9;6412:22;6391:53;:::i;:::-;6381:63;;6337:117;6493:2;6519:53;6564:7;6555:6;6544:9;6540:22;6519:53;:::i;:::-;6509:63;;6464:118;6621:2;6647:53;6692:7;6683:6;6672:9;6668:22;6647:53;:::i;:::-;6637:63;;6592:118;6098:619;;;;;:::o;6723:60::-;6751:3;6772:5;6765:12;;6723:60;;;:::o;6789:142::-;6839:9;6872:53;6890:34;6899:24;6917:5;6899:24;:::i;:::-;6890:34;:::i;:::-;6872:53;:::i;:::-;6859:66;;6789:142;;;:::o;6937:126::-;6987:9;7020:37;7051:5;7020:37;:::i;:::-;7007:50;;6937:126;;;:::o;7069:140::-;7133:9;7166:37;7197:5;7166:37;:::i;:::-;7153:50;;7069:140;;;:::o;7215:159::-;7316:51;7361:5;7316:51;:::i;:::-;7311:3;7304:64;7215:159;;:::o;7380:250::-;7487:4;7525:2;7514:9;7510:18;7502:26;;7538:85;7620:1;7609:9;7605:17;7596:6;7538:85;:::i;:::-;7380:250;;;;:::o;7636:502::-;7718:6;7726;7775:2;7763:9;7754:7;7750:23;7746:32;7743:119;;;7781:79;;:::i;:::-;7743:119;7901:1;7926:67;7985:7;7976:6;7965:9;7961:22;7926:67;:::i;:::-;7916:77;;7872:131;8042:2;8068:53;8113:7;8104:6;8093:9;8089:22;8068:53;:::i;:::-;8058:63;;8013:118;7636:502;;;;;:::o;8144:117::-;8253:1;8250;8243:12;8267:117;8376:1;8373;8366:12;8390:180;8438:77;8435:1;8428:88;8535:4;8532:1;8525:15;8559:4;8556:1;8549:15;8576:281;8659:27;8681:4;8659:27;:::i;:::-;8651:6;8647:40;8789:6;8777:10;8774:22;8753:18;8741:10;8738:34;8735:62;8732:88;;;8800:18;;:::i;:::-;8732:88;8840:10;8836:2;8829:22;8619:238;8576:281;;:::o;8863:129::-;8897:6;8924:20;;:::i;:::-;8914:30;;8953:33;8981:4;8973:6;8953:33;:::i;:::-;8863:129;;;:::o;8998:308::-;9060:4;9150:18;9142:6;9139:30;9136:56;;;9172:18;;:::i;:::-;9136:56;9210:29;9232:6;9210:29;:::i;:::-;9202:37;;9294:4;9288;9284:15;9276:23;;8998:308;;;:::o;9312:154::-;9396:6;9391:3;9386;9373:30;9458:1;9449:6;9444:3;9440:16;9433:27;9312:154;;;:::o;9472:412::-;9550:5;9575:66;9591:49;9633:6;9591:49;:::i;:::-;9575:66;:::i;:::-;9566:75;;9664:6;9657:5;9650:21;9702:4;9695:5;9691:16;9740:3;9731:6;9726:3;9722:16;9719:25;9716:112;;;9747:79;;:::i;:::-;9716:112;9837:41;9871:6;9866:3;9861;9837:41;:::i;:::-;9556:328;9472:412;;;;;:::o;9904:340::-;9960:5;10009:3;10002:4;9994:6;9990:17;9986:27;9976:122;;10017:79;;:::i;:::-;9976:122;10134:6;10121:20;10159:79;10234:3;10226:6;10219:4;10211:6;10207:17;10159:79;:::i;:::-;10150:88;;9966:278;9904:340;;;;:::o;10250:509::-;10319:6;10368:2;10356:9;10347:7;10343:23;10339:32;10336:119;;;10374:79;;:::i;:::-;10336:119;10522:1;10511:9;10507:17;10494:31;10552:18;10544:6;10541:30;10538:117;;;10574:79;;:::i;:::-;10538:117;10679:63;10734:7;10725:6;10714:9;10710:22;10679:63;:::i;:::-;10669:73;;10465:287;10250:509;;;;:::o;10765:329::-;10824:6;10873:2;10861:9;10852:7;10848:23;10844:32;10841:119;;;10879:79;;:::i;:::-;10841:119;10999:1;11024:53;11069:7;11060:6;11049:9;11045:22;11024:53;:::i;:::-;11014:63;;10970:117;10765:329;;;;:::o;11100:114::-;11167:6;11201:5;11195:12;11185:22;;11100:114;;;:::o;11220:184::-;11319:11;11353:6;11348:3;11341:19;11393:4;11388:3;11384:14;11369:29;;11220:184;;;;:::o;11410:132::-;11477:4;11500:3;11492:11;;11530:4;11525:3;11521:14;11513:22;;11410:132;;;:::o;11548:108::-;11625:24;11643:5;11625:24;:::i;:::-;11620:3;11613:37;11548:108;;:::o;11662:179::-;11731:10;11752:46;11794:3;11786:6;11752:46;:::i;:::-;11830:4;11825:3;11821:14;11807:28;;11662:179;;;;:::o;11847:113::-;11917:4;11949;11944:3;11940:14;11932:22;;11847:113;;;:::o;11996:732::-;12115:3;12144:54;12192:5;12144:54;:::i;:::-;12214:86;12293:6;12288:3;12214:86;:::i;:::-;12207:93;;12324:56;12374:5;12324:56;:::i;:::-;12403:7;12434:1;12419:284;12444:6;12441:1;12438:13;12419:284;;;12520:6;12514:13;12547:63;12606:3;12591:13;12547:63;:::i;:::-;12540:70;;12633:60;12686:6;12633:60;:::i;:::-;12623:70;;12479:224;12466:1;12463;12459:9;12454:14;;12419:284;;;12423:14;12719:3;12712:10;;12120:608;;;11996:732;;;;:::o;12734:373::-;12877:4;12915:2;12904:9;12900:18;12892:26;;12964:9;12958:4;12954:20;12950:1;12939:9;12935:17;12928:47;12992:108;13095:4;13086:6;12992:108;:::i;:::-;12984:116;;12734:373;;;;:::o;13113:116::-;13183:21;13198:5;13183:21;:::i;:::-;13176:5;13173:32;13163:60;;13219:1;13216;13209:12;13163:60;13113:116;:::o;13235:133::-;13278:5;13316:6;13303:20;13294:29;;13332:30;13356:5;13332:30;:::i;:::-;13235:133;;;;:::o;13374:468::-;13439:6;13447;13496:2;13484:9;13475:7;13471:23;13467:32;13464:119;;;13502:79;;:::i;:::-;13464:119;13622:1;13647:53;13692:7;13683:6;13672:9;13668:22;13647:53;:::i;:::-;13637:63;;13593:117;13749:2;13775:50;13817:7;13808:6;13797:9;13793:22;13775:50;:::i;:::-;13765:60;;13720:115;13374:468;;;;;:::o;13848:307::-;13909:4;13999:18;13991:6;13988:30;13985:56;;;14021:18;;:::i;:::-;13985:56;14059:29;14081:6;14059:29;:::i;:::-;14051:37;;14143:4;14137;14133:15;14125:23;;13848:307;;;:::o;14161:410::-;14238:5;14263:65;14279:48;14320:6;14279:48;:::i;:::-;14263:65;:::i;:::-;14254:74;;14351:6;14344:5;14337:21;14389:4;14382:5;14378:16;14427:3;14418:6;14413:3;14409:16;14406:25;14403:112;;;14434:79;;:::i;:::-;14403:112;14524:41;14558:6;14553:3;14548;14524:41;:::i;:::-;14244:327;14161:410;;;;;:::o;14590:338::-;14645:5;14694:3;14687:4;14679:6;14675:17;14671:27;14661:122;;14702:79;;:::i;:::-;14661:122;14819:6;14806:20;14844:78;14918:3;14910:6;14903:4;14895:6;14891:17;14844:78;:::i;:::-;14835:87;;14651:277;14590:338;;;;:::o;14934:943::-;15029:6;15037;15045;15053;15102:3;15090:9;15081:7;15077:23;15073:33;15070:120;;;15109:79;;:::i;:::-;15070:120;15229:1;15254:53;15299:7;15290:6;15279:9;15275:22;15254:53;:::i;:::-;15244:63;;15200:117;15356:2;15382:53;15427:7;15418:6;15407:9;15403:22;15382:53;:::i;:::-;15372:63;;15327:118;15484:2;15510:53;15555:7;15546:6;15535:9;15531:22;15510:53;:::i;:::-;15500:63;;15455:118;15640:2;15629:9;15625:18;15612:32;15671:18;15663:6;15660:30;15657:117;;;15693:79;;:::i;:::-;15657:117;15798:62;15852:7;15843:6;15832:9;15828:22;15798:62;:::i;:::-;15788:72;;15583:287;14934:943;;;;;;;:::o;15883:323::-;15939:6;15988:2;15976:9;15967:7;15963:23;15959:32;15956:119;;;15994:79;;:::i;:::-;15956:119;16114:1;16139:50;16181:7;16172:6;16161:9;16157:22;16139:50;:::i;:::-;16129:60;;16085:114;15883:323;;;;:::o;16212:474::-;16280:6;16288;16337:2;16325:9;16316:7;16312:23;16308:32;16305:119;;;16343:79;;:::i;:::-;16305:119;16463:1;16488:53;16533:7;16524:6;16513:9;16509:22;16488:53;:::i;:::-;16478:63;;16434:117;16590:2;16616:53;16661:7;16652:6;16641:9;16637:22;16616:53;:::i;:::-;16606:63;;16561:118;16212:474;;;;;:::o;16692:180::-;16740:77;16737:1;16730:88;16837:4;16834:1;16827:15;16861:4;16858:1;16851:15;16878:320;16922:6;16959:1;16953:4;16949:12;16939:22;;17006:1;17000:4;16996:12;17027:18;17017:81;;17083:4;17075:6;17071:17;17061:27;;17017:81;17145:2;17137:6;17134:14;17114:18;17111:38;17108:84;;17164:18;;:::i;:::-;17108:84;16929:269;16878:320;;;:::o;17204:220::-;17344:34;17340:1;17332:6;17328:14;17321:58;17413:3;17408:2;17400:6;17396:15;17389:28;17204:220;:::o;17430:366::-;17572:3;17593:67;17657:2;17652:3;17593:67;:::i;:::-;17586:74;;17669:93;17758:3;17669:93;:::i;:::-;17787:2;17782:3;17778:12;17771:19;;17430:366;;;:::o;17802:419::-;17968:4;18006:2;17995:9;17991:18;17983:26;;18055:9;18049:4;18045:20;18041:1;18030:9;18026:17;18019:47;18083:131;18209:4;18083:131;:::i;:::-;18075:139;;17802:419;;;:::o;18227:248::-;18367:34;18363:1;18355:6;18351:14;18344:58;18436:31;18431:2;18423:6;18419:15;18412:56;18227:248;:::o;18481:366::-;18623:3;18644:67;18708:2;18703:3;18644:67;:::i;:::-;18637:74;;18720:93;18809:3;18720:93;:::i;:::-;18838:2;18833:3;18829:12;18822:19;;18481:366;;;:::o;18853:419::-;19019:4;19057:2;19046:9;19042:18;19034:26;;19106:9;19100:4;19096:20;19092:1;19081:9;19077:17;19070:47;19134:131;19260:4;19134:131;:::i;:::-;19126:139;;18853:419;;;:::o;19278:232::-;19418:34;19414:1;19406:6;19402:14;19395:58;19487:15;19482:2;19474:6;19470:15;19463:40;19278:232;:::o;19516:366::-;19658:3;19679:67;19743:2;19738:3;19679:67;:::i;:::-;19672:74;;19755:93;19844:3;19755:93;:::i;:::-;19873:2;19868:3;19864:12;19857:19;;19516:366;;;:::o;19888:419::-;20054:4;20092:2;20081:9;20077:18;20069:26;;20141:9;20135:4;20131:20;20127:1;20116:9;20112:17;20105:47;20169:131;20295:4;20169:131;:::i;:::-;20161:139;;19888:419;;;:::o;20313:230::-;20453:34;20449:1;20441:6;20437:14;20430:58;20522:13;20517:2;20509:6;20505:15;20498:38;20313:230;:::o;20549:366::-;20691:3;20712:67;20776:2;20771:3;20712:67;:::i;:::-;20705:74;;20788:93;20877:3;20788:93;:::i;:::-;20906:2;20901:3;20897:12;20890:19;;20549:366;;;:::o;20921:419::-;21087:4;21125:2;21114:9;21110:18;21102:26;;21174:9;21168:4;21164:20;21160:1;21149:9;21145:17;21138:47;21202:131;21328:4;21202:131;:::i;:::-;21194:139;;20921:419;;;:::o;21346:147::-;21447:11;21484:3;21469:18;;21346:147;;;;:::o;21499:114::-;;:::o;21619:398::-;21778:3;21799:83;21880:1;21875:3;21799:83;:::i;:::-;21792:90;;21891:93;21980:3;21891:93;:::i;:::-;22009:1;22004:3;22000:11;21993:18;;21619:398;;;:::o;22023:379::-;22207:3;22229:147;22372:3;22229:147;:::i;:::-;22222:154;;22393:3;22386:10;;22023:379;;;:::o;22408:180::-;22456:77;22453:1;22446:88;22553:4;22550:1;22543:15;22577:4;22574:1;22567:15;22594:305;22634:3;22653:20;22671:1;22653:20;:::i;:::-;22648:25;;22687:20;22705:1;22687:20;:::i;:::-;22682:25;;22841:1;22773:66;22769:74;22766:1;22763:81;22760:107;;;22847:18;;:::i;:::-;22760:107;22891:1;22888;22884:9;22877:16;;22594:305;;;;:::o;22905:233::-;22944:3;22967:24;22985:5;22967:24;:::i;:::-;22958:33;;23013:66;23006:5;23003:77;23000:103;;23083:18;;:::i;:::-;23000:103;23130:1;23123:5;23119:13;23112:20;;22905:233;;;:::o;23144:348::-;23184:7;23207:20;23225:1;23207:20;:::i;:::-;23202:25;;23241:20;23259:1;23241:20;:::i;:::-;23236:25;;23429:1;23361:66;23357:74;23354:1;23351:81;23346:1;23339:9;23332:17;23328:105;23325:131;;;23436:18;;:::i;:::-;23325:131;23484:1;23481;23477:9;23466:20;;23144:348;;;;:::o;23498:231::-;23638:34;23634:1;23626:6;23622:14;23615:58;23707:14;23702:2;23694:6;23690:15;23683:39;23498:231;:::o;23735:366::-;23877:3;23898:67;23962:2;23957:3;23898:67;:::i;:::-;23891:74;;23974:93;24063:3;23974:93;:::i;:::-;24092:2;24087:3;24083:12;24076:19;;23735:366;;;:::o;24107:419::-;24273:4;24311:2;24300:9;24296:18;24288:26;;24360:9;24354:4;24350:20;24346:1;24335:9;24331:17;24324:47;24388:131;24514:4;24388:131;:::i;:::-;24380:139;;24107:419;;;:::o;24532:180::-;24580:77;24577:1;24570:88;24677:4;24674:1;24667:15;24701:4;24698:1;24691:15;24718:174;24858:26;24854:1;24846:6;24842:14;24835:50;24718:174;:::o;24898:366::-;25040:3;25061:67;25125:2;25120:3;25061:67;:::i;:::-;25054:74;;25137:93;25226:3;25137:93;:::i;:::-;25255:2;25250:3;25246:12;25239:19;;24898:366;;;:::o;25270:419::-;25436:4;25474:2;25463:9;25459:18;25451:26;;25523:9;25517:4;25513:20;25509:1;25498:9;25494:17;25487:47;25551:131;25677:4;25551:131;:::i;:::-;25543:139;;25270:419;;;:::o;25695:228::-;25835:34;25831:1;25823:6;25819:14;25812:58;25904:11;25899:2;25891:6;25887:15;25880:36;25695:228;:::o;25929:366::-;26071:3;26092:67;26156:2;26151:3;26092:67;:::i;:::-;26085:74;;26168:93;26257:3;26168:93;:::i;:::-;26286:2;26281:3;26277:12;26270:19;;25929:366;;;:::o;26301:419::-;26467:4;26505:2;26494:9;26490:18;26482:26;;26554:9;26548:4;26544:20;26540:1;26529:9;26525:17;26518:47;26582:131;26708:4;26582:131;:::i;:::-;26574:139;;26301:419;;;:::o;26726:228::-;26866:34;26862:1;26854:6;26850:14;26843:58;26935:11;26930:2;26922:6;26918:15;26911:36;26726:228;:::o;26960:366::-;27102:3;27123:67;27187:2;27182:3;27123:67;:::i;:::-;27116:74;;27199:93;27288:3;27199:93;:::i;:::-;27317:2;27312:3;27308:12;27301:19;;26960:366;;;:::o;27332:419::-;27498:4;27536:2;27525:9;27521:18;27513:26;;27585:9;27579:4;27575:20;27571:1;27560:9;27556:17;27549:47;27613:131;27739:4;27613:131;:::i;:::-;27605:139;;27332:419;;;:::o;27757:143::-;27814:5;27845:6;27839:13;27830:22;;27861:33;27888:5;27861:33;:::i;:::-;27757:143;;;;:::o;27906:351::-;27976:6;28025:2;28013:9;28004:7;28000:23;27996:32;27993:119;;;28031:79;;:::i;:::-;27993:119;28151:1;28176:64;28232:7;28223:6;28212:9;28208:22;28176:64;:::i;:::-;28166:74;;28122:128;27906:351;;;;:::o;28263:234::-;28403:34;28399:1;28391:6;28387:14;28380:58;28472:17;28467:2;28459:6;28455:15;28448:42;28263:234;:::o;28503:366::-;28645:3;28666:67;28730:2;28725:3;28666:67;:::i;:::-;28659:74;;28742:93;28831:3;28742:93;:::i;:::-;28860:2;28855:3;28851:12;28844:19;;28503:366;;;:::o;28875:419::-;29041:4;29079:2;29068:9;29064:18;29056:26;;29128:9;29122:4;29118:20;29114:1;29103:9;29099:17;29092:47;29156:131;29282:4;29156:131;:::i;:::-;29148:139;;28875:419;;;:::o;29300:148::-;29402:11;29439:3;29424:18;;29300:148;;;;:::o;29454:377::-;29560:3;29588:39;29621:5;29588:39;:::i;:::-;29643:89;29725:6;29720:3;29643:89;:::i;:::-;29636:96;;29741:52;29786:6;29781:3;29774:4;29767:5;29763:16;29741:52;:::i;:::-;29818:6;29813:3;29809:16;29802:23;;29564:267;29454:377;;;;:::o;29837:141::-;29886:4;29909:3;29901:11;;29932:3;29929:1;29922:14;29966:4;29963:1;29953:18;29945:26;;29837:141;;;:::o;30008:845::-;30111:3;30148:5;30142:12;30177:36;30203:9;30177:36;:::i;:::-;30229:89;30311:6;30306:3;30229:89;:::i;:::-;30222:96;;30349:1;30338:9;30334:17;30365:1;30360:137;;;;30511:1;30506:341;;;;30327:520;;30360:137;30444:4;30440:9;30429;30425:25;30420:3;30413:38;30480:6;30475:3;30471:16;30464:23;;30360:137;;30506:341;30573:38;30605:5;30573:38;:::i;:::-;30633:1;30647:154;30661:6;30658:1;30655:13;30647:154;;;30735:7;30729:14;30725:1;30720:3;30716:11;30709:35;30785:1;30776:7;30772:15;30761:26;;30683:4;30680:1;30676:12;30671:17;;30647:154;;;30830:6;30825:3;30821:16;30814:23;;30513:334;;30327:520;;30115:738;;30008:845;;;;:::o;30859:589::-;31084:3;31106:95;31197:3;31188:6;31106:95;:::i;:::-;31099:102;;31218:95;31309:3;31300:6;31218:95;:::i;:::-;31211:102;;31330:92;31418:3;31409:6;31330:92;:::i;:::-;31323:99;;31439:3;31432:10;;30859:589;;;;;;:::o;31454:182::-;31594:34;31590:1;31582:6;31578:14;31571:58;31454:182;:::o;31642:366::-;31784:3;31805:67;31869:2;31864:3;31805:67;:::i;:::-;31798:74;;31881:93;31970:3;31881:93;:::i;:::-;31999:2;31994:3;31990:12;31983:19;;31642:366;;;:::o;32014:419::-;32180:4;32218:2;32207:9;32203:18;32195:26;;32267:9;32261:4;32257:20;32253:1;32242:9;32238:17;32231:47;32295:131;32421:4;32295:131;:::i;:::-;32287:139;;32014:419;;;:::o;32439:224::-;32579:34;32575:1;32567:6;32563:14;32556:58;32648:7;32643:2;32635:6;32631:15;32624:32;32439:224;:::o;32669:366::-;32811:3;32832:67;32896:2;32891:3;32832:67;:::i;:::-;32825:74;;32908:93;32997:3;32908:93;:::i;:::-;33026:2;33021:3;33017:12;33010:19;;32669:366;;;:::o;33041:419::-;33207:4;33245:2;33234:9;33230:18;33222:26;;33294:9;33288:4;33284:20;33280:1;33269:9;33265:17;33258:47;33322:131;33448:4;33322:131;:::i;:::-;33314:139;;33041:419;;;:::o;33466:223::-;33606:34;33602:1;33594:6;33590:14;33583:58;33675:6;33670:2;33662:6;33658:15;33651:31;33466:223;:::o;33695:366::-;33837:3;33858:67;33922:2;33917:3;33858:67;:::i;:::-;33851:74;;33934:93;34023:3;33934:93;:::i;:::-;34052:2;34047:3;34043:12;34036:19;;33695:366;;;:::o;34067:419::-;34233:4;34271:2;34260:9;34256:18;34248:26;;34320:9;34314:4;34310:20;34306:1;34295:9;34291:17;34284:47;34348:131;34474:4;34348:131;:::i;:::-;34340:139;;34067:419;;;:::o;34492:181::-;34632:33;34628:1;34620:6;34616:14;34609:57;34492:181;:::o;34679:366::-;34821:3;34842:67;34906:2;34901:3;34842:67;:::i;:::-;34835:74;;34918:93;35007:3;34918:93;:::i;:::-;35036:2;35031:3;35027:12;35020:19;;34679:366;;;:::o;35051:419::-;35217:4;35255:2;35244:9;35240:18;35232:26;;35304:9;35298:4;35294:20;35290:1;35279:9;35275:17;35268:47;35332:131;35458:4;35332:131;:::i;:::-;35324:139;;35051:419;;;:::o;35476:442::-;35625:4;35663:2;35652:9;35648:18;35640:26;;35676:71;35744:1;35733:9;35729:17;35720:6;35676:71;:::i;:::-;35757:72;35825:2;35814:9;35810:18;35801:6;35757:72;:::i;:::-;35839;35907:2;35896:9;35892:18;35883:6;35839:72;:::i;:::-;35476:442;;;;;;:::o;35924:332::-;36045:4;36083:2;36072:9;36068:18;36060:26;;36096:71;36164:1;36153:9;36149:17;36140:6;36096:71;:::i;:::-;36177:72;36245:2;36234:9;36230:18;36221:6;36177:72;:::i;:::-;35924:332;;;;;:::o;36262:175::-;36402:27;36398:1;36390:6;36386:14;36379:51;36262:175;:::o;36443:366::-;36585:3;36606:67;36670:2;36665:3;36606:67;:::i;:::-;36599:74;;36682:93;36771:3;36682:93;:::i;:::-;36800:2;36795:3;36791:12;36784:19;;36443:366;;;:::o;36815:419::-;36981:4;37019:2;37008:9;37004:18;36996:26;;37068:9;37062:4;37058:20;37054:1;37043:9;37039:17;37032:47;37096:131;37222:4;37096:131;:::i;:::-;37088:139;;36815:419;;;:::o;37240:237::-;37380:34;37376:1;37368:6;37364:14;37357:58;37449:20;37444:2;37436:6;37432:15;37425:45;37240:237;:::o;37483:366::-;37625:3;37646:67;37710:2;37705:3;37646:67;:::i;:::-;37639:74;;37722:93;37811:3;37722:93;:::i;:::-;37840:2;37835:3;37831:12;37824:19;;37483:366;;;:::o;37855:419::-;38021:4;38059:2;38048:9;38044:18;38036:26;;38108:9;38102:4;38098:20;38094:1;38083:9;38079:17;38072:47;38136:131;38262:4;38136:131;:::i;:::-;38128:139;;37855:419;;;:::o;38280:180::-;38328:77;38325:1;38318:88;38425:4;38422:1;38415:15;38449:4;38446:1;38439:15;38466:240;38606:34;38602:1;38594:6;38590:14;38583:58;38675:23;38670:2;38662:6;38658:15;38651:48;38466:240;:::o;38712:366::-;38854:3;38875:67;38939:2;38934:3;38875:67;:::i;:::-;38868:74;;38951:93;39040:3;38951:93;:::i;:::-;39069:2;39064:3;39060:12;39053:19;;38712:366;;;:::o;39084:419::-;39250:4;39288:2;39277:9;39273:18;39265:26;;39337:9;39331:4;39327:20;39323:1;39312:9;39308:17;39301:47;39365:131;39491:4;39365:131;:::i;:::-;39357:139;;39084:419;;;:::o;39509:137::-;39563:5;39594:6;39588:13;39579:22;;39610:30;39634:5;39610:30;:::i;:::-;39509:137;;;;:::o;39652:345::-;39719:6;39768:2;39756:9;39747:7;39743:23;39739:32;39736:119;;;39774:79;;:::i;:::-;39736:119;39894:1;39919:61;39972:7;39963:6;39952:9;39948:22;39919:61;:::i;:::-;39909:71;;39865:125;39652:345;;;;:::o;40003:229::-;40143:34;40139:1;40131:6;40127:14;40120:58;40212:12;40207:2;40199:6;40195:15;40188:37;40003:229;:::o;40238:366::-;40380:3;40401:67;40465:2;40460:3;40401:67;:::i;:::-;40394:74;;40477:93;40566:3;40477:93;:::i;:::-;40595:2;40590:3;40586:12;40579:19;;40238:366;;;:::o;40610:419::-;40776:4;40814:2;40803:9;40799:18;40791:26;;40863:9;40857:4;40853:20;40849:1;40838:9;40834:17;40827:47;40891:131;41017:4;40891:131;:::i;:::-;40883:139;;40610:419;;;:::o;41035:98::-;41086:6;41120:5;41114:12;41104:22;;41035:98;;;:::o;41139:168::-;41222:11;41256:6;41251:3;41244:19;41296:4;41291:3;41287:14;41272:29;;41139:168;;;;:::o;41313:360::-;41399:3;41427:38;41459:5;41427:38;:::i;:::-;41481:70;41544:6;41539:3;41481:70;:::i;:::-;41474:77;;41560:52;41605:6;41600:3;41593:4;41586:5;41582:16;41560:52;:::i;:::-;41637:29;41659:6;41637:29;:::i;:::-;41632:3;41628:39;41621:46;;41403:270;41313:360;;;;:::o;41679:640::-;41874:4;41912:3;41901:9;41897:19;41889:27;;41926:71;41994:1;41983:9;41979:17;41970:6;41926:71;:::i;:::-;42007:72;42075:2;42064:9;42060:18;42051:6;42007:72;:::i;:::-;42089;42157:2;42146:9;42142:18;42133:6;42089:72;:::i;:::-;42208:9;42202:4;42198:20;42193:2;42182:9;42178:18;42171:48;42236:76;42307:4;42298:6;42236:76;:::i;:::-;42228:84;;41679:640;;;;;;;:::o;42325:141::-;42381:5;42412:6;42406:13;42397:22;;42428:32;42454:5;42428:32;:::i;:::-;42325:141;;;;:::o;42472:349::-;42541:6;42590:2;42578:9;42569:7;42565:23;42561:32;42558:119;;;42596:79;;:::i;:::-;42558:119;42716:1;42741:63;42796:7;42787:6;42776:9;42772:22;42741:63;:::i;:::-;42731:73;;42687:127;42472:349;;;;:::o;42827:191::-;42867:4;42887:20;42905:1;42887:20;:::i;:::-;42882:25;;42921:20;42939:1;42921:20;:::i;:::-;42916:25;;42960:1;42957;42954:8;42951:34;;;42965:18;;:::i;:::-;42951:34;43010:1;43007;43003:9;42995:17;;42827:191;;;;:::o;43024:180::-;43072:77;43069:1;43062:88;43169:4;43166:1;43159:15;43193:4;43190:1;43183:15;43210:182;43350:34;43346:1;43338:6;43334:14;43327:58;43210:182;:::o;43398:366::-;43540:3;43561:67;43625:2;43620:3;43561:67;:::i;:::-;43554:74;;43637:93;43726:3;43637:93;:::i;:::-;43755:2;43750:3;43746:12;43739:19;;43398:366;;;:::o;43770:419::-;43936:4;43974:2;43963:9;43959:18;43951:26;;44023:9;44017:4;44013:20;44009:1;43998:9;43994:17;43987:47;44051:131;44177:4;44051:131;:::i;:::-;44043:139;;43770:419;;;:::o;44195:178::-;44335:30;44331:1;44323:6;44319:14;44312:54;44195:178;:::o;44379:366::-;44521:3;44542:67;44606:2;44601:3;44542:67;:::i;:::-;44535:74;;44618:93;44707:3;44618:93;:::i;:::-;44736:2;44731:3;44727:12;44720:19;;44379:366;;;:::o;44751:419::-;44917:4;44955:2;44944:9;44940:18;44932:26;;45004:9;44998:4;44994:20;44990:1;44979:9;44975:17;44968:47;45032:131;45158:4;45032:131;:::i;:::-;45024:139;;44751:419;;;:::o;45176:225::-;45316:34;45312:1;45304:6;45300:14;45293:58;45385:8;45380:2;45372:6;45368:15;45361:33;45176:225;:::o;45407:366::-;45549:3;45570:67;45634:2;45629:3;45570:67;:::i;:::-;45563:74;;45646:93;45735:3;45646:93;:::i;:::-;45764:2;45759:3;45755:12;45748:19;;45407:366;;;:::o;45779:419::-;45945:4;45983:2;45972:9;45968:18;45960:26;;46032:9;46026:4;46022:20;46018:1;46007:9;46003:17;45996:47;46060:131;46186:4;46060:131;:::i;:::-;46052:139;;45779:419;;;:::o;46204:373::-;46308:3;46336:38;46368:5;46336:38;:::i;:::-;46390:88;46471:6;46466:3;46390:88;:::i;:::-;46383:95;;46487:52;46532:6;46527:3;46520:4;46513:5;46509:16;46487:52;:::i;:::-;46564:6;46559:3;46555:16;46548:23;;46312:265;46204:373;;;;:::o;46583:271::-;46713:3;46735:93;46824:3;46815:6;46735:93;:::i;:::-;46728:100;;46845:3;46838:10;;46583:271;;;;:::o;46860:179::-;47000:31;46996:1;46988:6;46984:14;46977:55;46860:179;:::o;47045:366::-;47187:3;47208:67;47272:2;47267:3;47208:67;:::i;:::-;47201:74;;47284:93;47373:3;47284:93;:::i;:::-;47402:2;47397:3;47393:12;47386:19;;47045:366;;;:::o;47417:419::-;47583:4;47621:2;47610:9;47606:18;47598:26;;47670:9;47664:4;47660:20;47656:1;47645:9;47641:17;47634:47;47698:131;47824:4;47698:131;:::i;:::-;47690:139;;47417:419;;;:::o

Swarm Source

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