ETH Price: $3,879.47 (+0.83%)

Token

Stable Diffusion (SD)
 

Overview

Max Total Supply

43 SD

Holders

29

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 SD
0x91b7ed3ce1170cf9a48f4156df39fbe9b29c82eb
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:
AIGC_NFT

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-05-23
*/

// Sources flattened with hardhat v2.19.2 https://hardhat.org

// SPDX-License-Identifier: MIT AND UNLICENSED

// File @openzeppelin/contracts/utils/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}


// File @openzeppelin/contracts/access/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

/**
 * @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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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 {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

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


// File @openzeppelin/contracts/utils/introspection/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @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/interfaces/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(
        uint256 tokenId,
        uint256 salePrice
    ) external view returns (address receiver, uint256 royaltyAmount);
}


// File @openzeppelin/contracts/interfaces/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}


// File @openzeppelin/contracts/token/ERC721/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;

/**
 * @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 address zero.
     *
     * 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/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.20;

/**
 * @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/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.20;

/**
 * @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/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

/**
 * @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);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}


// File @openzeppelin/contracts/utils/math/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @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 towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (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 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 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.

            uint256 twos = denominator & (0 - denominator);
            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 (unsignedRoundsUp(rounding) && 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
     * towards zero.
     *
     * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * 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 256, 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}


// File @openzeppelin/contracts/utils/math/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

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

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}


// File @openzeppelin/contracts/utils/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)

pragma solidity ^0.8.20;


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

    /**
     * @dev The `value` string doesn't fit in the specified `length`.
     */
    error StringsInsufficientHexLength(uint256 value, uint256 length);

    /**
     * @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), HEX_DIGITS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toStringSigned(int256 value) internal pure returns (string memory) {
        return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
    }

    /**
     * @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) {
        uint256 localValue = value;
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = HEX_DIGITS[localValue & 0xf];
            localValue >>= 4;
        }
        if (localValue != 0) {
            revert StringsInsufficientHexLength(value, length);
        }
        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);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
    }
}


// File @openzeppelin/contracts/token/ERC721/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.20;







/**
 * @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}.
 */
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    mapping(uint256 tokenId => address) private _owners;

    mapping(address owner => uint256) private _balances;

    mapping(uint256 tokenId => address) private _tokenApprovals;

    mapping(address owner => mapping(address operator => 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 returns (uint256) {
        if (owner == address(0)) {
            revert ERC721InvalidOwner(address(0));
        }
        return _balances[owner];
    }

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

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

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

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

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string.concat(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 {
        _approve(to, tokenId, _msgSender());
    }

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

        return _getApproved(tokenId);
    }

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists
        // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.
        address previousOwner = _update(to, tokenId, _msgSender());
        if (previousOwner != from) {
            revert ERC721IncorrectOwner(from, tokenId, previousOwner);
        }
    }

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
        transferFrom(from, to, tokenId);
        _checkOnERC721Received(from, to, tokenId, data);
    }

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     *
     * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
     * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances
     * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by
     * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.
     */
    function _getApproved(uint256 tokenId) internal view virtual returns (address) {
        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in
     * particular (ignoring whether it is owned by `owner`).
     *
     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
     * assumption.
     */
    function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
        return
            spender != address(0) &&
            (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
    }

    /**
     * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.
     * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets
     * the `spender` for the specific `tokenId`.
     *
     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
     * assumption.
     */
    function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
        if (!_isAuthorized(owner, spender, tokenId)) {
            if (owner == address(0)) {
                revert ERC721NonexistentToken(tokenId);
            } else {
                revert ERC721InsufficientApproval(spender, tokenId);
            }
        }
    }

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that
     * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.
     *
     * WARNING: Increasing an account's balance using this function tends to be paired with an override of the
     * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership
     * remain consistent with one another.
     */
    function _increaseBalance(address account, uint128 value) internal virtual {
        unchecked {
            _balances[account] += value;
        }
    }

    /**
     * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner
     * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.
     *
     * The `auth` argument is optional. If the value passed is non 0, then this function will check that
     * `auth` is either the owner of the token, or approved to operate on the token (by the owner).
     *
     * Emits a {Transfer} event.
     *
     * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.
     */
    function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
        address from = _ownerOf(tokenId);

        // Perform (optional) operator check
        if (auth != address(0)) {
            _checkAuthorized(from, auth, tokenId);
        }

        // Execute the update
        if (from != address(0)) {
            // Clear approval. No need to re-authorize or emit the Approval event
            _approve(address(0), tokenId, address(0), false);

            unchecked {
                _balances[from] -= 1;
            }
        }

        if (to != address(0)) {
            unchecked {
                _balances[to] += 1;
            }
        }

        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        return from;
    }

    /**
     * @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 {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        address previousOwner = _update(to, tokenId, address(0));
        if (previousOwner != address(0)) {
            revert ERC721InvalidSender(address(0));
        }
    }

    /**
     * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.
     *
     * 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 {
        _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);
        _checkOnERC721Received(address(0), to, tokenId, data);
    }

    /**
     * @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 {
        address previousOwner = _update(address(0), tokenId, address(0));
        if (previousOwner == address(0)) {
            revert ERC721NonexistentToken(tokenId);
        }
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        address previousOwner = _update(to, tokenId, address(0));
        if (previousOwner == address(0)) {
            revert ERC721NonexistentToken(tokenId);
        } else if (previousOwner != from) {
            revert ERC721IncorrectOwner(from, tokenId, previousOwner);
        }
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients
     * are aware of the ERC721 standard 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 like {safeTransferFrom} in the sense that it invokes
     * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `tokenId` token must exist and be owned by `from`.
     * - `to` cannot be the zero address.
     * - `from` cannot be the zero address.
     * - 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) internal {
        _safeTransfer(from, to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
        _transfer(from, to, tokenId);
        _checkOnERC721Received(from, to, tokenId, data);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is
     * either the owner of the token, or approved to operate on all tokens held by this owner.
     *
     * Emits an {Approval} event.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address to, uint256 tokenId, address auth) internal {
        _approve(to, tokenId, auth, true);
    }

    /**
     * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not
     * emitted in the context of transfers.
     */
    function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {
        // Avoid reading the owner unless necessary
        if (emitEvent || auth != address(0)) {
            address owner = _requireOwned(tokenId);

            // We do not use _isAuthorized because single-token approvals should not be able to call approve
            if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
                revert ERC721InvalidApprover(auth);
            }

            if (emitEvent) {
                emit Approval(owner, to, tokenId);
            }
        }

        _tokenApprovals[tokenId] = to;
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Requirements:
     * - operator can't be the address zero.
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
        if (operator == address(0)) {
            revert ERC721InvalidOperator(operator);
        }
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).
     * Returns the owner.
     *
     * Overrides to ownership logic should be done to {_ownerOf}.
     */
    function _requireOwned(uint256 tokenId) internal view returns (address) {
        address owner = _ownerOf(tokenId);
        if (owner == address(0)) {
            revert ERC721NonexistentToken(tokenId);
        }
        return owner;
    }

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the
     * recipient doesn't accept the token transfer. 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
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
        if (to.code.length > 0) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                if (retval != IERC721Receiver.onERC721Received.selector) {
                    revert ERC721InvalidReceiver(to);
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert ERC721InvalidReceiver(to);
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
    }
}


// File @openzeppelin/contracts/utils/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @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 or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * 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.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @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`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

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

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) 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 FailedInnerCall();
        }
    }
}


// File contracts/IAIOracle.sol

// SampleContract.sol
// Original license: SPDX_License_Identifier: MIT
pragma solidity ^0.8.9;

interface IAIOracle {
    /// @notice Event emitted upon receiving a callback request through requestCallback.
    event AICallbackRequest(
        address indexed account,
        uint256 indexed requestId,
        uint256 modelId,
        bytes input,
        address callbackContract,
        uint64 gasLimit,
        bytes callbackData
    );

    /// @notice Event emitted when the result is uploaded or update.
    event AICallbackResult(
        address indexed account,
        uint256 indexed requestId,
        address invoker,
        bytes output
    );

    /**
     * initiate a request in OAO
     * @param modelId ID for AI model
     * @param input input for AI model
     * @param callbackContract address of callback contract
     * @param gasLimit gas limitation of calling the callback function
     * @param callbackData optional, user-defined data, will send back to the callback function
     * @return requestID
     */
    function requestCallback(
        uint256 modelId,
        bytes memory input,
        address callbackContract,
        uint64 gasLimit,
        bytes memory callbackData
    ) external payable returns (uint256);

    function estimateFee(uint256 modelId, uint256 gasLimit) external view returns (uint256);

    function isFinalized(uint256 requestId) external view returns (bool);
}


// File contracts/AIOracleCallbackReceiver.sol

// SampleContract.sol
// Original license: SPDX_License_Identifier: MIT
pragma solidity ^0.8.9;

/// @notice A base contract for writing a AIOracle app
abstract contract AIOracleCallbackReceiver {

    // Address of the AIOracle contract
    IAIOracle public immutable aiOracle;

    // Invalid callback source error
    error UnauthorizedCallbackSource(IAIOracle expected, IAIOracle found);

    /// @notice Initialize the contract, binding it to a specified AIOracle contract
    constructor(IAIOracle _aiOracle) {
        aiOracle = _aiOracle;
    }

    /// @notice Verify this is a callback by the aiOracle contract 
    modifier onlyAIOracleCallback() {
        IAIOracle foundRelayAddress = IAIOracle(msg.sender);
        if (foundRelayAddress != aiOracle) {
            revert UnauthorizedCallbackSource(aiOracle, foundRelayAddress);
        }
        _;
    }

    /**
     * @dev the callback function in OAO, should add the modifier onlyAIOracleCallback!
     * @param requestId Id for the request in OAO (unique per request)
     * @param output AI model's output
     * @param callbackData user-defined data (The same as when the user call aiOracle.requestCallback)
     */
    function aiOracleCallback(uint256 requestId, bytes calldata output, bytes calldata callbackData) external virtual;

    function isFinalized(uint256 requestId) external view returns (bool) {
        return aiOracle.isFinalized(requestId);
    }
}


// File contracts/IERC7007.sol

// Original license: SPDX_License_Identifier: UNLICENSED
pragma solidity ^0.8.23;


/**
 * @dev Required interface of an ERC7007 compliant contract.
 */
interface IERC7007 is IERC165, IERC721 {
    /**
     * @dev Emitted when AI Generated Content (AIGC) data is added to token at `tokenId`.
     */
    event AigcData(
        uint256 indexed tokenId,
        bytes indexed prompt,
        bytes aigcData,
        bytes proof
    );

    /**
     * @dev Add AIGC data to token at `tokenId` given `prompt`, `aigcData` and `proof`.
     *
     * Optional:
     * - `proof` should not include `aigcData` to save gas.
     * - verify(`prompt`, `aigcData`, `proof`) should return true for zkML scenario.
     */
    function addAigcData(
        uint256 tokenId,
        bytes calldata prompt,
        bytes calldata aigcData,
        bytes calldata proof
    ) external;

    /**
     * @dev Verify the `prompt`, `aigcData` and `proof`.
     */
    function verify(
        bytes calldata prompt,
        bytes calldata aigcData,
        bytes calldata proof
    ) external view returns (bool success);
}


// File contracts/IERC7007Updatable.sol

// Original license: SPDX_License_Identifier: UNLICENSED
pragma solidity ^0.8.23;

/**
 * @title ERC7007 Token Standard, optional updatable extension
 */
interface IERC7007Updatable is IERC7007 {
    /**
     * @dev Update the `aigcData` of `prompt`.
     */
    function update(
        bytes calldata prompt,
        bytes calldata aigcData
    ) external;

    /**
     * @dev Emitted when `tokenId` token is updated.
     */
    event Update(
        uint256 indexed tokenId,
        bytes indexed prompt,
        bytes indexed aigcData
    );
}


// File contracts/IOpmlLib.sol

// Original license: SPDX_License_Identifier: UNLICENSED
pragma solidity ^0.8.23;

interface IOpmlLib {
    function initOpmlRequest(bytes calldata input) external returns (uint256 requestId);
	function uploadResult(uint256 requestId, bytes calldata output) external;
	function startChallenge(uint256 requestId, bytes32 finalState) external returns (uint256 challengeId);
	function respondState(uint256 challengeId, bytes32 stateHash) external;
	function proposeState(uint256 challengeId, bytes32 stateHash) external;
	function assertStateTransition(uint256 challengeId) external;
    function isFinalized(uint256 requestId) external view returns (bool);
	function getOutput(uint256 requestId) external view returns (bytes memory output);
}


// File contracts/AIGC_NFT.sol

// Original license: SPDX_License_Identifier: MIT
pragma solidity ^0.8.23;

// ref: https://sepolia.etherscan.io/address/0xe75af5294f4CB4a8423ef8260595a54298c7a2FB#code








contract AIGC_NFT is IERC2981, IERC7007Updatable, AIOracleCallbackReceiver, Ownable, ERC721 {

    using Address for address;

    uint256 public immutable aiModelId;
    address public immutable opmlLib;

    uint256 public mintPrice;
    uint256 public totalSupply;
    bool public hasStartMint;

    address public royaltyReceiver = 0xc9510F57FB32d75Df4316D2b7BB3c0A75A4b4592;
    uint256 public royaltyPercentage = 10;

    /// @notice Gas limit set on the callback from AIOracle.
    /// @dev Should be set to the maximum amount of gas your callback might reasonably consume.
    uint64 public aiOracleCallbackGasLimit = 500000; // default sd: 500k
    // mapping(address => uint256) public _mintedCounts;

    struct AIGC_Token {
        string prompt;
        string neg_prompt;
        string title;
        uint256 seed;
        address author;
    }

    struct AIOracleRequest {
        address sender;
        uint256 modelId;
        bytes input;
        bytes output;
    }

    mapping(uint256 => AIGC_Token) public AIGC_tokens; // token ID => xx
    mapping(uint256 => AIOracleRequest) public requests;
    mapping(bytes => uint256) public promptSeedToTokenId;
    mapping(uint256 => mapping(string => string)) public prompts;
    mapping (uint256 => uint256) public tokenIdToRequestId;

    event promptsUpdated(
        uint256 requestId,
        uint256 modelId,
        string input,
        string output,
        bytes callbackData
    );

    event promptRequest(
        uint256 requestId,
        address sender, 
        uint256 modelId,
        string prompt
    );

    constructor(
      IAIOracle _aiOracle,
      string memory _name,
      string memory _symbol,
      uint256 _mintPrice,
      uint256 _aiModelId,
      address _opmlLib
    )
      AIOracleCallbackReceiver(_aiOracle)
      ERC721(_name, _symbol)
      Ownable(msg.sender) {
        mintPrice = _mintPrice;
        // maxMintLimitPerAddr = _maxMintLimitPerAddr;
        // maxSupply = _maxSupply;
        // mintStartTime = _mintStartTime;
        aiModelId = _aiModelId;
        opmlLib = _opmlLib;
      }

    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        receiver = royaltyReceiver;
        royaltyAmount = (salePrice * royaltyPercentage) / 100;
    }

    // Function to set the royalty receiver
    function setRoyaltyReceiver(address _receiver) external onlyOwner {
        royaltyReceiver = _receiver;
    }

    function encode(string memory prompt, uint256 seed) public pure returns (bytes memory) {
        bytes memory data = abi.encodePacked(seed, prompt);
        return data;
    } 

    function getAIResultFromTokenId(uint256 tokenId) public view returns (string memory) {
        if (AIGC_tokens[tokenId].seed == 0) {
            return prompts[aiModelId][string(abi.encodePacked(AIGC_tokens[tokenId].prompt, "---", AIGC_tokens[tokenId].neg_prompt))];
        }
        bytes memory data = abi.encodePacked(AIGC_tokens[tokenId].seed, string(abi.encodePacked(AIGC_tokens[tokenId].prompt, "---", AIGC_tokens[tokenId].neg_prompt)));
        return prompts[aiModelId][string(data)];
    }

    function startOrStopMint() external onlyOwner {
        hasStartMint = !hasStartMint;
    }

    /**
     * @dev See {IERC7007-addAigcData}.
     */
    function addAigcData(
        uint256 tokenId,
        bytes calldata prompt,
        bytes calldata aigcData,
        bytes calldata proof
    ) public virtual override {
        tokenIdToRequestId[tokenId] = IOpmlLib(opmlLib).initOpmlRequest(prompt);
        IOpmlLib(opmlLib).uploadResult(tokenIdToRequestId[tokenId], aigcData);
        emit AigcData(tokenId, prompt, aigcData, proof);
    }

    /**
     * @dev See {IERC7007-verify}.
     */
    function verify(
        bytes calldata prompt,
        bytes calldata aigcData,
        bytes calldata proof
    ) public view virtual override returns (bool success) {
        uint256 tokenId = promptSeedToTokenId[prompt];
        bytes memory output = IOpmlLib(opmlLib).getOutput(tokenIdToRequestId[tokenId]);

        return IOpmlLib(opmlLib).isFinalized(tokenIdToRequestId[tokenId]) && (keccak256(output) == keccak256(aigcData));
    }

     /**
     * @dev See {IERC7007Updatable-update}.
     */
    function update(
        bytes calldata prompt,
        bytes calldata aigcData
    ) public virtual override {
        require(verify(prompt, aigcData, prompt), "ERC7007: invalid aigcData"); // proof argument is not used in verify() function for opML, so we can pass prompt as proof
        uint256 tokenId = promptSeedToTokenId[prompt];
        emit Update(tokenId, prompt, aigcData);
    }

    function updateAIOracleCallbackGasLimit(uint64 _gasLimit) external onlyOwner {
        aiOracleCallbackGasLimit = _gasLimit;
    }

    // only the AI Oracle can call this function
    function aiOracleCallback(uint256 requestId, bytes calldata output, bytes calldata callbackData) external override onlyAIOracleCallback() {
        AIOracleRequest storage request = requests[requestId];
        require(request.sender != address(0), "request not exists");
        prompts[aiModelId][string(request.input)] = string(output);
        emit promptsUpdated(requestId, request.modelId, string(request.input), string(output), callbackData);
    }

    function calculateAIResult(string memory prompt, uint256 seed) internal {
        bytes memory input = abi.encodePacked(seed, prompt);
        // we do not need to set the callbackData in this example
        uint256 requestId = aiOracle.requestCallback{value: msg.value}(
            aiModelId, input, address(this), aiOracleCallbackGasLimit, ""
        );
        AIOracleRequest storage request = requests[requestId];
        request.input = input;
        request.sender = msg.sender;
        request.modelId = aiModelId;
        emit promptRequest(requestId, msg.sender, aiModelId, prompt);
    }

    function estimateOAOFee() public view returns (uint256) {
        return aiOracle.estimateFee(aiModelId, aiOracleCallbackGasLimit);
    }
    function estimateTotalFee() public view returns (uint256) {
        return estimateOAOFee() + mintPrice;
    }
  
    /// NFT related
    function mint(address to, string calldata positive_prompt, string calldata neg_prompt, string calldata title, uint256 seed) external payable returns (uint256 tokenId) {
        // check time
        require(hasStartMint, "Sale not started");
        string memory prompt = string(abi.encodePacked(positive_prompt, "---", neg_prompt));
        require(promptSeedToTokenId[encode(prompt, seed)] == 0, "prompt and seed has already minted");
        // check fund
        require(msg.value >= estimateTotalFee(), "Not enough fund to mint NFT");
        
        // calculate AI result
        AIGC_tokens[totalSupply] = AIGC_Token(positive_prompt, neg_prompt, title, seed, to);
        calculateAIResult(prompt, seed);
        // mint
        super._safeMint(to, totalSupply);
        // increase minted count
        // _mintedCounts[to] ++;

        totalSupply ++;
        promptSeedToTokenId[encode(prompt, seed)] = totalSupply; // actual value is minus 1

        return totalSupply - 1;
    }

    /// @dev Withdraw. The contract owner can withdraw all ETH from the NFT sale
    function withdraw() external onlyOwner {
        Address.sendValue(payable(_msgSender()), address(this).balance);
    }

    function tokenURI(uint256 tokenId) override public view returns (string memory) {
      string memory json = Base64.encode(bytes(string(abi.encodePacked(
        '{"name":"', AIGC_tokens[tokenId].title, '", "attributes": [{"trait_type": "positive_prompt", "value": "', AIGC_tokens[tokenId].prompt, '"}, {"trait_type": "negative_prompt", "value": "', AIGC_tokens[tokenId].neg_prompt, '"}, {"trait_type": "seed", "value": "', toString(AIGC_tokens[tokenId].seed), '"}, {"trait_type": "author", "value": "0x', toAsciiString(AIGC_tokens[tokenId].author), '"}, {"trait_type": "model", "value": "Stable Diffusion"}], "description": "Stable Diffusion is a latent text-to-image diffusion model capable of generating photo-realistic images given any text input.", "image": "https://gateway.pinata.cloud/ipfs/', getAIResultFromTokenId(tokenId), '"}'))));
      string memory output = string(abi.encodePacked('data:application/json;base64,', json));

      return output;
    }

    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

function toAsciiString(address x) pure returns (string memory) {
    bytes memory s = new bytes(40);
    for (uint i = 0; i < 20; i++) {
        bytes1 b = bytes1(uint8(uint(uint160(x)) / (2**(8*(19 - i)))));
        bytes1 hi = bytes1(uint8(b) / 16);
        bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi));
        s[2*i] = char(hi);
        s[2*i+1] = char(lo);            
    }
    return string(s);
}

function char(bytes1 b) pure returns (bytes1 c) {
    if (uint8(b) < 10) return bytes1(uint8(b) + 0x30);
    else return bytes1(uint8(b) + 0x57);
}

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IAIOracle","name":"_aiOracle","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_mintPrice","type":"uint256"},{"internalType":"uint256","name":"_aiModelId","type":"uint256"},{"internalType":"address","name":"_opmlLib","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"contract IAIOracle","name":"expected","type":"address"},{"internalType":"contract IAIOracle","name":"found","type":"address"}],"name":"UnauthorizedCallbackSource","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"bytes","name":"prompt","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"aigcData","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"proof","type":"bytes"}],"name":"AigcData","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"bytes","name":"prompt","type":"bytes"},{"indexed":true,"internalType":"bytes","name":"aigcData","type":"bytes"}],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"modelId","type":"uint256"},{"indexed":false,"internalType":"string","name":"prompt","type":"string"}],"name":"promptRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"modelId","type":"uint256"},{"indexed":false,"internalType":"string","name":"input","type":"string"},{"indexed":false,"internalType":"string","name":"output","type":"string"},{"indexed":false,"internalType":"bytes","name":"callbackData","type":"bytes"}],"name":"promptsUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"AIGC_tokens","outputs":[{"internalType":"string","name":"prompt","type":"string"},{"internalType":"string","name":"neg_prompt","type":"string"},{"internalType":"string","name":"title","type":"string"},{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"address","name":"author","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"prompt","type":"bytes"},{"internalType":"bytes","name":"aigcData","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"addAigcData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"aiModelId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aiOracle","outputs":[{"internalType":"contract IAIOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"bytes","name":"output","type":"bytes"},{"internalType":"bytes","name":"callbackData","type":"bytes"}],"name":"aiOracleCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"aiOracleCallbackGasLimit","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"prompt","type":"string"},{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"encode","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"estimateOAOFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimateTotalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getAIResultFromTokenId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasStartMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"isFinalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"positive_prompt","type":"string"},{"internalType":"string","name":"neg_prompt","type":"string"},{"internalType":"string","name":"title","type":"string"},{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"opmlLib","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"promptSeedToTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"string","name":"","type":"string"}],"name":"prompts","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requests","outputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"modelId","type":"uint256"},{"internalType":"bytes","name":"input","type":"bytes"},{"internalType":"bytes","name":"output","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"setRoyaltyReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startOrStopMint","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":"","type":"uint256"}],"name":"tokenIdToRequestId","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":[{"internalType":"bytes","name":"prompt","type":"bytes"},{"internalType":"bytes","name":"aigcData","type":"bytes"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_gasLimit","type":"uint64"}],"name":"updateAIOracleCallbackGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"prompt","type":"bytes"},{"internalType":"bytes","name":"aigcData","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"verify","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e06040526009805474c9510f57fb32d75df4316d2b7bb3c0a75a4b459200610100600160a81b0319909116179055600a8055600b80546001600160401b0319166207a12017905534801562000053575f80fd5b5060405162003f8138038062003f8183398101604081905262000076916200021e565b6001600160a01b03861660805284843380620000ab57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b620000b681620000f6565b506001620000c583826200034a565b506002620000d482826200034a565b50505060079290925560a0526001600160a01b031660c0525062000416915050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200015a575f80fd5b50565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011262000181575f80fd5b81516001600160401b03808211156200019e576200019e6200015d565b604051601f8301601f19908116603f01168101908282118183101715620001c957620001c96200015d565b8160405283815260209250866020858801011115620001e6575f80fd5b5f91505b83821015620002095785820183015181830184015290820190620001ea565b5f602085830101528094505050505092915050565b5f805f805f8060c0878903121562000234575f80fd5b8651620002418162000145565b60208801519096506001600160401b03808211156200025e575f80fd5b6200026c8a838b0162000171565b9650604089015191508082111562000282575f80fd5b506200029189828a0162000171565b945050606087015192506080870151915060a0870151620002b28162000145565b809150509295509295509295565b600181811c90821680620002d557607f821691505b602082108103620002f457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156200034557805f5260205f20601f840160051c81016020851015620003215750805b601f840160051c820191505b8181101562000342575f81556001016200032d565b50505b505050565b81516001600160401b038111156200036657620003666200015d565b6200037e81620003778454620002c0565b84620002fa565b602080601f831160018114620003b4575f84156200039c5750858301515b5f19600386901b1c1916600185901b1785556200040e565b5f85815260208120601f198616915b82811015620003e457888601518255948401946001909101908401620003c3565b50858210156200040257878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b60805160a05160c051613ad7620004aa5f395f81816103cb01528181611616015281816116b401528181611ae30152611b7f01525f818161073301528181610c5101528181610daa015281816118550152818161194501528181611f4a0152611ff401525f81816103fe01528181610a8801528181611783015281816117c00152818161197d0152611f1b0152613ad75ff3fe60806040526004361061026a575f3560e01c80637df047871161014a578063aea30507116100be578063c87b56dd11610078578063c87b56dd1461079c578063de8f50a1146107bb578063e985e9c5146107da578063ec3e5f45146107f9578063f2fde38b14610830578063f907dd041461084f575f80fd5b8063aea30507146106e4578063b034781414610703578063b0f7a3ff14610722578063b7b6ccd514610755578063b88d4fde14610769578063c1d88c4414610788575f80fd5b80638dc251e31161010f5780638dc251e31461063057806395d89b411461064f5780639ee74dd1146106635780639fbc871314610676578063a22cb4651461069a578063ad72e1a5146106b9575f80fd5b80637df047871461057a57806381d12c58146105b15780638a71bb2d146105e05780638cbc52d9146105f55780638da5cb5b14610614575f80fd5b80633c1c8e49116101e15780635bb4688d116101a65780635bb4688d146104cf5780636352211e146104ff5780636817c76c1461051e578063702de1e31461053357806370a0823114610547578063715018a614610566575f80fd5b80633c1c8e491461043f5780633ccfd60b1461045e5780633f37dce21461047257806342842e0e1461049157806358fd416d146104b0575f80fd5b806323b872dd1161023257806323b872dd1461033e5780632a55205a1461035d5780632cfb20801461039b5780632f03012e146103ba57806331b221cd146103ed57806333727c4d14610420575f80fd5b806301ffc9a71461026e57806306fdde03146102a2578063081812fc146102c3578063095ea7b3146102fa57806318160ddd1461031b575b5f80fd5b348015610279575f80fd5b5061028d610288366004612866565b610868565b60405190151581526020015b60405180910390f35b3480156102ad575f80fd5b506102b66108b9565b60405161029991906128d5565b3480156102ce575f80fd5b506102e26102dd3660046128e7565b610949565b6040516001600160a01b039091168152602001610299565b348015610305575f80fd5b50610319610314366004612914565b610970565b005b348015610326575f80fd5b5061033060085481565b604051908152602001610299565b348015610349575f80fd5b5061031961035836600461293c565b61097f565b348015610368575f80fd5b5061037c610377366004612975565b610a0d565b604080516001600160a01b039093168352602083019190915201610299565b3480156103a6575f80fd5b506103196103b5366004612995565b610a45565b3480156103c5575f80fd5b506102e27f000000000000000000000000000000000000000000000000000000000000000081565b3480156103f8575f80fd5b506102e27f000000000000000000000000000000000000000000000000000000000000000081565b34801561042b575f80fd5b5061028d61043a3660046128e7565b610a70565b34801561044a575f80fd5b506102b6610459366004612a77565b610af9565b348015610469575f80fd5b50610319610b27565b34801561047d575f80fd5b5061031961048c366004612afc565b610b3b565b34801561049c575f80fd5b506103196104ab36600461293c565b610c17565b3480156104bb575f80fd5b506102b66104ca3660046128e7565b610c36565b3480156104da575f80fd5b506104ee6104e93660046128e7565b610e82565b604051610299959493929190612b62565b34801561050a575f80fd5b506102e26105193660046128e7565b61104b565b348015610529575f80fd5b5061033060075481565b34801561053e575f80fd5b50610330611055565b348015610552575f80fd5b50610330610561366004612bbd565b611070565b348015610571575f80fd5b506103196110b5565b348015610585575f80fd5b50610330610594366004612bd6565b8051602081830181018051600e8252928201919093012091525481565b3480156105bc575f80fd5b506105d06105cb3660046128e7565b6110c6565b6040516102999493929190612c07565b3480156105eb575f80fd5b50610330600a5481565b348015610600575f80fd5b506102b661060f366004612c4a565b611204565b34801561061f575f80fd5b505f546001600160a01b03166102e2565b34801561063b575f80fd5b5061031961064a366004612bbd565b6112b7565b34801561065a575f80fd5b506102b66112e7565b610330610671366004612c8d565b6112f6565b348015610681575f80fd5b506009546102e29061010090046001600160a01b031681565b3480156106a5575f80fd5b506103196106b4366004612d43565b6115f4565b3480156106c4575f80fd5b506103306106d33660046128e7565b60106020525f908152604090205481565b3480156106ef575f80fd5b506103196106fe366004612d78565b6115ff565b34801561070e575f80fd5b5061031961071d366004612e13565b611778565b34801561072d575f80fd5b506103307f000000000000000000000000000000000000000000000000000000000000000081565b348015610760575f80fd5b50610319611901565b348015610774575f80fd5b50610319610783366004612e86565b61191d565b348015610793575f80fd5b50610330611934565b3480156107a7575f80fd5b506102b66107b63660046128e7565b6119ed565b3480156107c6575f80fd5b5061028d6107d5366004612ee9565b611a9c565b3480156107e5575f80fd5b5061028d6107f4366004612f7b565b611c2b565b348015610804575f80fd5b50600b54610818906001600160401b031681565b6040516001600160401b039091168152602001610299565b34801561083b575f80fd5b5061031961084a366004612bbd565b611c58565b34801561085a575f80fd5b5060095461028d9060ff1681565b5f6001600160e01b031982166380ac58cd60e01b148061089857506001600160e01b03198216635b5e139f60e01b145b806108b357506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600180546108c890612fa3565b80601f01602080910402602001604051908101604052809291908181526020018280546108f490612fa3565b801561093f5780601f106109165761010080835404028352916020019161093f565b820191905f5260205f20905b81548152906001019060200180831161092257829003601f168201915b5050505050905090565b5f61095382611c95565b505f828152600560205260409020546001600160a01b03166108b3565b61097b828233611ccd565b5050565b6001600160a01b0382166109ad57604051633250574960e11b81525f60048201526024015b60405180910390fd5b5f6109b9838333611cda565b9050836001600160a01b0316816001600160a01b031614610a07576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016109a4565b50505050565b600954600a546101009091046001600160a01b0316905f90606490610a329085612fef565b610a3c919061301a565b90509250929050565b610a4d611dcc565b600b805467ffffffffffffffff19166001600160401b0392909216919091179055565b6040516333727c4d60e01b8152600481018290525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906333727c4d90602401602060405180830381865afa158015610ad5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b3919061302d565b60605f8284604051602001610b0f929190613063565b60408051808303601f19018152919052949350505050565b610b2f611dcc565b610b393347611df8565b565b610b49848484848888611a9c565b610b955760405162461bcd60e51b815260206004820152601960248201527f455243373030373a20696e76616c69642061696763446174610000000000000060448201526064016109a4565b5f600e8585604051610ba8929190613088565b908152604051908190036020018120549150610bc79084908490613088565b60405180910390208585604051610bdf929190613088565b6040519081900381209083907fd77aab0eeab3a3cbdac072fcdbc34709b18d6c4af91f7869c71cbbb13d71a6b9905f90a45050505050565b610c3183838360405180602001604052805f81525061191d565b505050565b5f818152600c602052604081206003015460609103610d52577f00000000000000000000000000000000000000000000000000000000000000005f908152600f60209081526040808320858452600c8352928190209051610c9c92600183019101613106565b60408051601f1981840301815290829052610cb691613130565b90815260200160405180910390208054610ccf90612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610cfb90612fa3565b8015610d465780601f10610d1d57610100808354040283529160200191610d46565b820191905f5260205f20905b815481529060010190602001808311610d2957829003601f168201915b50505050509050919050565b5f828152600c60209081526040808320600381015491519192610d7a92600183019101613106565b60408051601f1981840301815290829052610d989291602001613063565b60408051601f198184030181528282527f00000000000000000000000000000000000000000000000000000000000000005f908152600f6020529190912090925090610de5908390613130565b90815260200160405180910390208054610dfe90612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610e2a90612fa3565b8015610e755780601f10610e4c57610100808354040283529160200191610e75565b820191905f5260205f20905b815481529060010190602001808311610e5857829003601f168201915b5050505050915050919050565b600c6020525f9081526040902080548190610e9c90612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ec890612fa3565b8015610f135780601f10610eea57610100808354040283529160200191610f13565b820191905f5260205f20905b815481529060010190602001808311610ef657829003601f168201915b505050505090806001018054610f2890612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5490612fa3565b8015610f9f5780601f10610f7657610100808354040283529160200191610f9f565b820191905f5260205f20905b815481529060010190602001808311610f8257829003601f168201915b505050505090806002018054610fb490612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610fe090612fa3565b801561102b5780601f106110025761010080835404028352916020019161102b565b820191905f5260205f20905b81548152906001019060200180831161100e57829003601f168201915b5050505060038301546004909301549192916001600160a01b0316905085565b5f6108b382611c95565b5f600754611061611934565b61106b919061314b565b905090565b5f6001600160a01b03821661109a576040516322718ad960e21b81525f60048201526024016109a4565b506001600160a01b03165f9081526004602052604090205490565b6110bd611dcc565b610b395f611e8b565b600d6020525f90815260409020805460018201546002830180546001600160a01b039093169391926110f790612fa3565b80601f016020809104026020016040519081016040528092919081815260200182805461112390612fa3565b801561116e5780601f106111455761010080835404028352916020019161116e565b820191905f5260205f20905b81548152906001019060200180831161115157829003601f168201915b50505050509080600301805461118390612fa3565b80601f01602080910402602001604051908101604052809291908181526020018280546111af90612fa3565b80156111fa5780601f106111d1576101008083540402835291602001916111fa565b820191905f5260205f20905b8154815290600101906020018083116111dd57829003601f168201915b5050505050905084565b600f60209081525f928352604090922081518083018401805192815290840192909301919091209152805461123890612fa3565b80601f016020809104026020016040519081016040528092919081815260200182805461126490612fa3565b80156112af5780601f10611286576101008083540402835291602001916112af565b820191905f5260205f20905b81548152906001019060200180831161129257829003601f168201915b505050505081565b6112bf611dcc565b600980546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6060600280546108c890612fa3565b6009545f9060ff1661133d5760405162461bcd60e51b815260206004820152601060248201526f14d85b19481b9bdd081cdd185c9d195960821b60448201526064016109a4565b5f88888888604051602001611355949392919061315e565b6040516020818303038152906040529050600e6113728285610af9565b60405161137f9190613130565b9081526020016040518091039020545f146113e75760405162461bcd60e51b815260206004820152602260248201527f70726f6d707420616e6420736565642068617320616c7265616479206d696e74604482015261195960f21b60648201526084016109a4565b6113ef611055565b34101561143e5760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420656e6f7567682066756e6420746f206d696e74204e4654000000000060448201526064016109a4565b6040518060a001604052808a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250505090825250604080516020601f8b0181900481028201810190925289815291810191908a908a90819084018382808284375f92019190915250505090825250604080516020601f8901819004810282018101909252878152918101919088908890819084018382808284375f92018290525093855250505060208083018790526001600160a01b038e166040938401526008548252600c9052208151819061152490826131cd565b506020820151600182019061153990826131cd565b506040820151600282019061154e90826131cd565b5060608201516003820155608090910151600490910180546001600160a01b0319166001600160a01b0390921691909117905561158b8184611eda565b6115978a60085461205b565b60088054905f6115a68361328c565b9190505550600854600e6115ba8386610af9565b6040516115c79190613130565b908152604051908190036020019020556008546115e6906001906132a4565b9a9950505050505050505050565b61097b338383612074565b60405163c4be5cab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c4be5cab9061164d90899089906004016132df565b6020604051808303815f875af1158015611669573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061168d91906132f2565b5f888152601060205260409081902082905551630901e0f960e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163480f07c8916116ec919088908890600401613309565b5f604051808303815f87803b158015611703575f80fd5b505af1158015611715573d5f803e3d5ffd5b505050508585604051611729929190613088565b6040518091039020877f65deac95b53ba76b9cdc6cf446af81731e1218c91eaf9811a95d28bde23b893e868686866040516117679493929190613322565b60405180910390a350505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681146117f55760405163432e033760e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152821660248201526044016109a4565b5f868152600d6020526040902080546001600160a01b031661184e5760405162461bcd60e51b815260206004820152601260248201527172657175657374206e6f742065786973747360701b60448201526064016109a4565b8585600f5f7f000000000000000000000000000000000000000000000000000000000000000081526020019081526020015f20836002016040516118929190613348565b908152602001604051809103902091826118ad929190613353565b507faf2b2381ddcb18a2b18a7826186fd216acdd9c852a8c7a9a49e7eab127f96ccf87826001015483600201898989896040516118f0979695949392919061340c565b60405180910390a150505050505050565b611909611dcc565b6009805460ff19811660ff90911615179055565b61192884848461097f565b610a0784848484612112565b600b54604051620e1d8d60e41b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160401b0390911660248201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169062e1d8d090604401602060405180830381865afa1580156119c9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061106b91906132f2565b5f818152600c60205260408120600381015460609291611a70916002820191906001820190611a1b90612238565b5f888152600c6020526040902060040154611a3e906001600160a01b031661233c565b611a4789610c36565b604051602001611a5c969594939291906134c3565b604051602081830303815290604052612475565b90505f81604051602001611a849190613761565b60408051601f19818403018152919052949350505050565b5f80600e8888604051611ab0929190613088565b9081526040805160209281900383018120545f8181526010909452918320546317861f8760e01b825260048201529092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906317861f87906024015f60405180830381865afa158015611b2f573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611b5691908101906137a5565b5f83815260106020526040908190205490516333727c4d60e01b81529192506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916333727c4d91611bb69160040190815260200190565b602060405180830381865afa158015611bd1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bf5919061302d565b8015611c1e57508686604051611c0c929190613088565b60405180910390208180519060200120145b9998505050505050505050565b6001600160a01b039182165f90815260066020908152604080832093909416825291909152205460ff1690565b611c60611dcc565b6001600160a01b038116611c8957604051631e4fbdf760e01b81525f60048201526024016109a4565b611c9281611e8b565b50565b5f818152600360205260408120546001600160a01b0316806108b357604051637e27328960e01b8152600481018490526024016109a4565b610c3183838360016125d7565b5f828152600360205260408120546001600160a01b0390811690831615611d0657611d068184866126db565b6001600160a01b03811615611d4057611d215f855f806125d7565b6001600160a01b0381165f90815260046020526040902080545f190190555b6001600160a01b03851615611d6e576001600160a01b0385165f908152600460205260409020805460010190555b5f8481526003602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b5f546001600160a01b03163314610b395760405163118cdaa760e01b81523360048201526024016109a4565b80471015611e1b5760405163cd78605960e01b81523060048201526024016109a4565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611e64576040519150601f19603f3d011682016040523d82523d5f602084013e611e69565b606091505b5050905080610c3157604051630a12f52160e11b815260040160405180910390fd5b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f8183604051602001611eee929190613063565b60408051601f1981840301815290829052600b54632dca9c0360e11b83529092505f916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691635b953806913491611f80917f000000000000000000000000000000000000000000000000000000000000000091889130916001600160401b03169060040161380d565b60206040518083038185885af1158015611f9c573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611fc191906132f2565b5f818152600d6020526040902090915060028101611fdf84826131cd565b5080546001600160a01b0319163390811782557f0000000000000000000000000000000000000000000000000000000000000000600183018190556040517fa0faead83d70148ae18b694377f9bef079251342ab90e14af0f9ef68b891269f9261204c9286928a9061385d565b60405180910390a15050505050565b61097b828260405180602001604052805f81525061273f565b6001600160a01b0382166120a657604051630b61174360e31b81526001600160a01b03831660048201526024016109a4565b6001600160a01b038381165f81815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b15610a0757604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290612154903390889087908790600401613893565b6020604051808303815f875af192505050801561218e575060408051601f3d908101601f1916820190925261218b918101906138c5565b60015b6121f5573d8080156121bb576040519150601f19603f3d011682016040523d82523d5f602084013e6121c0565b606091505b5080515f036121ed57604051633250574960e11b81526001600160a01b03851660048201526024016109a4565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b1461223157604051633250574960e11b81526001600160a01b03851660048201526024016109a4565b5050505050565b6060815f0361225e5750506040805180820190915260018152600360fc1b602082015290565b815f5b811561228757806122718161328c565b91506122809050600a8361301a565b9150612261565b5f816001600160401b038111156122a0576122a06129bb565b6040519080825280601f01601f1916602001820160405280156122ca576020820181803683370190505b5090505b8415612334576122df6001836132a4565b91506122ec600a866138e0565b6122f790603061314b565b60f81b81838151811061230c5761230c6138f3565b60200101906001600160f81b03191690815f1a90535061232d600a8661301a565b94506122ce565b949350505050565b60408051602880825260608281019093525f91906020820181803683370190505090505f5b601481101561246e575f6123768260136132a4565b612381906008612fef565b61238c9060026139e7565b61239f906001600160a01b03871661301a565b60f81b90505f60108260f81c6123b591906139f2565b60f81b90505f8160f81c60106123cb9190613a13565b8360f81c6123d99190613a2f565b60f81b90506123e782612755565b856123f3866002612fef565b81518110612403576124036138f3565b60200101906001600160f81b03191690815f1a90535061242281612755565b8561242e866002612fef565b61243990600161314b565b81518110612449576124496138f3565b60200101906001600160f81b03191690815f1a90535050600190920191506123619050565b5092915050565b80516060905f81900361249757505060408051602081019091525f8152919050565b5f60036124a583600261314b565b6124af919061301a565b6124ba906004612fef565b90505f6124c882602061314b565b6001600160401b038111156124df576124df6129bb565b6040519080825280601f01601f191660200182016040528015612509576020820181803683370190505b5090505f604051806060016040528060408152602001613a6260409139905060018101602083015f5b86811015612593576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101612532565b5060038606600181146125ad57600281146125be576125c9565b613d3d60f01b6001198301526125c9565b603d60f81b5f198301525b505050918152949350505050565b80806125eb57506001600160a01b03821615155b156126ac575f6125fa84611c95565b90506001600160a01b038316158015906126265750826001600160a01b0316816001600160a01b031614155b801561263957506126378184611c2b565b155b156126625760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016109a4565b81156126aa5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b50505f90815260056020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b6126e683838361278f565b610c31576001600160a01b03831661271457604051637e27328960e01b8152600481018290526024016109a4565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016109a4565b61274983836127f0565b610c315f848484612112565b5f600a60f883901c101561277b5761277260f883901c6030613a48565b60f81b92915050565b61277260f883901c6057613a48565b919050565b5f6001600160a01b038316158015906123345750826001600160a01b0316846001600160a01b031614806127c857506127c88484611c2b565b806123345750505f908152600560205260409020546001600160a01b03908116911614919050565b6001600160a01b03821661281957604051633250574960e11b81525f60048201526024016109a4565b5f61282583835f611cda565b90506001600160a01b03811615610c31576040516339e3563760e11b81525f60048201526024016109a4565b6001600160e01b031981168114611c92575f80fd5b5f60208284031215612876575f80fd5b813561288181612851565b9392505050565b5f5b838110156128a257818101518382015260200161288a565b50505f910152565b5f81518084526128c1816020860160208601612888565b601f01601f19169290920160200192915050565b602081525f61288160208301846128aa565b5f602082840312156128f7575f80fd5b5035919050565b80356001600160a01b038116811461278a575f80fd5b5f8060408385031215612925575f80fd5b61292e836128fe565b946020939093013593505050565b5f805f6060848603121561294e575f80fd5b612957846128fe565b9250612965602085016128fe565b9150604084013590509250925092565b5f8060408385031215612986575f80fd5b50508035926020909101359150565b5f602082840312156129a5575f80fd5b81356001600160401b0381168114612881575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156129f7576129f76129bb565b604052919050565b5f6001600160401b03821115612a1757612a176129bb565b50601f01601f191660200190565b5f82601f830112612a34575f80fd5b8135612a47612a42826129ff565b6129cf565b818152846020838601011115612a5b575f80fd5b816020850160208301375f918101602001919091529392505050565b5f8060408385031215612a88575f80fd5b82356001600160401b03811115612a9d575f80fd5b612aa985828601612a25565b95602094909401359450505050565b5f8083601f840112612ac8575f80fd5b5081356001600160401b03811115612ade575f80fd5b602083019150836020828501011115612af5575f80fd5b9250929050565b5f805f8060408587031215612b0f575f80fd5b84356001600160401b0380821115612b25575f80fd5b612b3188838901612ab8565b90965094506020870135915080821115612b49575f80fd5b50612b5687828801612ab8565b95989497509550505050565b60a081525f612b7460a08301886128aa565b8281036020840152612b8681886128aa565b90508281036040840152612b9a81876128aa565b606084019590955250506001600160a01b03919091166080909101529392505050565b5f60208284031215612bcd575f80fd5b612881826128fe565b5f60208284031215612be6575f80fd5b81356001600160401b03811115612bfb575f80fd5b61233484828501612a25565b60018060a01b0385168152836020820152608060408201525f612c2d60808301856128aa565b8281036060840152612c3f81856128aa565b979650505050505050565b5f8060408385031215612c5b575f80fd5b8235915060208301356001600160401b03811115612c77575f80fd5b612c8385828601612a25565b9150509250929050565b5f805f805f805f8060a0898b031215612ca4575f80fd5b612cad896128fe565b975060208901356001600160401b0380821115612cc8575f80fd5b612cd48c838d01612ab8565b909950975060408b0135915080821115612cec575f80fd5b612cf88c838d01612ab8565b909750955060608b0135915080821115612d10575f80fd5b50612d1d8b828c01612ab8565b999c989b50969995989497949560800135949350505050565b8015158114611c92575f80fd5b5f8060408385031215612d54575f80fd5b612d5d836128fe565b91506020830135612d6d81612d36565b809150509250929050565b5f805f805f805f6080888a031215612d8e575f80fd5b8735965060208801356001600160401b0380821115612dab575f80fd5b612db78b838c01612ab8565b909850965060408a0135915080821115612dcf575f80fd5b612ddb8b838c01612ab8565b909650945060608a0135915080821115612df3575f80fd5b50612e008a828b01612ab8565b989b979a50959850939692959293505050565b5f805f805f60608688031215612e27575f80fd5b8535945060208601356001600160401b0380821115612e44575f80fd5b612e5089838a01612ab8565b90965094506040880135915080821115612e68575f80fd5b50612e7588828901612ab8565b969995985093965092949392505050565b5f805f8060808587031215612e99575f80fd5b612ea2856128fe565b9350612eb0602086016128fe565b92506040850135915060608501356001600160401b03811115612ed1575f80fd5b612edd87828801612a25565b91505092959194509250565b5f805f805f8060608789031215612efe575f80fd5b86356001600160401b0380821115612f14575f80fd5b612f208a838b01612ab8565b90985096506020890135915080821115612f38575f80fd5b612f448a838b01612ab8565b90965094506040890135915080821115612f5c575f80fd5b50612f6989828a01612ab8565b979a9699509497509295939492505050565b5f8060408385031215612f8c575f80fd5b612f95836128fe565b9150610a3c602084016128fe565b600181811c90821680612fb757607f821691505b602082108103612fd557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176108b3576108b3612fdb565b634e487b7160e01b5f52601260045260245ffd5b5f8261302857613028613006565b500490565b5f6020828403121561303d575f80fd5b815161288181612d36565b5f8151613059818560208601612888565b9290920192915050565b8281525f825161307a816020850160208701612888565b919091016020019392505050565b818382375f9101908152919050565b5f81546130a381612fa3565b600182811680156130bb57600181146130d0576130fc565b60ff19841687528215158302870194506130fc565b855f526020805f205f5b858110156130f35781548a8201529084019082016130da565b50505082870194505b5050505092915050565b5f6131118285613097565b622d2d2d60e81b81526131276003820185613097565b95945050505050565b5f8251613141818460208701612888565b9190910192915050565b808201808211156108b3576108b3612fdb565b838582375f848201622d2d2d60e81b8152838560038301375f93016003019283525090949350505050565b601f821115610c3157805f5260205f20601f840160051c810160208510156131ae5750805b601f840160051c820191505b81811015612231575f81556001016131ba565b81516001600160401b038111156131e6576131e66129bb565b6131fa816131f48454612fa3565b84613189565b602080601f83116001811461322d575f84156132165750858301515b5f19600386901b1c1916600185901b178555613284565b5f85815260208120601f198616915b8281101561325b5788860151825594840194600190910190840161323c565b508582101561327857878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f6001820161329d5761329d612fdb565b5060010190565b818103818111156108b3576108b3612fdb565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f6123346020830184866132b7565b5f60208284031215613302575f80fd5b5051919050565b838152604060208201525f6131276040830184866132b7565b604081525f6133356040830186886132b7565b8281036020840152612c3f8185876132b7565b5f6128818284613097565b6001600160401b0383111561336a5761336a6129bb565b61337e836133788354612fa3565b83613189565b5f601f8411600181146133af575f85156133985750838201355b5f19600387901b1c1916600186901b178355612231565b5f83815260208120601f198716915b828110156133de57868501358255602094850194600190920191016133be565b50868210156133fa575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b8781525f602088602084015260a060408401525f885461342b81612fa3565b8060a087015260c060018084165f811461344c576001811461346857613495565b60ff19851660c08a015260c084151560051b8a01019550613495565b8d5f5260205f205f5b8581101561348c5781548b8201860152908301908801613471565b8a0160c0019650505b505050505083810360608501526134ad81888a6132b7565b91505082810360808401526115e68185876132b7565b683d913730b6b2911d1160b91b81525f6134e06009830189613097565b7f222c202261747472696275746573223a205b7b2274726169745f74797065223a81527f2022706f7369746976655f70726f6d7074222c202276616c7565223a202200006020820152613536603e820189613097565b7f227d2c207b2274726169745f74797065223a20226e656761746976655f70726f81526f36b83a111610113b30b63ab2911d101160811b602082015290506135816030820188613097565b90507f227d2c207b2274726169745f74797065223a202273656564222c202276616c7581526432911d101160d91b602082015285516135c7816025840160208a01612888565b7f227d2c207b2274726169745f74797065223a2022617574686f72222c2022766160259290910191820152680d8eaca4474404460f60bb1b6045820152611c1e61375361374d61361a604e850189613048565b7f227d2c207b2274726169745f74797065223a20226d6f64656c222c202276616c81527f7565223a2022537461626c6520446966667573696f6e227d5d2c20226465736360208201527f72697074696f6e223a2022537461626c6520446966667573696f6e206973206160408201527f206c6174656e7420746578742d746f2d696d61676520646966667573696f6e2060608201527f6d6f64656c2063617061626c65206f662067656e65726174696e672070686f7460808201527f6f2d7265616c697374696320696d6167657320676976656e20616e792074657860a08201527f7420696e7075742e222c2022696d616765223a202268747470733a2f2f67617460c08201527f657761792e70696e6174612e636c6f75642f697066732f00000000000000000060e082015260f70190565b86613048565b61227d60f01b815260020190565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081525f825161379881601d850160208701612888565b91909101601d0192915050565b5f602082840312156137b5575f80fd5b81516001600160401b038111156137ca575f80fd5b8201601f810184136137da575f80fd5b80516137e8612a42826129ff565b8181528560208385010111156137fc575f80fd5b613127826020830160208601612888565b84815260a060208201525f61382560a08301866128aa565b6001600160a01b03949094166040830152506001600160401b039190911660608201528082036080909101525f815260200192915050565b84815260018060a01b0384166020820152826040820152608060608201525f61388960808301846128aa565b9695505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90613889908301846128aa565b5f602082840312156138d5575f80fd5b815161288181612851565b5f826138ee576138ee613006565b500690565b634e487b7160e01b5f52603260045260245ffd5b600181815b8085111561394157815f190482111561392757613927612fdb565b8085161561393457918102915b93841c939080029061390c565b509250929050565b5f82613957575060016108b3565b8161396357505f6108b3565b816001811461397957600281146139835761399f565b60019150506108b3565b60ff84111561399457613994612fdb565b50506001821b6108b3565b5060208310610133831016604e8410600b84101617156139c2575081810a6108b3565b6139cc8383613907565b805f19048211156139df576139df612fdb565b029392505050565b5f6128818383613949565b5f60ff831680613a0457613a04613006565b8060ff84160491505092915050565b60ff818116838216029081169081811461246e5761246e612fdb565b60ff82811682821603908111156108b3576108b3612fdb565b60ff81811683821601908111156108b3576108b3612fdb56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212201553cb7a24a467fc48ae0ed4b38a9f006b48f63d4ea104b1eaf615c7a4fa26d764736f6c634300081700330000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b5f000000000000000000000000c3287bdef03b925a7c7f54791edadcd88e632ccd0000000000000000000000000000000000000000000000000000000000000010537461626c6520446966667573696f6e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025344000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361061026a575f3560e01c80637df047871161014a578063aea30507116100be578063c87b56dd11610078578063c87b56dd1461079c578063de8f50a1146107bb578063e985e9c5146107da578063ec3e5f45146107f9578063f2fde38b14610830578063f907dd041461084f575f80fd5b8063aea30507146106e4578063b034781414610703578063b0f7a3ff14610722578063b7b6ccd514610755578063b88d4fde14610769578063c1d88c4414610788575f80fd5b80638dc251e31161010f5780638dc251e31461063057806395d89b411461064f5780639ee74dd1146106635780639fbc871314610676578063a22cb4651461069a578063ad72e1a5146106b9575f80fd5b80637df047871461057a57806381d12c58146105b15780638a71bb2d146105e05780638cbc52d9146105f55780638da5cb5b14610614575f80fd5b80633c1c8e49116101e15780635bb4688d116101a65780635bb4688d146104cf5780636352211e146104ff5780636817c76c1461051e578063702de1e31461053357806370a0823114610547578063715018a614610566575f80fd5b80633c1c8e491461043f5780633ccfd60b1461045e5780633f37dce21461047257806342842e0e1461049157806358fd416d146104b0575f80fd5b806323b872dd1161023257806323b872dd1461033e5780632a55205a1461035d5780632cfb20801461039b5780632f03012e146103ba57806331b221cd146103ed57806333727c4d14610420575f80fd5b806301ffc9a71461026e57806306fdde03146102a2578063081812fc146102c3578063095ea7b3146102fa57806318160ddd1461031b575b5f80fd5b348015610279575f80fd5b5061028d610288366004612866565b610868565b60405190151581526020015b60405180910390f35b3480156102ad575f80fd5b506102b66108b9565b60405161029991906128d5565b3480156102ce575f80fd5b506102e26102dd3660046128e7565b610949565b6040516001600160a01b039091168152602001610299565b348015610305575f80fd5b50610319610314366004612914565b610970565b005b348015610326575f80fd5b5061033060085481565b604051908152602001610299565b348015610349575f80fd5b5061031961035836600461293c565b61097f565b348015610368575f80fd5b5061037c610377366004612975565b610a0d565b604080516001600160a01b039093168352602083019190915201610299565b3480156103a6575f80fd5b506103196103b5366004612995565b610a45565b3480156103c5575f80fd5b506102e27f000000000000000000000000c3287bdef03b925a7c7f54791edadcd88e632ccd81565b3480156103f8575f80fd5b506102e27f0000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a081565b34801561042b575f80fd5b5061028d61043a3660046128e7565b610a70565b34801561044a575f80fd5b506102b6610459366004612a77565b610af9565b348015610469575f80fd5b50610319610b27565b34801561047d575f80fd5b5061031961048c366004612afc565b610b3b565b34801561049c575f80fd5b506103196104ab36600461293c565b610c17565b3480156104bb575f80fd5b506102b66104ca3660046128e7565b610c36565b3480156104da575f80fd5b506104ee6104e93660046128e7565b610e82565b604051610299959493929190612b62565b34801561050a575f80fd5b506102e26105193660046128e7565b61104b565b348015610529575f80fd5b5061033060075481565b34801561053e575f80fd5b50610330611055565b348015610552575f80fd5b50610330610561366004612bbd565b611070565b348015610571575f80fd5b506103196110b5565b348015610585575f80fd5b50610330610594366004612bd6565b8051602081830181018051600e8252928201919093012091525481565b3480156105bc575f80fd5b506105d06105cb3660046128e7565b6110c6565b6040516102999493929190612c07565b3480156105eb575f80fd5b50610330600a5481565b348015610600575f80fd5b506102b661060f366004612c4a565b611204565b34801561061f575f80fd5b505f546001600160a01b03166102e2565b34801561063b575f80fd5b5061031961064a366004612bbd565b6112b7565b34801561065a575f80fd5b506102b66112e7565b610330610671366004612c8d565b6112f6565b348015610681575f80fd5b506009546102e29061010090046001600160a01b031681565b3480156106a5575f80fd5b506103196106b4366004612d43565b6115f4565b3480156106c4575f80fd5b506103306106d33660046128e7565b60106020525f908152604090205481565b3480156106ef575f80fd5b506103196106fe366004612d78565b6115ff565b34801561070e575f80fd5b5061031961071d366004612e13565b611778565b34801561072d575f80fd5b506103307f0000000000000000000000000000000000000000000000000000000000001b5f81565b348015610760575f80fd5b50610319611901565b348015610774575f80fd5b50610319610783366004612e86565b61191d565b348015610793575f80fd5b50610330611934565b3480156107a7575f80fd5b506102b66107b63660046128e7565b6119ed565b3480156107c6575f80fd5b5061028d6107d5366004612ee9565b611a9c565b3480156107e5575f80fd5b5061028d6107f4366004612f7b565b611c2b565b348015610804575f80fd5b50600b54610818906001600160401b031681565b6040516001600160401b039091168152602001610299565b34801561083b575f80fd5b5061031961084a366004612bbd565b611c58565b34801561085a575f80fd5b5060095461028d9060ff1681565b5f6001600160e01b031982166380ac58cd60e01b148061089857506001600160e01b03198216635b5e139f60e01b145b806108b357506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600180546108c890612fa3565b80601f01602080910402602001604051908101604052809291908181526020018280546108f490612fa3565b801561093f5780601f106109165761010080835404028352916020019161093f565b820191905f5260205f20905b81548152906001019060200180831161092257829003601f168201915b5050505050905090565b5f61095382611c95565b505f828152600560205260409020546001600160a01b03166108b3565b61097b828233611ccd565b5050565b6001600160a01b0382166109ad57604051633250574960e11b81525f60048201526024015b60405180910390fd5b5f6109b9838333611cda565b9050836001600160a01b0316816001600160a01b031614610a07576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016109a4565b50505050565b600954600a546101009091046001600160a01b0316905f90606490610a329085612fef565b610a3c919061301a565b90509250929050565b610a4d611dcc565b600b805467ffffffffffffffff19166001600160401b0392909216919091179055565b6040516333727c4d60e01b8152600481018290525f907f0000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a06001600160a01b0316906333727c4d90602401602060405180830381865afa158015610ad5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b3919061302d565b60605f8284604051602001610b0f929190613063565b60408051808303601f19018152919052949350505050565b610b2f611dcc565b610b393347611df8565b565b610b49848484848888611a9c565b610b955760405162461bcd60e51b815260206004820152601960248201527f455243373030373a20696e76616c69642061696763446174610000000000000060448201526064016109a4565b5f600e8585604051610ba8929190613088565b908152604051908190036020018120549150610bc79084908490613088565b60405180910390208585604051610bdf929190613088565b6040519081900381209083907fd77aab0eeab3a3cbdac072fcdbc34709b18d6c4af91f7869c71cbbb13d71a6b9905f90a45050505050565b610c3183838360405180602001604052805f81525061191d565b505050565b5f818152600c602052604081206003015460609103610d52577f0000000000000000000000000000000000000000000000000000000000001b5f5f908152600f60209081526040808320858452600c8352928190209051610c9c92600183019101613106565b60408051601f1981840301815290829052610cb691613130565b90815260200160405180910390208054610ccf90612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610cfb90612fa3565b8015610d465780601f10610d1d57610100808354040283529160200191610d46565b820191905f5260205f20905b815481529060010190602001808311610d2957829003601f168201915b50505050509050919050565b5f828152600c60209081526040808320600381015491519192610d7a92600183019101613106565b60408051601f1981840301815290829052610d989291602001613063565b60408051601f198184030181528282527f0000000000000000000000000000000000000000000000000000000000001b5f5f908152600f6020529190912090925090610de5908390613130565b90815260200160405180910390208054610dfe90612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610e2a90612fa3565b8015610e755780601f10610e4c57610100808354040283529160200191610e75565b820191905f5260205f20905b815481529060010190602001808311610e5857829003601f168201915b5050505050915050919050565b600c6020525f9081526040902080548190610e9c90612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ec890612fa3565b8015610f135780601f10610eea57610100808354040283529160200191610f13565b820191905f5260205f20905b815481529060010190602001808311610ef657829003601f168201915b505050505090806001018054610f2890612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5490612fa3565b8015610f9f5780601f10610f7657610100808354040283529160200191610f9f565b820191905f5260205f20905b815481529060010190602001808311610f8257829003601f168201915b505050505090806002018054610fb490612fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610fe090612fa3565b801561102b5780601f106110025761010080835404028352916020019161102b565b820191905f5260205f20905b81548152906001019060200180831161100e57829003601f168201915b5050505060038301546004909301549192916001600160a01b0316905085565b5f6108b382611c95565b5f600754611061611934565b61106b919061314b565b905090565b5f6001600160a01b03821661109a576040516322718ad960e21b81525f60048201526024016109a4565b506001600160a01b03165f9081526004602052604090205490565b6110bd611dcc565b610b395f611e8b565b600d6020525f90815260409020805460018201546002830180546001600160a01b039093169391926110f790612fa3565b80601f016020809104026020016040519081016040528092919081815260200182805461112390612fa3565b801561116e5780601f106111455761010080835404028352916020019161116e565b820191905f5260205f20905b81548152906001019060200180831161115157829003601f168201915b50505050509080600301805461118390612fa3565b80601f01602080910402602001604051908101604052809291908181526020018280546111af90612fa3565b80156111fa5780601f106111d1576101008083540402835291602001916111fa565b820191905f5260205f20905b8154815290600101906020018083116111dd57829003601f168201915b5050505050905084565b600f60209081525f928352604090922081518083018401805192815290840192909301919091209152805461123890612fa3565b80601f016020809104026020016040519081016040528092919081815260200182805461126490612fa3565b80156112af5780601f10611286576101008083540402835291602001916112af565b820191905f5260205f20905b81548152906001019060200180831161129257829003601f168201915b505050505081565b6112bf611dcc565b600980546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6060600280546108c890612fa3565b6009545f9060ff1661133d5760405162461bcd60e51b815260206004820152601060248201526f14d85b19481b9bdd081cdd185c9d195960821b60448201526064016109a4565b5f88888888604051602001611355949392919061315e565b6040516020818303038152906040529050600e6113728285610af9565b60405161137f9190613130565b9081526020016040518091039020545f146113e75760405162461bcd60e51b815260206004820152602260248201527f70726f6d707420616e6420736565642068617320616c7265616479206d696e74604482015261195960f21b60648201526084016109a4565b6113ef611055565b34101561143e5760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420656e6f7567682066756e6420746f206d696e74204e4654000000000060448201526064016109a4565b6040518060a001604052808a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250505090825250604080516020601f8b0181900481028201810190925289815291810191908a908a90819084018382808284375f92019190915250505090825250604080516020601f8901819004810282018101909252878152918101919088908890819084018382808284375f92018290525093855250505060208083018790526001600160a01b038e166040938401526008548252600c9052208151819061152490826131cd565b506020820151600182019061153990826131cd565b506040820151600282019061154e90826131cd565b5060608201516003820155608090910151600490910180546001600160a01b0319166001600160a01b0390921691909117905561158b8184611eda565b6115978a60085461205b565b60088054905f6115a68361328c565b9190505550600854600e6115ba8386610af9565b6040516115c79190613130565b908152604051908190036020019020556008546115e6906001906132a4565b9a9950505050505050505050565b61097b338383612074565b60405163c4be5cab60e01b81526001600160a01b037f000000000000000000000000c3287bdef03b925a7c7f54791edadcd88e632ccd169063c4be5cab9061164d90899089906004016132df565b6020604051808303815f875af1158015611669573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061168d91906132f2565b5f888152601060205260409081902082905551630901e0f960e31b81526001600160a01b037f000000000000000000000000c3287bdef03b925a7c7f54791edadcd88e632ccd169163480f07c8916116ec919088908890600401613309565b5f604051808303815f87803b158015611703575f80fd5b505af1158015611715573d5f803e3d5ffd5b505050508585604051611729929190613088565b6040518091039020877f65deac95b53ba76b9cdc6cf446af81731e1218c91eaf9811a95d28bde23b893e868686866040516117679493929190613322565b60405180910390a350505050505050565b336001600160a01b037f0000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a01681146117f55760405163432e033760e11b81526001600160a01b037f0000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a081166004830152821660248201526044016109a4565b5f868152600d6020526040902080546001600160a01b031661184e5760405162461bcd60e51b815260206004820152601260248201527172657175657374206e6f742065786973747360701b60448201526064016109a4565b8585600f5f7f0000000000000000000000000000000000000000000000000000000000001b5f81526020019081526020015f20836002016040516118929190613348565b908152602001604051809103902091826118ad929190613353565b507faf2b2381ddcb18a2b18a7826186fd216acdd9c852a8c7a9a49e7eab127f96ccf87826001015483600201898989896040516118f0979695949392919061340c565b60405180910390a150505050505050565b611909611dcc565b6009805460ff19811660ff90911615179055565b61192884848461097f565b610a0784848484612112565b600b54604051620e1d8d60e41b81527f0000000000000000000000000000000000000000000000000000000000001b5f60048201526001600160401b0390911660248201525f907f0000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a06001600160a01b03169062e1d8d090604401602060405180830381865afa1580156119c9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061106b91906132f2565b5f818152600c60205260408120600381015460609291611a70916002820191906001820190611a1b90612238565b5f888152600c6020526040902060040154611a3e906001600160a01b031661233c565b611a4789610c36565b604051602001611a5c969594939291906134c3565b604051602081830303815290604052612475565b90505f81604051602001611a849190613761565b60408051601f19818403018152919052949350505050565b5f80600e8888604051611ab0929190613088565b9081526040805160209281900383018120545f8181526010909452918320546317861f8760e01b825260048201529092507f000000000000000000000000c3287bdef03b925a7c7f54791edadcd88e632ccd6001600160a01b0316906317861f87906024015f60405180830381865afa158015611b2f573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611b5691908101906137a5565b5f83815260106020526040908190205490516333727c4d60e01b81529192506001600160a01b037f000000000000000000000000c3287bdef03b925a7c7f54791edadcd88e632ccd16916333727c4d91611bb69160040190815260200190565b602060405180830381865afa158015611bd1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bf5919061302d565b8015611c1e57508686604051611c0c929190613088565b60405180910390208180519060200120145b9998505050505050505050565b6001600160a01b039182165f90815260066020908152604080832093909416825291909152205460ff1690565b611c60611dcc565b6001600160a01b038116611c8957604051631e4fbdf760e01b81525f60048201526024016109a4565b611c9281611e8b565b50565b5f818152600360205260408120546001600160a01b0316806108b357604051637e27328960e01b8152600481018490526024016109a4565b610c3183838360016125d7565b5f828152600360205260408120546001600160a01b0390811690831615611d0657611d068184866126db565b6001600160a01b03811615611d4057611d215f855f806125d7565b6001600160a01b0381165f90815260046020526040902080545f190190555b6001600160a01b03851615611d6e576001600160a01b0385165f908152600460205260409020805460010190555b5f8481526003602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b5f546001600160a01b03163314610b395760405163118cdaa760e01b81523360048201526024016109a4565b80471015611e1b5760405163cd78605960e01b81523060048201526024016109a4565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611e64576040519150601f19603f3d011682016040523d82523d5f602084013e611e69565b606091505b5050905080610c3157604051630a12f52160e11b815260040160405180910390fd5b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f8183604051602001611eee929190613063565b60408051601f1981840301815290829052600b54632dca9c0360e11b83529092505f916001600160a01b037f0000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a01691635b953806913491611f80917f0000000000000000000000000000000000000000000000000000000000001b5f91889130916001600160401b03169060040161380d565b60206040518083038185885af1158015611f9c573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611fc191906132f2565b5f818152600d6020526040902090915060028101611fdf84826131cd565b5080546001600160a01b0319163390811782557f0000000000000000000000000000000000000000000000000000000000001b5f600183018190556040517fa0faead83d70148ae18b694377f9bef079251342ab90e14af0f9ef68b891269f9261204c9286928a9061385d565b60405180910390a15050505050565b61097b828260405180602001604052805f81525061273f565b6001600160a01b0382166120a657604051630b61174360e31b81526001600160a01b03831660048201526024016109a4565b6001600160a01b038381165f81815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b15610a0757604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290612154903390889087908790600401613893565b6020604051808303815f875af192505050801561218e575060408051601f3d908101601f1916820190925261218b918101906138c5565b60015b6121f5573d8080156121bb576040519150601f19603f3d011682016040523d82523d5f602084013e6121c0565b606091505b5080515f036121ed57604051633250574960e11b81526001600160a01b03851660048201526024016109a4565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b1461223157604051633250574960e11b81526001600160a01b03851660048201526024016109a4565b5050505050565b6060815f0361225e5750506040805180820190915260018152600360fc1b602082015290565b815f5b811561228757806122718161328c565b91506122809050600a8361301a565b9150612261565b5f816001600160401b038111156122a0576122a06129bb565b6040519080825280601f01601f1916602001820160405280156122ca576020820181803683370190505b5090505b8415612334576122df6001836132a4565b91506122ec600a866138e0565b6122f790603061314b565b60f81b81838151811061230c5761230c6138f3565b60200101906001600160f81b03191690815f1a90535061232d600a8661301a565b94506122ce565b949350505050565b60408051602880825260608281019093525f91906020820181803683370190505090505f5b601481101561246e575f6123768260136132a4565b612381906008612fef565b61238c9060026139e7565b61239f906001600160a01b03871661301a565b60f81b90505f60108260f81c6123b591906139f2565b60f81b90505f8160f81c60106123cb9190613a13565b8360f81c6123d99190613a2f565b60f81b90506123e782612755565b856123f3866002612fef565b81518110612403576124036138f3565b60200101906001600160f81b03191690815f1a90535061242281612755565b8561242e866002612fef565b61243990600161314b565b81518110612449576124496138f3565b60200101906001600160f81b03191690815f1a90535050600190920191506123619050565b5092915050565b80516060905f81900361249757505060408051602081019091525f8152919050565b5f60036124a583600261314b565b6124af919061301a565b6124ba906004612fef565b90505f6124c882602061314b565b6001600160401b038111156124df576124df6129bb565b6040519080825280601f01601f191660200182016040528015612509576020820181803683370190505b5090505f604051806060016040528060408152602001613a6260409139905060018101602083015f5b86811015612593576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101612532565b5060038606600181146125ad57600281146125be576125c9565b613d3d60f01b6001198301526125c9565b603d60f81b5f198301525b505050918152949350505050565b80806125eb57506001600160a01b03821615155b156126ac575f6125fa84611c95565b90506001600160a01b038316158015906126265750826001600160a01b0316816001600160a01b031614155b801561263957506126378184611c2b565b155b156126625760405163a9fbf51f60e01b81526001600160a01b03841660048201526024016109a4565b81156126aa5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b50505f90815260056020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b6126e683838361278f565b610c31576001600160a01b03831661271457604051637e27328960e01b8152600481018290526024016109a4565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016109a4565b61274983836127f0565b610c315f848484612112565b5f600a60f883901c101561277b5761277260f883901c6030613a48565b60f81b92915050565b61277260f883901c6057613a48565b919050565b5f6001600160a01b038316158015906123345750826001600160a01b0316846001600160a01b031614806127c857506127c88484611c2b565b806123345750505f908152600560205260409020546001600160a01b03908116911614919050565b6001600160a01b03821661281957604051633250574960e11b81525f60048201526024016109a4565b5f61282583835f611cda565b90506001600160a01b03811615610c31576040516339e3563760e11b81525f60048201526024016109a4565b6001600160e01b031981168114611c92575f80fd5b5f60208284031215612876575f80fd5b813561288181612851565b9392505050565b5f5b838110156128a257818101518382015260200161288a565b50505f910152565b5f81518084526128c1816020860160208601612888565b601f01601f19169290920160200192915050565b602081525f61288160208301846128aa565b5f602082840312156128f7575f80fd5b5035919050565b80356001600160a01b038116811461278a575f80fd5b5f8060408385031215612925575f80fd5b61292e836128fe565b946020939093013593505050565b5f805f6060848603121561294e575f80fd5b612957846128fe565b9250612965602085016128fe565b9150604084013590509250925092565b5f8060408385031215612986575f80fd5b50508035926020909101359150565b5f602082840312156129a5575f80fd5b81356001600160401b0381168114612881575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156129f7576129f76129bb565b604052919050565b5f6001600160401b03821115612a1757612a176129bb565b50601f01601f191660200190565b5f82601f830112612a34575f80fd5b8135612a47612a42826129ff565b6129cf565b818152846020838601011115612a5b575f80fd5b816020850160208301375f918101602001919091529392505050565b5f8060408385031215612a88575f80fd5b82356001600160401b03811115612a9d575f80fd5b612aa985828601612a25565b95602094909401359450505050565b5f8083601f840112612ac8575f80fd5b5081356001600160401b03811115612ade575f80fd5b602083019150836020828501011115612af5575f80fd5b9250929050565b5f805f8060408587031215612b0f575f80fd5b84356001600160401b0380821115612b25575f80fd5b612b3188838901612ab8565b90965094506020870135915080821115612b49575f80fd5b50612b5687828801612ab8565b95989497509550505050565b60a081525f612b7460a08301886128aa565b8281036020840152612b8681886128aa565b90508281036040840152612b9a81876128aa565b606084019590955250506001600160a01b03919091166080909101529392505050565b5f60208284031215612bcd575f80fd5b612881826128fe565b5f60208284031215612be6575f80fd5b81356001600160401b03811115612bfb575f80fd5b61233484828501612a25565b60018060a01b0385168152836020820152608060408201525f612c2d60808301856128aa565b8281036060840152612c3f81856128aa565b979650505050505050565b5f8060408385031215612c5b575f80fd5b8235915060208301356001600160401b03811115612c77575f80fd5b612c8385828601612a25565b9150509250929050565b5f805f805f805f8060a0898b031215612ca4575f80fd5b612cad896128fe565b975060208901356001600160401b0380821115612cc8575f80fd5b612cd48c838d01612ab8565b909950975060408b0135915080821115612cec575f80fd5b612cf88c838d01612ab8565b909750955060608b0135915080821115612d10575f80fd5b50612d1d8b828c01612ab8565b999c989b50969995989497949560800135949350505050565b8015158114611c92575f80fd5b5f8060408385031215612d54575f80fd5b612d5d836128fe565b91506020830135612d6d81612d36565b809150509250929050565b5f805f805f805f6080888a031215612d8e575f80fd5b8735965060208801356001600160401b0380821115612dab575f80fd5b612db78b838c01612ab8565b909850965060408a0135915080821115612dcf575f80fd5b612ddb8b838c01612ab8565b909650945060608a0135915080821115612df3575f80fd5b50612e008a828b01612ab8565b989b979a50959850939692959293505050565b5f805f805f60608688031215612e27575f80fd5b8535945060208601356001600160401b0380821115612e44575f80fd5b612e5089838a01612ab8565b90965094506040880135915080821115612e68575f80fd5b50612e7588828901612ab8565b969995985093965092949392505050565b5f805f8060808587031215612e99575f80fd5b612ea2856128fe565b9350612eb0602086016128fe565b92506040850135915060608501356001600160401b03811115612ed1575f80fd5b612edd87828801612a25565b91505092959194509250565b5f805f805f8060608789031215612efe575f80fd5b86356001600160401b0380821115612f14575f80fd5b612f208a838b01612ab8565b90985096506020890135915080821115612f38575f80fd5b612f448a838b01612ab8565b90965094506040890135915080821115612f5c575f80fd5b50612f6989828a01612ab8565b979a9699509497509295939492505050565b5f8060408385031215612f8c575f80fd5b612f95836128fe565b9150610a3c602084016128fe565b600181811c90821680612fb757607f821691505b602082108103612fd557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176108b3576108b3612fdb565b634e487b7160e01b5f52601260045260245ffd5b5f8261302857613028613006565b500490565b5f6020828403121561303d575f80fd5b815161288181612d36565b5f8151613059818560208601612888565b9290920192915050565b8281525f825161307a816020850160208701612888565b919091016020019392505050565b818382375f9101908152919050565b5f81546130a381612fa3565b600182811680156130bb57600181146130d0576130fc565b60ff19841687528215158302870194506130fc565b855f526020805f205f5b858110156130f35781548a8201529084019082016130da565b50505082870194505b5050505092915050565b5f6131118285613097565b622d2d2d60e81b81526131276003820185613097565b95945050505050565b5f8251613141818460208701612888565b9190910192915050565b808201808211156108b3576108b3612fdb565b838582375f848201622d2d2d60e81b8152838560038301375f93016003019283525090949350505050565b601f821115610c3157805f5260205f20601f840160051c810160208510156131ae5750805b601f840160051c820191505b81811015612231575f81556001016131ba565b81516001600160401b038111156131e6576131e66129bb565b6131fa816131f48454612fa3565b84613189565b602080601f83116001811461322d575f84156132165750858301515b5f19600386901b1c1916600185901b178555613284565b5f85815260208120601f198616915b8281101561325b5788860151825594840194600190910190840161323c565b508582101561327857878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f6001820161329d5761329d612fdb565b5060010190565b818103818111156108b3576108b3612fdb565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f6123346020830184866132b7565b5f60208284031215613302575f80fd5b5051919050565b838152604060208201525f6131276040830184866132b7565b604081525f6133356040830186886132b7565b8281036020840152612c3f8185876132b7565b5f6128818284613097565b6001600160401b0383111561336a5761336a6129bb565b61337e836133788354612fa3565b83613189565b5f601f8411600181146133af575f85156133985750838201355b5f19600387901b1c1916600186901b178355612231565b5f83815260208120601f198716915b828110156133de57868501358255602094850194600190920191016133be565b50868210156133fa575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b8781525f602088602084015260a060408401525f885461342b81612fa3565b8060a087015260c060018084165f811461344c576001811461346857613495565b60ff19851660c08a015260c084151560051b8a01019550613495565b8d5f5260205f205f5b8581101561348c5781548b8201860152908301908801613471565b8a0160c0019650505b505050505083810360608501526134ad81888a6132b7565b91505082810360808401526115e68185876132b7565b683d913730b6b2911d1160b91b81525f6134e06009830189613097565b7f222c202261747472696275746573223a205b7b2274726169745f74797065223a81527f2022706f7369746976655f70726f6d7074222c202276616c7565223a202200006020820152613536603e820189613097565b7f227d2c207b2274726169745f74797065223a20226e656761746976655f70726f81526f36b83a111610113b30b63ab2911d101160811b602082015290506135816030820188613097565b90507f227d2c207b2274726169745f74797065223a202273656564222c202276616c7581526432911d101160d91b602082015285516135c7816025840160208a01612888565b7f227d2c207b2274726169745f74797065223a2022617574686f72222c2022766160259290910191820152680d8eaca4474404460f60bb1b6045820152611c1e61375361374d61361a604e850189613048565b7f227d2c207b2274726169745f74797065223a20226d6f64656c222c202276616c81527f7565223a2022537461626c6520446966667573696f6e227d5d2c20226465736360208201527f72697074696f6e223a2022537461626c6520446966667573696f6e206973206160408201527f206c6174656e7420746578742d746f2d696d61676520646966667573696f6e2060608201527f6d6f64656c2063617061626c65206f662067656e65726174696e672070686f7460808201527f6f2d7265616c697374696320696d6167657320676976656e20616e792074657860a08201527f7420696e7075742e222c2022696d616765223a202268747470733a2f2f67617460c08201527f657761792e70696e6174612e636c6f75642f697066732f00000000000000000060e082015260f70190565b86613048565b61227d60f01b815260020190565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081525f825161379881601d850160208701612888565b91909101601d0192915050565b5f602082840312156137b5575f80fd5b81516001600160401b038111156137ca575f80fd5b8201601f810184136137da575f80fd5b80516137e8612a42826129ff565b8181528560208385010111156137fc575f80fd5b613127826020830160208601612888565b84815260a060208201525f61382560a08301866128aa565b6001600160a01b03949094166040830152506001600160401b039190911660608201528082036080909101525f815260200192915050565b84815260018060a01b0384166020820152826040820152608060608201525f61388960808301846128aa565b9695505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90613889908301846128aa565b5f602082840312156138d5575f80fd5b815161288181612851565b5f826138ee576138ee613006565b500690565b634e487b7160e01b5f52603260045260245ffd5b600181815b8085111561394157815f190482111561392757613927612fdb565b8085161561393457918102915b93841c939080029061390c565b509250929050565b5f82613957575060016108b3565b8161396357505f6108b3565b816001811461397957600281146139835761399f565b60019150506108b3565b60ff84111561399457613994612fdb565b50506001821b6108b3565b5060208310610133831016604e8410600b84101617156139c2575081810a6108b3565b6139cc8383613907565b805f19048211156139df576139df612fdb565b029392505050565b5f6128818383613949565b5f60ff831680613a0457613a04613006565b8060ff84160491505092915050565b60ff818116838216029081169081811461246e5761246e612fdb565b60ff82811682821603908111156108b3576108b3612fdb565b60ff81811683821601908111156108b3576108b3612fdb56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212201553cb7a24a467fc48ae0ed4b38a9f006b48f63d4ea104b1eaf615c7a4fa26d764736f6c63430008170033

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

0000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b5f000000000000000000000000c3287bdef03b925a7c7f54791edadcd88e632ccd0000000000000000000000000000000000000000000000000000000000000010537461626c6520446966667573696f6e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025344000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _aiOracle (address): 0x0A0f4321214BB6C7811dD8a71cF587bdaF03f0A0
Arg [1] : _name (string): Stable Diffusion
Arg [2] : _symbol (string): SD
Arg [3] : _mintPrice (uint256): 0
Arg [4] : _aiModelId (uint256): 7007
Arg [5] : _opmlLib (address): 0xC3287BDEF03b925A7C7f54791EDADCD88e632CcD

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000000a0f4321214bb6c7811dd8a71cf587bdaf03f0a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000001b5f
Arg [5] : 000000000000000000000000c3287bdef03b925a7c7f54791edadcd88e632ccd
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [7] : 537461626c6520446966667573696f6e00000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [9] : 5344000000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

71647:9388:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42698:305;;;;;;;;;;-1:-1:-1;42698:305:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;42698:305:0;;;;;;;;43529:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;44701:158::-;;;;;;;;;;-1:-1:-1;44701:158:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1719:32:1;;;1701:51;;1689:2;1674:18;44701:158:0;1555:203:1;44520:115:0;;;;;;;;;;-1:-1:-1;44520:115:0;;;;;:::i;:::-;;:::i;:::-;;71895:26;;;;;;;;;;;;;;;;;;;2346:25:1;;;2334:2;2319:18;71895:26:0;2200:177:1;45370:588:0;;;;;;;;;;-1:-1:-1;45370:588:0;;;;;:::i;:::-;;:::i;73833:280::-;;;;;;;;;;-1:-1:-1;73833:280:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3160:32:1;;;3142:51;;3224:2;3209:18;;3202:34;;;;3115:18;73833:280:0;2968:274:1;76539:132:0;;;;;;;;;;-1:-1:-1;76539:132:0;;;;;:::i;:::-;;:::i;71823:32::-;;;;;;;;;;;;;;;67599:35;;;;;;;;;;;;;;;68695:126;;;;;;;;;;-1:-1:-1;68695:126:0;;;;;:::i;:::-;;:::i;74286:178::-;;;;;;;;;;-1:-1:-1;74286:178:0;;;;;:::i;:::-;;:::i;79209:121::-;;;;;;;;;;;;;:::i;76132:399::-;;;;;;;;;;-1:-1:-1;76132:399:0;;;;;:::i;:::-;;:::i;46029:134::-;;;;;;;;;;-1:-1:-1;46029:134:0;;;;;:::i;:::-;;:::i;74473:505::-;;;;;;;;;;-1:-1:-1;74473:505:0;;;;;:::i;:::-;;:::i;72674:49::-;;;;;;;;;;-1:-1:-1;72674:49:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;43342:120::-;;;;;;;;;;-1:-1:-1;43342:120:0;;;;;:::i;:::-;;:::i;71864:24::-;;;;;;;;;;;;;;;;77962:112;;;;;;;;;;;;;:::i;43067:213::-;;;;;;;;;;-1:-1:-1;43067:213:0;;;;;:::i;:::-;;:::i;3586:103::-;;;;;;;;;;;;;:::i;72806:52::-;;;;;;;;;;-1:-1:-1;72806:52:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;72748:51;;;;;;;;;;-1:-1:-1;72748:51:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;72043:37::-;;;;;;;;;;;;;;;;72865:60;;;;;;;;;;-1:-1:-1;72865:60:0;;;;;:::i;:::-;;:::i;2911:87::-;;;;;;;;;;-1:-1:-1;2957:7:0;2984:6;-1:-1:-1;;;;;2984:6:0;2911:87;;74166:112;;;;;;;;;;-1:-1:-1;74166:112:0;;;;;:::i;:::-;;:::i;43689:95::-;;;;;;;;;;;;;:::i;78105:1014::-;;;;;;:::i;:::-;;:::i;71961:75::-;;;;;;;;;;-1:-1:-1;71961:75:0;;;;;;;-1:-1:-1;;;;;71961:75:0;;;44931:146;;;;;;;;;;-1:-1:-1;44931:146:0;;;;;:::i;:::-;;:::i;72932:54::-;;;;;;;;;;-1:-1:-1;72932:54:0;;;;;:::i;:::-;;;;;;;;;;;;;;75146:403;;;;;;;;;;-1:-1:-1;75146:403:0;;;;;:::i;:::-;;:::i;76729:460::-;;;;;;;;;;-1:-1:-1;76729:460:0;;;;;:::i;:::-;;:::i;71782:34::-;;;;;;;;;;;;;;;74986:93;;;;;;;;;;;;;:::i;46234:211::-;;;;;;;;;;-1:-1:-1;46234:211:0;;;;;:::i;:::-;;:::i;77817:139::-;;;;;;;;;;;;;:::i;79338:971::-;;;;;;;;;;-1:-1:-1;79338:971:0;;;;;:::i;:::-;;:::i;75611:449::-;;;;;;;;;;-1:-1:-1;75611:449:0;;;;;:::i;:::-;;:::i;45148:155::-;;;;;;;;;;-1:-1:-1;45148:155:0;;;;;:::i;:::-;;:::i;72248:47::-;;;;;;;;;;-1:-1:-1;72248:47:0;;;;-1:-1:-1;;;;;72248:47:0;;;;;;-1:-1:-1;;;;;14227:31:1;;;14209:50;;14197:2;14182:18;72248:47:0;14065:200:1;3844:220:0;;;;;;;;;;-1:-1:-1;3844:220:0;;;;;:::i;:::-;;:::i;71928:24::-;;;;;;;;;;-1:-1:-1;71928:24:0;;;;;;;;42698:305;42800:4;-1:-1:-1;;;;;;42837:40:0;;-1:-1:-1;;;42837:40:0;;:105;;-1:-1:-1;;;;;;;42894:48:0;;-1:-1:-1;;;42894:48:0;42837:105;:158;;;-1:-1:-1;;;;;;;;;;21143:40:0;;;42959:36;42817:178;42698:305;-1:-1:-1;;42698:305:0:o;43529:91::-;43574:13;43607:5;43600:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43529:91;:::o;44701:158::-;44768:7;44788:22;44802:7;44788:13;:22::i;:::-;-1:-1:-1;47277:7:0;47304:24;;;:15;:24;;;;;;-1:-1:-1;;;;;47304:24:0;44830:21;47207:129;44520:115;44592:35;44601:2;44605:7;945:10;44592:8;:35::i;:::-;44520:115;;:::o;45370:588::-;-1:-1:-1;;;;;45465:16:0;;45461:89;;45505:33;;-1:-1:-1;;;45505:33:0;;45535:1;45505:33;;;1701:51:1;1674:18;;45505:33:0;;;;;;;;45461:89;45771:21;45795:34;45803:2;45807:7;945:10;45795:7;:34::i;:::-;45771:58;;45861:4;-1:-1:-1;;;;;45844:21:0;:13;-1:-1:-1;;;;;45844:21:0;;45840:111;;45889:50;;-1:-1:-1;;;45889:50:0;;-1:-1:-1;;;;;14913:15:1;;;45889:50:0;;;14895:34:1;14945:18;;;14938:34;;;15008:15;;14988:18;;;14981:43;14830:18;;45889:50:0;14655:375:1;45840:111:0;45450:508;45370:588;;;:::o;73833:280::-;74026:15;;74081:17;;74026:15;;;;-1:-1:-1;;;;;74026:15:0;;73958:16;;74102:3;;74069:29;;:9;:29;:::i;:::-;74068:37;;;;:::i;:::-;74052:53;;73833:280;;;;;:::o;76539:132::-;2797:13;:11;:13::i;:::-;76627:24:::1;:36:::0;;-1:-1:-1;;76627:36:0::1;-1:-1:-1::0;;;;;76627:36:0;;;::::1;::::0;;;::::1;::::0;;76539:132::o;68695:126::-;68782:31;;-1:-1:-1;;;68782:31:0;;;;;2346:25:1;;;68758:4:0;;68782:8;-1:-1:-1;;;;;68782:20:0;;;;2319:18:1;;68782:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;74286:178::-;74359:12;74384:17;74421:4;74427:6;74404:30;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;74404:30:0;;;;;;;74286:178;-1:-1:-1;;;;74286:178:0:o;79209:121::-;2797:13;:11;:13::i;:::-;79259:63:::1;945:10:::0;79300:21:::1;79259:17;:63::i;:::-;79209:121::o:0;76132:399::-;76264:32;76271:6;;76279:8;;76289:6;;76264;:32::i;:::-;76256:70;;;;-1:-1:-1;;;76256:70:0;;16618:2:1;76256:70:0;;;16600:21:1;16657:2;16637:18;;;16630:30;16696:27;16676:18;;;16669:55;16741:18;;76256:70:0;16416:349:1;76256:70:0;76429:15;76447:19;76467:6;;76447:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;76490:33:0;;76514:8;;;;76490:33;:::i;:::-;;;;;;;;76506:6;;76490:33;;;;;;;:::i;:::-;;;;;;;;;;76497:7;;76490:33;;;;;76245:286;76132:399;;;;:::o;46029:134::-;46116:39;46133:4;46139:2;46143:7;46116:39;;;;;;;;;;;;:16;:39::i;:::-;46029:134;;;:::o;74473:505::-;74573:20;;;;:11;:20;;;;;:25;;;74543:13;;74573:30;74569:183;;74635:9;74627:18;;;;:7;:18;;;;;;;;74670:20;;;:11;:20;;;;;;74653:85;;;;74706:31;;;;74653:85;;:::i;:::-;;;;-1:-1:-1;;74653:85:0;;;;;;;;;;74627:113;;;:::i;:::-;;;;;;;;;;;;;74620:120;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74473:505;;;:::o;74569:183::-;74762:17;74799:20;;;:11;:20;;;;;;;;:25;;;;74833:85;;74799:25;;74833:85;;74886:31;;;;74833:85;;:::i;:::-;;;;-1:-1:-1;;74833:85:0;;;;;;;;;;74782:138;;;74833:85;74782:138;;:::i;:::-;;;;-1:-1:-1;;74782:138:0;;;;;;;;;74946:9;74938:18;;;;:7;74782:138;74938:18;;;;;74782:138;;-1:-1:-1;74938:18:0;:32;;74782:138;;74938:32;:::i;:::-;;;;;;;;;;;;;74931:39;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74473:505;;;:::o;72674:49::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;72674:49:0;;;;;;;;;;;;-1:-1:-1;;;;;72674:49:0;;-1:-1:-1;72674:49:0;:::o;43342:120::-;43405:7;43432:22;43446:7;43432:13;:22::i;77962:112::-;78011:7;78057:9;;78038:16;:14;:16::i;:::-;:28;;;;:::i;:::-;78031:35;;77962:112;:::o;43067:213::-;43130:7;-1:-1:-1;;;;;43154:19:0;;43150:89;;43197:30;;-1:-1:-1;;;43197:30:0;;43224:1;43197:30;;;1701:51:1;1674:18;;43197:30:0;1555:203:1;43150:89:0;-1:-1:-1;;;;;;43256:16:0;;;;;:9;:16;;;;;;;43067:213::o;3586:103::-;2797:13;:11;:13::i;:::-;3651:30:::1;3678:1;3651:18;:30::i;72748:51::-:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;72748:51:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;72865:60::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;74166:112::-;2797:13;:11;:13::i;:::-;74243:15:::1;:27:::0;;-1:-1:-1;;;;;74243:27:0;;::::1;;;-1:-1:-1::0;;;;;;74243:27:0;;::::1;::::0;;;::::1;::::0;;74166:112::o;43689:95::-;43736:13;43769:7;43762:14;;;;;:::i;78105:1014::-;78314:12;;78255:15;;78314:12;;78306:41;;;;-1:-1:-1;;;78306:41:0;;18964:2:1;78306:41:0;;;18946:21:1;19003:2;18983:18;;;18976:30;-1:-1:-1;;;19022:18:1;;;19015:46;19078:18;;78306:41:0;18762:340:1;78306:41:0;78358:20;78405:15;;78429:10;;78388:52;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;78358:83;;78460:19;78480:20;78487:6;78495:4;78480:6;:20::i;:::-;78460:41;;;;;;:::i;:::-;;;;;;;;;;;;;;78505:1;78460:46;78452:93;;;;-1:-1:-1;;;78452:93:0;;20155:2:1;78452:93:0;;;20137:21:1;20194:2;20174:18;;;20167:30;20233:34;20213:18;;;20206:62;-1:-1:-1;;;20284:18:1;;;20277:32;20326:19;;78452:93:0;19953:398:1;78452:93:0;78600:18;:16;:18::i;:::-;78587:9;:31;;78579:71;;;;-1:-1:-1;;;78579:71:0;;20558:2:1;78579:71:0;;;20540:21:1;20597:2;20577:18;;;20570:30;20636:29;20616:18;;;20609:57;20683:18;;78579:71:0;20356:351:1;78579:71:0;78730:56;;;;;;;;78741:15;;78730:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;78730:56:0;;;-1:-1:-1;78730:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;78758:10;;;;;;78730:56;;78758:10;;;;78730:56;;;;;;;;;-1:-1:-1;;;78730:56:0;;;-1:-1:-1;78730:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;78770:5;;;;;;78730:56;;78770:5;;;;78730:56;;;;;;;;-1:-1:-1;78730:56:0;;;-1:-1:-1;;;78730:56:0;;;;;;;-1:-1:-1;;;;;78730:56:0;;;;;;;78715:11;;78703:24;;:11;:24;;;:83;;:24;;:83;;:24;:83;:::i;:::-;-1:-1:-1;78703:83:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;78703:83:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;78703:83:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;78703:83:0;-1:-1:-1;;;;;78703:83:0;;;;;;;;;78797:31;78815:6;78823:4;78797:17;:31::i;:::-;78856:32;78872:2;78876:11;;78856:15;:32::i;:::-;78969:11;:14;;;:11;:14;;;:::i;:::-;;;;;;79038:11;;78994:19;79014:20;79021:6;79029:4;79014:6;:20::i;:::-;78994:41;;;;;;:::i;:::-;;;;;;;;;;;;;;:55;79096:11;;:15;;79110:1;;79096:15;:::i;:::-;79089:22;78105:1014;-1:-1:-1;;;;;;;;;;78105:1014:0:o;44931:146::-;45017:52;945:10;45050:8;45060;45017:18;:52::i;75146:403::-;75362:41;;-1:-1:-1;;;75362:41:0;;-1:-1:-1;;;;;75371:7:0;75362:33;;;;:41;;75396:6;;;;75362:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75332:27;;;;:18;:27;;;;;;;:71;;;75414:69;-1:-1:-1;;;75414:69:0;;-1:-1:-1;;;;;75423:7:0;75414:30;;;;:69;;75332:71;75474:8;;;;75414:69;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75517:6;;75499:42;;;;;;;:::i;:::-;;;;;;;;75508:7;75499:42;75525:8;;75535:5;;75499:42;;;;;;;;;:::i;:::-;;;;;;;;75146:403;;;;;;;:::o;76729:460::-;68077:10;-1:-1:-1;;;;;68124:8:0;68103:29;;;68099:124;;68156:55;;-1:-1:-1;;;68156:55:0;;-1:-1:-1;;;;;68183:8:0;24760:15:1;;68156:55:0;;;24742:34:1;24812:15;;24792:18;;;24785:43;24677:18;;68156:55:0;24494:340:1;68099:124:0;76878:31:::1;76912:19:::0;;;:8:::1;:19;::::0;;;;76950:14;;-1:-1:-1;;;;;76950:14:0::1;76942:59;;;::::0;-1:-1:-1;;;76942:59:0;;25041:2:1;76942:59:0::1;::::0;::::1;25023:21:1::0;25080:2;25060:18;;;25053:30;-1:-1:-1;;;25099:18:1;;;25092:48;25157:18;;76942:59:0::1;24839:342:1::0;76942:59:0::1;77063:6;;77012:7;:18;77020:9;77012:18;;;;;;;;;;;77038:7;:13;;77012:41;;;;;;:::i;:::-;;;;;;;;;;;;;:58;;;;;;;:::i;:::-;;77086:95;77101:9;77112:7;:15;;;77136:7;:13;;77159:6;;77168:12;;77086:95;;;;;;;;;;;;:::i;:::-;;;;;;;;76867:322;68026:216:::0;76729:460;;;;;:::o;74986:93::-;2797:13;:11;:13::i;:::-;75059:12:::1;::::0;;-1:-1:-1;;75043:28:0;::::1;75059:12;::::0;;::::1;75058:13;75043:28;::::0;;74986:93::o;46234:211::-;46348:31;46361:4;46367:2;46371:7;46348:12;:31::i;:::-;46390:47;46413:4;46419:2;46423:7;46432:4;46390:22;:47::i;77817:139::-;77923:24;;77891:57;;-1:-1:-1;;;77891:57:0;;77912:9;77891:57;;;28232:25:1;-1:-1:-1;;;;;77923:24:0;;;28273:18:1;;;28266:59;77864:7:0;;77891:8;-1:-1:-1;;;;;77891:20:0;;;;28205:18:1;;77891:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;79338:971::-;79427:18;79515:20;;;:11;:20;;;;;79773:25;;;;79403:13;;79427:18;79448:734;;79515:26;;;;:20;79690:31;;;;79764:35;;:8;:35::i;:::-;79860:20;;;;:11;:20;;;;;:27;;;79846:42;;-1:-1:-1;;;;;79860:27:0;79846:13;:42::i;:::-;80141:31;80164:7;80141:22;:31::i;:::-;79475:704;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;79448:13;:734::i;:::-;79427:755;;80191:20;80271:4;80221:55;;;;;;;;:::i;:::-;;;;-1:-1:-1;;80221:55:0;;;;;;;;;;79338:971;-1:-1:-1;;;;79338:971:0:o;75611:449::-;75769:12;75794:15;75812:19;75832:6;;75812:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;75850:19;75900:27;;;:18;:27;;;;;;;-1:-1:-1;;;75872:56:0;;;;;2346:25:1;75812:27:0;;-1:-1:-1;75881:7:0;-1:-1:-1;;;;;75872:27:0;;;;2319:18:1;;75872:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;75872:56:0;;;;;;;;;;;;:::i;:::-;75978:27;;;;:18;:27;;;;;;;;75948:58;;-1:-1:-1;;;75948:58:0;;75850:78;;-1:-1:-1;;;;;;75957:7:0;75948:29;;;;:58;;;;2346:25:1;;;2334:2;2319:18;;2200:177;75948:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:104;;;;;76042:8;;76032:19;;;;;;;:::i;:::-;;;;;;;;76021:6;76011:17;;;;;;:40;75948:104;75941:111;75611:449;-1:-1:-1;;;;;;;;;75611:449:0:o;45148:155::-;-1:-1:-1;;;;;45260:25:0;;;45236:4;45260:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;45148:155::o;3844:220::-;2797:13;:11;:13::i;:::-;-1:-1:-1;;;;;3929:22:0;::::1;3925:93;;3975:31;::::0;-1:-1:-1;;;3975:31:0;;4003:1:::1;3975:31;::::0;::::1;1701:51:1::0;1674:18;;3975:31:0::1;1555:203:1::0;3925:93:0::1;4028:28;4047:8;4028:18;:28::i;:::-;3844:220:::0;:::o;57676:247::-;57739:7;47062:16;;;:7;:16;;;;;;-1:-1:-1;;;;;47062:16:0;;57803:90;;57850:31;;-1:-1:-1;;;57850:31:0;;;;;2346:25:1;;;2319:18;;57850:31:0;2200:177:1;55908:122:0;55989:33;55998:2;56002:7;56011:4;56017;55989:8;:33::i;50169:824::-;50255:7;47062:16;;;:7;:16;;;;;;-1:-1:-1;;;;;47062:16:0;;;;50370:18;;;50366:88;;50405:37;50422:4;50428;50434:7;50405:16;:37::i;:::-;-1:-1:-1;;;;;50501:18:0;;;50497:263;;50619:48;50636:1;50640:7;50657:1;50661:5;50619:8;:48::i;:::-;-1:-1:-1;;;;;50713:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;50713:20:0;;;50497:263;-1:-1:-1;;;;;50776:16:0;;;50772:111;;-1:-1:-1;;;;;50838:13:0;;;;;;:9;:13;;;;;:18;;50855:1;50838:18;;;50772:111;50895:16;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;50895:21:0;-1:-1:-1;;;;;50895:21:0;;;;;;;;;50934:27;;50895:16;;50934:27;;;;;;;50981:4;50169:824;-1:-1:-1;;;;50169:824:0:o;3076:166::-;2957:7;2984:6;-1:-1:-1;;;;;2984:6:0;945:10;3136:23;3132:103;;3183:40;;-1:-1:-1;;;3183:40:0;;945:10;3183:40;;;1701:51:1;1674:18;;3183:40:0;1555:203:1;60930:340:0;61040:6;61016:21;:30;61012:111;;;61070:41;;-1:-1:-1;;;61070:41:0;;61105:4;61070:41;;;1701:51:1;1674:18;;61070:41:0;1555:203:1;61012:111:0;61136:12;61154:9;-1:-1:-1;;;;;61154:14:0;61176:6;61154:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61135:52;;;61203:7;61198:65;;61234:17;;-1:-1:-1;;;61234:17:0;;;;;;;;;;;4224:191;4298:16;4317:6;;-1:-1:-1;;;;;4334:17:0;;;-1:-1:-1;;;;;;4334:17:0;;;;;;4367:40;;4317:6;;;;;;;4367:40;;4298:16;4367:40;4287:128;4224:191;:::o;77197:612::-;77280:18;77318:4;77324:6;77301:30;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;77301:30:0;;;;;;;;;;77519:24;;-1:-1:-1;;;77429:129:0;;77301:30;;-1:-1:-1;77409:17:0;;-1:-1:-1;;;;;77429:8:0;:24;;;;77461:9;;77429:129;;77486:9;;77301:30;;77512:4;;-1:-1:-1;;;;;77519:24:0;;77429:129;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77569:31;77603:19;;;:8;:19;;;;;77409:149;;-1:-1:-1;77633:13:0;;;:21;77649:5;77633:13;:21;:::i;:::-;-1:-1:-1;77665:27:0;;-1:-1:-1;;;;;;77665:27:0;77682:10;77665:27;;;;;77721:9;77665:27;77703:15;;:27;;;77746:55;;;;;;77760:9;;77794:6;;77746:55;:::i;:::-;;;;;;;;77269:540;;;77197:612;;:::o;52027:102::-;52095:26;52105:2;52109:7;52095:26;;;;;;;;;;;;:9;:26::i;57115:318::-;-1:-1:-1;;;;;57223:22:0;;57219:93;;57269:31;;-1:-1:-1;;;57269:31:0;;-1:-1:-1;;;;;1719:32:1;;57269:31:0;;;1701:51:1;1674:18;;57269:31:0;1555:203:1;57219:93:0;-1:-1:-1;;;;;57322:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;57322:46:0;;;;;;;;;;57384:41;;540::1;;;57384::0;;513:18:1;57384:41:0;;;;;;;57115:318;;;:::o;58473:799::-;-1:-1:-1;;;;;58590:14:0;;;:18;58586:679;;58629:71;;-1:-1:-1;;;58629:71:0;;-1:-1:-1;;;;;58629:36:0;;;;;:71;;945:10;;58680:4;;58686:7;;58695:4;;58629:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58629:71:0;;;;;;;;-1:-1:-1;;58629:71:0;;;;;;;;;;;;:::i;:::-;;;58625:629;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58943:6;:13;58960:1;58943:18;58939:300;;58993:25;;-1:-1:-1;;;58993:25:0;;-1:-1:-1;;;;;1719:32:1;;58993:25:0;;;1701:51:1;1674:18;;58993:25:0;1555:203:1;58939:300:0;59189:6;59183:13;59174:6;59170:2;59166:15;59159:38;58625:629;-1:-1:-1;;;;;;58748:51:0;;-1:-1:-1;;;58748:51:0;58744:132;;58831:25;;-1:-1:-1;;;58831:25:0;;-1:-1:-1;;;;;1719:32:1;;58831:25:0;;;1701:51:1;1674:18;;58831:25:0;1555:203:1;58744:132:0;58701:190;58473:799;;;;:::o;80317:715::-;80373:13;80586:5;80595:1;80586:10;80582:53;;-1:-1:-1;;80613:10:0;;;;;;;;;;;;-1:-1:-1;;;80613:10:0;;;;;80317:715::o;80582:53::-;80660:5;80645:12;80701:78;80708:9;;80701:78;;80734:8;;;;:::i;:::-;;-1:-1:-1;80757:10:0;;-1:-1:-1;80765:2:0;80757:10;;:::i;:::-;;;80701:78;;;80789:19;80821:6;-1:-1:-1;;;;;80811:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80811:17:0;;80789:39;;80839:154;80846:10;;80839:154;;80873:11;80883:1;80873:11;;:::i;:::-;;-1:-1:-1;80942:10:0;80950:2;80942:5;:10;:::i;:::-;80929:24;;:2;:24;:::i;:::-;80916:39;;80899:6;80906;80899:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;80899:56:0;;;;;;;;-1:-1:-1;80970:11:0;80979:2;80970:11;;:::i;:::-;;;80839:154;;;81017:6;80317:715;-1:-1:-1;;;;80317:715:0:o;81039:414::-;81126:13;;;81136:2;81126:13;;;81087;81126;;;;;;81109:14;;81126:13;;;;;;;;;;;-1:-1:-1;81126:13:0;81109:30;;81151:6;81146:281;81167:2;81163:1;:6;81146:281;;;81187:8;81238:6;81243:1;81238:2;:6;:::i;:::-;81235:10;;:1;:10;:::i;:::-;81231:15;;:1;:15;:::i;:::-;81211:36;;-1:-1:-1;;;;;81211:16:0;;:36;:::i;:::-;81198:51;;81187:62;;81260:9;81290:2;81285:1;81279:8;;:13;;;;:::i;:::-;81272:21;;81260:33;;81304:9;81345:2;81339:9;;81334:2;:14;;;;:::i;:::-;81329:1;81323:8;;:25;;;;:::i;:::-;81316:33;;81304:45;;81369:8;81374:2;81369:4;:8::i;:::-;81360:1;81362:3;81364:1;81362;:3;:::i;:::-;81360:6;;;;;;;;:::i;:::-;;;;:17;-1:-1:-1;;;;;81360:17:0;;;;;;;;;81399:8;81404:2;81399:4;:8::i;:::-;81388:1;81390:3;81392:1;81390;:3;:::i;:::-;:5;;81394:1;81390:5;:::i;:::-;81388:8;;;;;;;;:::i;:::-;;;;:19;-1:-1:-1;;;;;81388:19:0;;;;;;;;-1:-1:-1;;81171:3:0;;;;;-1:-1:-1;81146:281:0;;-1:-1:-1;81146:281:0;;-1:-1:-1;81447:1:0;81039:414;-1:-1:-1;;81039:414:0:o;81958:1607::-;82056:11;;82016:13;;82042:11;82082:8;;;82078:23;;-1:-1:-1;;82092:9:0;;;;;;;;;-1:-1:-1;82092:9:0;;;81958:1607;-1:-1:-1;81958:1607:0:o;82078:23::-;82153:18;82191:1;82180:7;:3;82186:1;82180:7;:::i;:::-;82179:13;;;;:::i;:::-;82174:19;;:1;:19;:::i;:::-;82153:40;-1:-1:-1;82251:19:0;82283:15;82153:40;82296:2;82283:15;:::i;:::-;-1:-1:-1;;;;;82273:26:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82273:26:0;;82251:48;;82312:18;82333:5;;;;;;;;;;;;;;;;;82312:26;;82402:1;82395:5;82391:13;82447:2;82439:6;82435:15;82498:1;82466:777;82521:3;82518:1;82515:10;82466:777;;;82576:1;82619:12;;;;;82613:19;82714:4;82702:2;82698:14;;;;;82680:40;;82674:47;82823:2;82819:14;;;82815:25;;82801:40;;82795:47;82952:1;82948:13;;;82944:24;;82930:39;;82924:46;83072:16;;;;83058:31;;83052:38;82750:1;82746:11;;;82844:4;82791:58;;;82782:68;82875:11;;82920:57;;;82911:67;;;;83003:11;;83048:49;;83039:59;83127:3;83123:13;83156:22;;83226:1;83211:17;;;;82569:9;82466:777;;;82470:44;83275:1;83270:3;83266:11;83296:1;83291:84;;;;83394:1;83389:82;;;;83259:212;;83291:84;-1:-1:-1;;;;;83324:17:0;;83317:43;83291:84;;83389:82;-1:-1:-1;;;;;83422:17:0;;83415:41;83259:212;-1:-1:-1;;;83487:26:0;;;83494:6;81958:1607;-1:-1:-1;;;;81958:1607:0:o;56218:678::-;56380:9;:31;;;-1:-1:-1;;;;;;56393:18:0;;;;56380:31;56376:471;;;56428:13;56444:22;56458:7;56444:13;:22::i;:::-;56428:38;-1:-1:-1;;;;;;56597:18:0;;;;;;:35;;;56628:4;-1:-1:-1;;;;;56619:13:0;:5;-1:-1:-1;;;;;56619:13:0;;;56597:35;:69;;;;;56637:29;56654:5;56661:4;56637:16;:29::i;:::-;56636:30;56597:69;56593:144;;;56694:27;;-1:-1:-1;;;56694:27:0;;-1:-1:-1;;;;;1719:32:1;;56694:27:0;;;1701:51:1;1674:18;;56694:27:0;1555:203:1;56593:144:0;56757:9;56753:83;;;56812:7;56808:2;-1:-1:-1;;;;;56792:28:0;56801:5;-1:-1:-1;;;;;56792:28:0;;;;;;;;;;;56753:83;56413:434;56376:471;-1:-1:-1;;56859:24:0;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;56859:29:0;-1:-1:-1;;;;;56859:29:0;;;;;;;;;;56218:678::o;48376:376::-;48489:38;48503:5;48510:7;48519;48489:13;:38::i;:::-;48484:261;;-1:-1:-1;;;;;48548:19:0;;48544:190;;48595:31;;-1:-1:-1;;;48595:31:0;;;;;2346:25:1;;;2319:18;;48595:31:0;2200:177:1;48544:190:0;48674:44;;-1:-1:-1;;;48674:44:0;;-1:-1:-1;;;;;3160:32:1;;48674:44:0;;;3142:51:1;3209:18;;;3202:34;;;3115:18;;48674:44:0;2968:274:1;52356:185:0;52451:18;52457:2;52461:7;52451:5;:18::i;:::-;52480:53;52511:1;52515:2;52519:7;52528:4;52480:22;:53::i;81457:150::-;81495:8;81527:2;81516:8;;;;:13;81512:91;;;81545:15;:8;;;;81556:4;81545:15;:::i;:::-;81538:23;;;81457:150;-1:-1:-1;;81457:150:0:o;81512:91::-;81587:15;:8;;;;81598:4;81587:15;:::i;81512:91::-;81457:150;;;:::o;47656:276::-;47759:4;-1:-1:-1;;;;;47796:21:0;;;;;;:128;;;47844:7;-1:-1:-1;;;;;47835:16:0;:5;-1:-1:-1;;;;;47835:16:0;;:52;;;;47855:32;47872:5;47879:7;47855:16;:32::i;:::-;47835:88;;;-1:-1:-1;;47277:7:0;47304:24;;;:15;:24;;;;;;-1:-1:-1;;;;;47304:24:0;;;47891:32;;;;47776:148;-1:-1:-1;47656:276:0:o;51329:335::-;-1:-1:-1;;;;;51397:16:0;;51393:89;;51437:33;;-1:-1:-1;;;51437:33:0;;51467:1;51437:33;;;1701:51:1;1674:18;;51437:33:0;1555:203:1;51393:89:0;51492:21;51516:32;51524:2;51528:7;51545:1;51516:7;:32::i;:::-;51492:56;-1:-1:-1;;;;;;51563:27:0;;;51559:98;;51614:31;;-1:-1:-1;;;51614:31:0;;51642:1;51614:31;;;1701:51:1;1674:18;;51614:31:0;1555:203:1;14:131;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:1:o;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:1;816:16;;809:27;592:250::o;847:282::-;900:3;938:5;932:12;965:6;960:3;953:19;981:76;1050:6;1043:4;1038:3;1034:14;1027:4;1020:5;1016:16;981:76;:::i;:::-;1111:2;1090:15;-1:-1:-1;;1086:29:1;1077:39;;;;1118:4;1073:50;;847:282;-1:-1:-1;;847:282:1:o;1134:231::-;1283:2;1272:9;1265:21;1246:4;1303:56;1355:2;1344:9;1340:18;1332:6;1303:56;:::i;1370:180::-;1429:6;1482:2;1470:9;1461:7;1457:23;1453:32;1450:52;;;1498:1;1495;1488:12;1450:52;-1:-1:-1;1521:23:1;;1370:180;-1:-1:-1;1370:180:1:o;1763:173::-;1831:20;;-1:-1:-1;;;;;1880:31:1;;1870:42;;1860:70;;1926:1;1923;1916:12;1941:254;2009:6;2017;2070:2;2058:9;2049:7;2045:23;2041:32;2038:52;;;2086:1;2083;2076:12;2038:52;2109:29;2128:9;2109:29;:::i;:::-;2099:39;2185:2;2170:18;;;;2157:32;;-1:-1:-1;;;1941:254:1:o;2382:328::-;2459:6;2467;2475;2528:2;2516:9;2507:7;2503:23;2499:32;2496:52;;;2544:1;2541;2534:12;2496:52;2567:29;2586:9;2567:29;:::i;:::-;2557:39;;2615:38;2649:2;2638:9;2634:18;2615:38;:::i;:::-;2605:48;;2700:2;2689:9;2685:18;2672:32;2662:42;;2382:328;;;;;:::o;2715:248::-;2783:6;2791;2844:2;2832:9;2823:7;2819:23;2815:32;2812:52;;;2860:1;2857;2850:12;2812:52;-1:-1:-1;;2883:23:1;;;2953:2;2938:18;;;2925:32;;-1:-1:-1;2715:248:1:o;3247:284::-;3305:6;3358:2;3346:9;3337:7;3333:23;3329:32;3326:52;;;3374:1;3371;3364:12;3326:52;3413:9;3400:23;-1:-1:-1;;;;;3456:5:1;3452:30;3445:5;3442:41;3432:69;;3497:1;3494;3487:12;3762:127;3823:10;3818:3;3814:20;3811:1;3804:31;3854:4;3851:1;3844:15;3878:4;3875:1;3868:15;3894:275;3965:2;3959:9;4030:2;4011:13;;-1:-1:-1;;4007:27:1;3995:40;;-1:-1:-1;;;;;4050:34:1;;4086:22;;;4047:62;4044:88;;;4112:18;;:::i;:::-;4148:2;4141:22;3894:275;;-1:-1:-1;3894:275:1:o;4174:187::-;4223:4;-1:-1:-1;;;;;4248:6:1;4245:30;4242:56;;;4278:18;;:::i;:::-;-1:-1:-1;4344:2:1;4323:15;-1:-1:-1;;4319:29:1;4350:4;4315:40;;4174:187::o;4366:464::-;4409:5;4462:3;4455:4;4447:6;4443:17;4439:27;4429:55;;4480:1;4477;4470:12;4429:55;4516:6;4503:20;4547:49;4563:32;4592:2;4563:32;:::i;:::-;4547:49;:::i;:::-;4621:2;4612:7;4605:19;4667:3;4660:4;4655:2;4647:6;4643:15;4639:26;4636:35;4633:55;;;4684:1;4681;4674:12;4633:55;4749:2;4742:4;4734:6;4730:17;4723:4;4714:7;4710:18;4697:55;4797:1;4772:16;;;4790:4;4768:27;4761:38;;;;4776:7;4366:464;-1:-1:-1;;;4366:464:1:o;4835:390::-;4913:6;4921;4974:2;4962:9;4953:7;4949:23;4945:32;4942:52;;;4990:1;4987;4980:12;4942:52;5030:9;5017:23;-1:-1:-1;;;;;5055:6:1;5052:30;5049:50;;;5095:1;5092;5085:12;5049:50;5118;5160:7;5151:6;5140:9;5136:22;5118:50;:::i;:::-;5108:60;5215:2;5200:18;;;;5187:32;;-1:-1:-1;;;;4835:390:1:o;5464:347::-;5515:8;5525:6;5579:3;5572:4;5564:6;5560:17;5556:27;5546:55;;5597:1;5594;5587:12;5546:55;-1:-1:-1;5620:20:1;;-1:-1:-1;;;;;5652:30:1;;5649:50;;;5695:1;5692;5685:12;5649:50;5732:4;5724:6;5720:17;5708:29;;5784:3;5777:4;5768:6;5760;5756:19;5752:30;5749:39;5746:59;;;5801:1;5798;5791:12;5746:59;5464:347;;;;;:::o;5816:717::-;5906:6;5914;5922;5930;5983:2;5971:9;5962:7;5958:23;5954:32;5951:52;;;5999:1;5996;5989:12;5951:52;6039:9;6026:23;-1:-1:-1;;;;;6109:2:1;6101:6;6098:14;6095:34;;;6125:1;6122;6115:12;6095:34;6164:58;6214:7;6205:6;6194:9;6190:22;6164:58;:::i;:::-;6241:8;;-1:-1:-1;6138:84:1;-1:-1:-1;6329:2:1;6314:18;;6301:32;;-1:-1:-1;6345:16:1;;;6342:36;;;6374:1;6371;6364:12;6342:36;;6413:60;6465:7;6454:8;6443:9;6439:24;6413:60;:::i;:::-;5816:717;;;;-1:-1:-1;6492:8:1;-1:-1:-1;;;;5816:717:1:o;6538:750::-;6839:3;6828:9;6821:22;6802:4;6866:57;6918:3;6907:9;6903:19;6895:6;6866:57;:::i;:::-;6971:9;6963:6;6959:22;6954:2;6943:9;6939:18;6932:50;7005:44;7042:6;7034;7005:44;:::i;:::-;6991:58;;7097:9;7089:6;7085:22;7080:2;7069:9;7065:18;7058:50;7125:44;7162:6;7154;7125:44;:::i;:::-;7200:2;7185:18;;7178:34;;;;-1:-1:-1;;;;;;;7249:32:1;;;;7243:3;7228:19;;;7221:61;7117:52;6538:750;-1:-1:-1;;;6538:750:1:o;7293:186::-;7352:6;7405:2;7393:9;7384:7;7380:23;7376:32;7373:52;;;7421:1;7418;7411:12;7373:52;7444:29;7463:9;7444:29;:::i;7484:321::-;7552:6;7605:2;7593:9;7584:7;7580:23;7576:32;7573:52;;;7621:1;7618;7611:12;7573:52;7661:9;7648:23;-1:-1:-1;;;;;7686:6:1;7683:30;7680:50;;;7726:1;7723;7716:12;7680:50;7749;7791:7;7782:6;7771:9;7767:22;7749:50;:::i;7810:571::-;8088:1;8084;8079:3;8075:11;8071:19;8063:6;8059:32;8048:9;8041:51;8128:6;8123:2;8112:9;8108:18;8101:34;8171:3;8166:2;8155:9;8151:18;8144:31;8022:4;8198:57;8250:3;8239:9;8235:19;8227:6;8198:57;:::i;:::-;8303:9;8295:6;8291:22;8286:2;8275:9;8271:18;8264:50;8331:44;8368:6;8360;8331:44;:::i;:::-;8323:52;7810:571;-1:-1:-1;;;;;;;7810:571:1:o;8386:390::-;8464:6;8472;8525:2;8513:9;8504:7;8500:23;8496:32;8493:52;;;8541:1;8538;8531:12;8493:52;8577:9;8564:23;8554:33;;8638:2;8627:9;8623:18;8610:32;-1:-1:-1;;;;;8657:6:1;8654:30;8651:50;;;8697:1;8694;8687:12;8651:50;8720;8762:7;8753:6;8742:9;8738:22;8720:50;:::i;:::-;8710:60;;;8386:390;;;;;:::o;8781:1151::-;8912:6;8920;8928;8936;8944;8952;8960;8968;9021:3;9009:9;9000:7;8996:23;8992:33;8989:53;;;9038:1;9035;9028:12;8989:53;9061:29;9080:9;9061:29;:::i;:::-;9051:39;;9141:2;9130:9;9126:18;9113:32;-1:-1:-1;;;;;9205:2:1;9197:6;9194:14;9191:34;;;9221:1;9218;9211:12;9191:34;9260:58;9310:7;9301:6;9290:9;9286:22;9260:58;:::i;:::-;9337:8;;-1:-1:-1;9234:84:1;-1:-1:-1;9425:2:1;9410:18;;9397:32;;-1:-1:-1;9441:16:1;;;9438:36;;;9470:1;9467;9460:12;9438:36;9509:60;9561:7;9550:8;9539:9;9535:24;9509:60;:::i;:::-;9588:8;;-1:-1:-1;9483:86:1;-1:-1:-1;9676:2:1;9661:18;;9648:32;;-1:-1:-1;9692:16:1;;;9689:36;;;9721:1;9718;9711:12;9689:36;;9760:60;9812:7;9801:8;9790:9;9786:24;9760:60;:::i;:::-;8781:1151;;;;-1:-1:-1;8781:1151:1;;;;;;9734:86;;9921:3;9906:19;9893:33;;8781:1151;-1:-1:-1;;;;8781:1151:1:o;9937:118::-;10023:5;10016:13;10009:21;10002:5;9999:32;9989:60;;10045:1;10042;10035:12;10060:315;10125:6;10133;10186:2;10174:9;10165:7;10161:23;10157:32;10154:52;;;10202:1;10199;10192:12;10154:52;10225:29;10244:9;10225:29;:::i;:::-;10215:39;;10304:2;10293:9;10289:18;10276:32;10317:28;10339:5;10317:28;:::i;:::-;10364:5;10354:15;;;10060:315;;;;;:::o;10380:1073::-;10499:6;10507;10515;10523;10531;10539;10547;10600:3;10588:9;10579:7;10575:23;10571:33;10568:53;;;10617:1;10614;10607:12;10568:53;10653:9;10640:23;10630:33;;10714:2;10703:9;10699:18;10686:32;-1:-1:-1;;;;;10778:2:1;10770:6;10767:14;10764:34;;;10794:1;10791;10784:12;10764:34;10833:58;10883:7;10874:6;10863:9;10859:22;10833:58;:::i;:::-;10910:8;;-1:-1:-1;10807:84:1;-1:-1:-1;10998:2:1;10983:18;;10970:32;;-1:-1:-1;11014:16:1;;;11011:36;;;11043:1;11040;11033:12;11011:36;11082:60;11134:7;11123:8;11112:9;11108:24;11082:60;:::i;:::-;11161:8;;-1:-1:-1;11056:86:1;-1:-1:-1;11249:2:1;11234:18;;11221:32;;-1:-1:-1;11265:16:1;;;11262:36;;;11294:1;11291;11284:12;11262:36;;11333:60;11385:7;11374:8;11363:9;11359:24;11333:60;:::i;:::-;10380:1073;;;;-1:-1:-1;10380:1073:1;;-1:-1:-1;10380:1073:1;;;;11307:86;;-1:-1:-1;;;10380:1073:1:o;11458:785::-;11557:6;11565;11573;11581;11589;11642:2;11630:9;11621:7;11617:23;11613:32;11610:52;;;11658:1;11655;11648:12;11610:52;11694:9;11681:23;11671:33;;11755:2;11744:9;11740:18;11727:32;-1:-1:-1;;;;;11819:2:1;11811:6;11808:14;11805:34;;;11835:1;11832;11825:12;11805:34;11874:58;11924:7;11915:6;11904:9;11900:22;11874:58;:::i;:::-;11951:8;;-1:-1:-1;11848:84:1;-1:-1:-1;12039:2:1;12024:18;;12011:32;;-1:-1:-1;12055:16:1;;;12052:36;;;12084:1;12081;12074:12;12052:36;;12123:60;12175:7;12164:8;12153:9;12149:24;12123:60;:::i;:::-;11458:785;;;;-1:-1:-1;11458:785:1;;-1:-1:-1;12202:8:1;;12097:86;11458:785;-1:-1:-1;;;11458:785:1:o;12248:538::-;12343:6;12351;12359;12367;12420:3;12408:9;12399:7;12395:23;12391:33;12388:53;;;12437:1;12434;12427:12;12388:53;12460:29;12479:9;12460:29;:::i;:::-;12450:39;;12508:38;12542:2;12531:9;12527:18;12508:38;:::i;:::-;12498:48;;12593:2;12582:9;12578:18;12565:32;12555:42;;12648:2;12637:9;12633:18;12620:32;-1:-1:-1;;;;;12667:6:1;12664:30;12661:50;;;12707:1;12704;12697:12;12661:50;12730;12772:7;12763:6;12752:9;12748:22;12730:50;:::i;:::-;12720:60;;;12248:538;;;;;;;:::o;12791:1004::-;12901:6;12909;12917;12925;12933;12941;12994:2;12982:9;12973:7;12969:23;12965:32;12962:52;;;13010:1;13007;13000:12;12962:52;13050:9;13037:23;-1:-1:-1;;;;;13120:2:1;13112:6;13109:14;13106:34;;;13136:1;13133;13126:12;13106:34;13175:58;13225:7;13216:6;13205:9;13201:22;13175:58;:::i;:::-;13252:8;;-1:-1:-1;13149:84:1;-1:-1:-1;13340:2:1;13325:18;;13312:32;;-1:-1:-1;13356:16:1;;;13353:36;;;13385:1;13382;13375:12;13353:36;13424:60;13476:7;13465:8;13454:9;13450:24;13424:60;:::i;:::-;13503:8;;-1:-1:-1;13398:86:1;-1:-1:-1;13591:2:1;13576:18;;13563:32;;-1:-1:-1;13607:16:1;;;13604:36;;;13636:1;13633;13626:12;13604:36;;13675:60;13727:7;13716:8;13705:9;13701:24;13675:60;:::i;:::-;12791:1004;;;;-1:-1:-1;12791:1004:1;;-1:-1:-1;12791:1004:1;;13754:8;;12791:1004;-1:-1:-1;;;12791:1004:1:o;13800:260::-;13868:6;13876;13929:2;13917:9;13908:7;13904:23;13900:32;13897:52;;;13945:1;13942;13935:12;13897:52;13968:29;13987:9;13968:29;:::i;:::-;13958:39;;14016:38;14050:2;14039:9;14035:18;14016:38;:::i;14270:380::-;14349:1;14345:12;;;;14392;;;14413:61;;14467:4;14459:6;14455:17;14445:27;;14413:61;14520:2;14512:6;14509:14;14489:18;14486:38;14483:161;;14566:10;14561:3;14557:20;14554:1;14547:31;14601:4;14598:1;14591:15;14629:4;14626:1;14619:15;14483:161;;14270:380;;;:::o;15035:127::-;15096:10;15091:3;15087:20;15084:1;15077:31;15127:4;15124:1;15117:15;15151:4;15148:1;15141:15;15167:168;15240:9;;;15271;;15288:15;;;15282:22;;15268:37;15258:71;;15309:18;;:::i;15340:127::-;15401:10;15396:3;15392:20;15389:1;15382:31;15432:4;15429:1;15422:15;15456:4;15453:1;15446:15;15472:120;15512:1;15538;15528:35;;15543:18;;:::i;:::-;-1:-1:-1;15577:9:1;;15472:120::o;15597:245::-;15664:6;15717:2;15705:9;15696:7;15692:23;15688:32;15685:52;;;15733:1;15730;15723:12;15685:52;15765:9;15759:16;15784:28;15806:5;15784:28;:::i;15847:198::-;15889:3;15927:5;15921:12;15942:65;16000:6;15995:3;15988:4;15981:5;15977:16;15942:65;:::i;:::-;16023:16;;;;;15847:198;-1:-1:-1;;15847:198:1:o;16050:361::-;16239:6;16234:3;16227:19;16209:3;16275:6;16269:13;16291:73;16357:6;16352:2;16347:3;16343:12;16338:2;16330:6;16326:15;16291:73;:::i;:::-;16384:16;;;;16402:2;16380:25;;16050:361;-1:-1:-1;;;16050:361:1:o;16770:271::-;16953:6;16945;16940:3;16927:33;16909:3;16979:16;;17004:13;;;16979:16;16770:271;-1:-1:-1;16770:271:1:o;17172:723::-;17222:3;17263:5;17257:12;17292:36;17318:9;17292:36;:::i;:::-;17347:1;17364:17;;;17390:133;;;;17537:1;17532:357;;;;17357:532;;17390:133;-1:-1:-1;;17423:24:1;;17411:37;;17496:14;;17489:22;17477:35;;17468:45;;;-1:-1:-1;17390:133:1;;17532:357;17563:5;17560:1;17553:16;17592:4;17637;17634:1;17624:18;17664:1;17678:165;17692:6;17689:1;17686:13;17678:165;;;17770:14;;17757:11;;;17750:35;17813:16;;;;17707:10;;17678:165;;;17682:3;;;17872:6;17867:3;17863:16;17856:23;;17357:532;;;;;17172:723;;;;:::o;17900:433::-;18174:3;18202:38;18236:3;18228:6;18202:38;:::i;:::-;-1:-1:-1;;;18256:2:1;18249:17;18282:45;18324:1;18320:2;18316:10;18308:6;18282:45;:::i;:::-;18275:52;17900:433;-1:-1:-1;;;;;17900:433:1:o;18338:289::-;18469:3;18507:6;18501:13;18523:66;18582:6;18577:3;18570:4;18562:6;18558:17;18523:66;:::i;:::-;18605:16;;;;;18338:289;-1:-1:-1;;18338:289:1:o;18632:125::-;18697:9;;;18718:10;;;18715:36;;;18731:18;;:::i;19107:549::-;19451:6;19443;19438:3;19425:33;19407:3;19486:6;19481:3;19477:16;-1:-1:-1;;;19509:2:1;19502:17;19561:6;19553;19549:1;19545:2;19541:10;19528:40;19630:1;19591:15;;19608:1;19587:23;19619:13;;;-1:-1:-1;19587:23:1;;19107:549;-1:-1:-1;;;;19107:549:1:o;20712:518::-;20814:2;20809:3;20806:11;20803:421;;;20850:5;20847:1;20840:16;20894:4;20891:1;20881:18;20964:2;20952:10;20948:19;20945:1;20941:27;20935:4;20931:38;21000:4;20988:10;20985:20;20982:47;;;-1:-1:-1;21023:4:1;20982:47;21078:2;21073:3;21069:12;21066:1;21062:20;21056:4;21052:31;21042:41;;21133:81;21151:2;21144:5;21141:13;21133:81;;;21210:1;21196:16;;21177:1;21166:13;21133:81;;21406:1345;21532:3;21526:10;-1:-1:-1;;;;;21551:6:1;21548:30;21545:56;;;21581:18;;:::i;:::-;21610:97;21700:6;21660:38;21692:4;21686:11;21660:38;:::i;:::-;21654:4;21610:97;:::i;:::-;21762:4;;21819:2;21808:14;;21836:1;21831:663;;;;22538:1;22555:6;22552:89;;;-1:-1:-1;22607:19:1;;;22601:26;22552:89;-1:-1:-1;;21363:1:1;21359:11;;;21355:24;21351:29;21341:40;21387:1;21383:11;;;21338:57;22654:81;;21801:944;;21831:663;17119:1;17112:14;;;17156:4;17143:18;;-1:-1:-1;;21867:20:1;;;21985:236;21999:7;21996:1;21993:14;21985:236;;;22088:19;;;22082:26;22067:42;;22180:27;;;;22148:1;22136:14;;;;22015:19;;21985:236;;;21989:3;22249:6;22240:7;22237:19;22234:201;;;22310:19;;;22304:26;-1:-1:-1;;22393:1:1;22389:14;;;22405:3;22385:24;22381:37;22377:42;22362:58;22347:74;;22234:201;;;22481:1;22472:6;22469:1;22465:14;22461:22;22455:4;22448:36;21801:944;;;;;21406:1345;;:::o;22756:135::-;22795:3;22816:17;;;22813:43;;22836:18;;:::i;:::-;-1:-1:-1;22883:1:1;22872:13;;22756:135::o;22896:128::-;22963:9;;;22984:11;;;22981:37;;;22998:18;;:::i;23029:266::-;23117:6;23112:3;23105:19;23169:6;23162:5;23155:4;23150:3;23146:14;23133:43;-1:-1:-1;23221:1:1;23196:16;;;23214:4;23192:27;;;23185:38;;;;23277:2;23256:15;;;-1:-1:-1;;23252:29:1;23243:39;;;23239:50;;23029:266::o;23300:244::-;23457:2;23446:9;23439:21;23420:4;23477:61;23534:2;23523:9;23519:18;23511:6;23503;23477:61;:::i;23549:184::-;23619:6;23672:2;23660:9;23651:7;23647:23;23643:32;23640:52;;;23688:1;23685;23678:12;23640:52;-1:-1:-1;23711:16:1;;23549:184;-1:-1:-1;23549:184:1:o;23738:315::-;23923:6;23912:9;23905:25;23966:2;23961;23950:9;23946:18;23939:30;23886:4;23986:61;24043:2;24032:9;24028:18;24020:6;24012;23986:61;:::i;24058:431::-;24271:2;24260:9;24253:21;24234:4;24297:61;24354:2;24343:9;24339:18;24331:6;24323;24297:61;:::i;:::-;24406:9;24398:6;24394:22;24389:2;24378:9;24374:18;24367:50;24434:49;24476:6;24468;24460;24434:49;:::i;25186:201::-;25318:3;25343:38;25377:3;25369:6;25343:38;:::i;25392:1198::-;-1:-1:-1;;;;;25511:3:1;25508:27;25505:53;;;25538:18;;:::i;:::-;25567:94;25657:3;25617:38;25649:4;25643:11;25617:38;:::i;:::-;25611:4;25567:94;:::i;:::-;25687:1;25712:2;25707:3;25704:11;25729:1;25724:608;;;;26376:1;26393:3;26390:93;;;-1:-1:-1;26449:19:1;;;26436:33;26390:93;-1:-1:-1;;21363:1:1;21359:11;;;21355:24;21351:29;21341:40;21387:1;21383:11;;;21338:57;26496:78;;25697:887;;25724:608;17119:1;17112:14;;;17156:4;17143:18;;-1:-1:-1;;25760:17:1;;;25875:229;25889:7;25886:1;25883:14;25875:229;;;25978:19;;;25965:33;25950:49;;26085:4;26070:20;;;;26038:1;26026:14;;;;25905:12;25875:229;;;25879:3;26132;26123:7;26120:16;26117:159;;;26256:1;26252:6;26246:3;26240;26237:1;26233:11;26229:21;26225:34;26221:39;26208:9;26203:3;26199:19;26186:33;26182:79;26174:6;26167:95;26117:159;;;26319:1;26313:3;26310:1;26306:11;26302:19;26296:4;26289:33;25697:887;;25392:1198;;;:::o;26595:1459::-;26915:6;26904:9;26897:25;26878:4;26941:2;26979:6;26974:2;26963:9;26959:18;26952:34;27022:3;27017:2;27006:9;27002:18;26995:31;27046:1;27079:6;27073:13;27109:36;27135:9;27109:36;:::i;:::-;27182:6;27176:3;27165:9;27161:19;27154:35;27208:3;27230:1;27262;27251:9;27247:17;27278:1;27273:160;;;;27447:1;27442:355;;;;27240:557;;27273:160;27341:3;27337:8;27326:9;27322:24;27316:3;27305:9;27301:19;27294:53;27419:3;27407:6;27400:14;27393:22;27390:1;27386:30;27375:9;27371:46;27367:56;27360:63;;27273:160;;27442:355;27473:6;27470:1;27463:17;27521:2;27518:1;27508:16;27546:1;27560:180;27574:6;27571:1;27568:13;27560:180;;;27667:14;;27643:17;;;27639:26;;27632:50;27710:16;;;;27589:10;;27560:180;;;27764:17;;27783:3;27760:27;;-1:-1:-1;;27240:557:1;;;;;;27842:9;27837:3;27833:19;27828:2;27817:9;27813:18;27806:47;27876:46;27918:3;27910:6;27902;27876:46;:::i;:::-;27862:60;;;27971:9;27963:6;27959:22;27953:3;27942:9;27938:19;27931:51;27999:49;28041:6;28033;28025;27999:49;:::i;29191:2259::-;-1:-1:-1;;;30278:43:1;;30260:3;30340:46;30383:1;30374:11;;30366:6;30340:46;:::i;:::-;30406:66;30402:2;30395:78;30502:66;30497:2;30493;30489:11;30482:87;30588:46;30630:2;30626;30622:11;30614:6;30588:46;:::i;:::-;30654:66;30643:78;;-1:-1:-1;;;30745:2:1;30737:11;;30730:65;30578:56;-1:-1:-1;30814:46:1;30856:2;30848:11;;30840:6;30814:46;:::i;:::-;30804:56;;30880:66;30876:2;30869:78;30985:12;30980:3;30976:22;30971:2;30967;30963:11;30956:43;31028:6;31022:13;31044:72;31109:6;31104:2;31100;31096:11;31091:2;31083:6;31079:15;31044:72;:::i;:::-;31179:66;31174:2;31135:15;;;;31166:11;;;31159:87;-1:-1:-1;;;31270:2:1;31262:11;;31255:51;31322:122;31352:91;31378:64;31403:38;31437:2;31429:11;;31421:6;31403:38;:::i;:::-;28408:66;28396:79;;28505:66;28500:2;28491:12;;28484:88;28602:66;28597:2;28588:12;;28581:88;28699:34;28694:2;28685:12;;28678:56;28765:34;28759:3;28750:13;;28743:57;28831:34;28825:3;28816:13;;28809:57;28897:66;28891:3;28882:13;;28875:89;28995:25;28989:3;28980:13;;28973:48;29046:3;29037:13;;28336:720;31378:64;31370:6;31352:91;:::i;:::-;-1:-1:-1;;;29126:27:1;;29178:1;29169:11;;29061:125;31455:461;31717:31;31712:3;31705:44;31687:3;31778:6;31772:13;31794:75;31862:6;31857:2;31852:3;31848:12;31841:4;31833:6;31829:17;31794:75;:::i;:::-;31889:16;;;;31907:2;31885:25;;31455:461;-1:-1:-1;;31455:461:1:o;31921:648::-;32000:6;32053:2;32041:9;32032:7;32028:23;32024:32;32021:52;;;32069:1;32066;32059:12;32021:52;32102:9;32096:16;-1:-1:-1;;;;;32127:6:1;32124:30;32121:50;;;32167:1;32164;32157:12;32121:50;32190:22;;32243:4;32235:13;;32231:27;-1:-1:-1;32221:55:1;;32272:1;32269;32262:12;32221:55;32301:2;32295:9;32326:49;32342:32;32371:2;32342:32;:::i;32326:49::-;32398:2;32391:5;32384:17;32438:7;32433:2;32428;32424;32420:11;32416:20;32413:33;32410:53;;;32459:1;32456;32449:12;32410:53;32472:67;32536:2;32531;32524:5;32520:14;32515:2;32511;32507:11;32472:67;:::i;32784:717::-;33113:6;33102:9;33095:25;33156:3;33151:2;33140:9;33136:18;33129:31;33076:4;33183:57;33235:3;33224:9;33220:19;33212:6;33183:57;:::i;:::-;-1:-1:-1;;;;;33276:32:1;;;;33271:2;33256:18;;33249:60;-1:-1:-1;;;;;;33345:31:1;;;;33340:2;33325:18;;33318:59;33414:22;;;33408:3;33393:19;;;33386:51;-1:-1:-1;33446:17:1;;33492:2;33480:15;;32784:717;-1:-1:-1;;32784:717:1:o;34854:472::-;35087:6;35076:9;35069:25;35159:1;35155;35150:3;35146:11;35142:19;35134:6;35130:32;35125:2;35114:9;35110:18;35103:60;35199:6;35194:2;35183:9;35179:18;35172:34;35242:3;35237:2;35226:9;35222:18;35215:31;35050:4;35263:57;35315:3;35304:9;35300:19;35292:6;35263:57;:::i;:::-;35255:65;34854:472;-1:-1:-1;;;;;;34854:472:1:o;35331:500::-;-1:-1:-1;;;;;35600:15:1;;;35582:34;;35652:15;;35647:2;35632:18;;35625:43;35699:2;35684:18;;35677:34;;;35747:3;35742:2;35727:18;;35720:31;;;35525:4;;35768:57;;35805:19;;35797:6;35768:57;:::i;35836:249::-;35905:6;35958:2;35946:9;35937:7;35933:23;35929:32;35926:52;;;35974:1;35971;35964:12;35926:52;36006:9;36000:16;36025:30;36049:5;36025:30;:::i;36090:112::-;36122:1;36148;36138:35;;36153:18;;:::i;:::-;-1:-1:-1;36187:9:1;;36090:112::o;36207:127::-;36268:10;36263:3;36259:20;36256:1;36249:31;36299:4;36296:1;36289:15;36323:4;36320:1;36313:15;36339:416;36428:1;36465:5;36428:1;36479:270;36500:7;36490:8;36487:21;36479:270;;;36559:4;36555:1;36551:6;36547:17;36541:4;36538:27;36535:53;;;36568:18;;:::i;:::-;36618:7;36608:8;36604:22;36601:55;;;36638:16;;;;36601:55;36717:22;;;;36677:15;;;;36479:270;;;36483:3;36339:416;;;;;:::o;36760:806::-;36809:5;36839:8;36829:80;;-1:-1:-1;36880:1:1;36894:5;;36829:80;36928:4;36918:76;;-1:-1:-1;36965:1:1;36979:5;;36918:76;37010:4;37028:1;37023:59;;;;37096:1;37091:130;;;;37003:218;;37023:59;37053:1;37044:10;;37067:5;;;37091:130;37128:3;37118:8;37115:17;37112:43;;;37135:18;;:::i;:::-;-1:-1:-1;;37191:1:1;37177:16;;37206:5;;37003:218;;37305:2;37295:8;37292:16;37286:3;37280:4;37277:13;37273:36;37267:2;37257:8;37254:16;37249:2;37243:4;37240:12;37236:35;37233:77;37230:159;;;-1:-1:-1;37342:19:1;;;37374:5;;37230:159;37421:34;37446:8;37440:4;37421:34;:::i;:::-;37491:6;37487:1;37483:6;37479:19;37470:7;37467:32;37464:58;;;37502:18;;:::i;:::-;37540:20;;36760:806;-1:-1:-1;;;36760:806:1:o;37571:131::-;37631:5;37660:36;37687:8;37681:4;37660:36;:::i;37707:165::-;37745:1;37779:4;37776:1;37772:12;37803:3;37793:37;;37810:18;;:::i;:::-;37862:3;37855:4;37852:1;37848:12;37844:22;37839:27;;;37707:165;;;;:::o;37877:225::-;37981:4;37960:12;;;37974;;;37956:31;38007:22;;;;38048:24;;;38038:58;;38076:18;;:::i;38107:151::-;38197:4;38190:12;;;38176;;;38172:31;;38215:14;;38212:40;;;38232:18;;:::i;38263:148::-;38351:4;38330:12;;;38344;;;38326:31;;38369:13;;38366:39;;;38385:18;;:::i

Swarm Source

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