ETH Price: $2,653.63 (-0.35%)

Token

ALPHABET (ABET)
 

Overview

Max Total Supply

15 ABET

Holders

11

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 ABET
0x78f553B2858fC58473f7c5307446b2B27d240e6d
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:
AlphaBet

Compiler Version
v0.8.14+commit.80d49f37

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

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

// Sources flattened with hardhat v2.11.2 https://hardhat.org
// SPDX-License-Identifier: MIT
// File @openzeppelin/contracts/utils/[email protected]

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

/**
 * @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.
 *
 * _Available since v4.5._
 */
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/utils/introspection/[email protected]

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

pragma solidity ^0.8.0;

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

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

// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

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

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(
        uint256 _tokenId,
        uint256 _salePrice
    ) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) /
            _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(
            feeNumerator <= _feeDenominator(),
            "ERC2981: royalty fee will exceed salePrice"
        );
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(
            feeNumerator <= _feeDenominator(),
            "ERC2981: royalty fee will exceed salePrice"
        );
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

// File operator-filter-registry/src/lib/[email protected]

pragma solidity ^0.8.13;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

// File operator-filter-registry/src/[email protected]

pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(
        address registrant,
        address operator
    ) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(
        address registrant,
        address subscription
    ) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(
        address registrant,
        address registrantToCopy
    ) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(
        address registrant,
        address operator,
        bool filtered
    ) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(
        address registrant,
        address[] calldata operators,
        bool filtered
    ) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(
        address registrant,
        bytes32 codehash,
        bool filtered
    ) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(
        address registrant,
        bytes32[] calldata codeHashes,
        bool filtered
    ) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(
        address registrant,
        address registrantToSubscribe
    ) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(
        address registrant
    ) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(
        address registrant,
        uint256 index
    ) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(
        address registrant,
        address registrantToCopy
    ) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(
        address registrant,
        address operator
    ) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(
        address registrant,
        address operatorWithCode
    ) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(
        address registrant,
        bytes32 codeHash
    ) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(
        address addr
    ) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(
        address addr
    ) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(
        address registrant,
        uint256 index
    ) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(
        address registrant,
        uint256 index
    ) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}

// File operator-filter-registry/src/[email protected]

pragma solidity ^0.8.13;

/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 *         Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract OperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS);

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(
                    address(this),
                    subscriptionOrRegistrantToCopy
                );
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(
                        address(this),
                        subscriptionOrRegistrantToCopy
                    );
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    /**
     * @dev A helper function to check if an operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (
                !OPERATOR_FILTER_REGISTRY.isOperatorAllowed(
                    address(this),
                    operator
                )
            ) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

// File operator-filter-registry/src/[email protected]

pragma solidity ^0.8.13;

/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 * @dev    Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract DefaultOperatorFilterer is OperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {}
}

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

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

pragma solidity ^0.8.0;

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(
                target,
                data,
                value,
                "Address: low-level call with value failed"
            );
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(
            address(this).balance >= value,
            "Address: insufficient balance for call"
        );
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(
            data
        );
        return verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

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

pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // 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);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(
        uint256 value,
        uint256 length
    ) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

pragma solidity ^0.8.0;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

        _balances[to] += 1;
        _owners[tokenId] = to;

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

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

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

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

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

        _afterTokenTransfer(owner, address(0), 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 virtual {
        require(
            ERC721.ownerOf(tokenId) == from,
            "ERC721: transfer from incorrect owner"
        );
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

        return super.tokenURI(tokenId);
    }

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

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

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

// File contracts/AlphaBet.sol

pragma solidity 0.8.14;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

error ALPHABET_ContractPaused();
error ALPHABET_SaleNotActive();
error ALPHABET_CannotMintSameWordAgain();
error ALPHABET_CannotBeZero();
error ALPHABET_InsufficientFunds();
error ALPHABET_FailedToWithdraw();
error ALPHABET_BalanceIsZero();
error ALPHABET_MaxMintLimitReached();
error ALPHABET_InvalidSignature();
error ALPHABET_InvalidSignatureLength();

contract AlphaBet is
    DefaultOperatorFilterer,
    ERC721,
    ERC721URIStorage,
    Ownable,
    ERC2981
{
    using Counters for Counters.Counter;
    enum SaleConfig {
        PAUSED,
        ACTIVE
    }

    enum SpecialEvent {
        INACTIVE,
        ACTIVE
    }

    struct WordData {
        uint256 currentCost;
        uint256 numbersMinted;
        address[] addressMinted;
    }

    ///////////////////////////////////////////////////////////
    //              SET SALE PAUSED
    // ///////////////////////////////////////////////////////
    SaleConfig private saleConfig = SaleConfig.PAUSED;

    ///////////////////////////////////////////////////////////
    //              PROJECT INFO
    // ///////////////////////////////////////////////////////
    Counters.Counter private _tokenIdCounter;
    uint256 private s_cost = 0.02 ether;
    uint256 private s_maxmintAmount = 1 ether;
    string private s_tos;
    SpecialEvent private s_specialEvent = SpecialEvent.INACTIVE;
    mapping(string => WordData) private mintedWord;
    mapping(address => uint256) private numberOfWordMinted;

    ///////////////////////////////////////////////////////////
    //                      Events
    // ///////////////////////////////////////////////////////
    event Minted(
        address indexed _minter,
        string indexed _word,
        string _uri,
        uint256 indexed _tokenId
    );

    event SaleConfigSet(SaleConfig _saleConfig);

    event SpecialEventSet(SpecialEvent _specialEvent);

    event IntialCostSet(uint256 _cost);

    event MaxMintAmountSet(uint256 _maxMintAmount);

    event TOSUpdated(string _tos);

    event RoyaltyUpdated(address _royaltyAddress, uint256 _royaltyBips);

    event Withdrawn(address _to, uint256 _amount);

    ///////////////////////////////////////////////////////////
    //              TRACKING AND CONSTRUCTOR
    // ///////////////////////////////////////////////////////
    constructor() ERC721("ALPHABET", "ABET") {
        // 1000 Bips = 10%
        _setDefaultRoyalty(msg.sender, 1000);
    }

    ///////////////////////////////////////////////////////////
    //              Modifiers
    // ///////////////////////////////////////////////////////
    modifier mintCompliance(string memory _word) {
        if (!isSaleActive()) revert ALPHABET_SaleNotActive();
        uint256 mintedCount = getNumbersMinted(_word);
        uint256 actualCost = cost(_word, msg.sender);
        if (actualCost > maxMintAmount()) revert ALPHABET_MaxMintLimitReached();
        if (msg.value < actualCost) revert ALPHABET_InsufficientFunds();
        _;
    }

    modifier isSigned(
        bytes32 _ethSignedMessageHash,
        bytes memory _signature,
        address _signer
    ) {
        address signer = getSigner(_ethSignedMessageHash, _signature);
        if (signer != _signer) revert ALPHABET_InvalidSignature();
        _;
    }

    ///////////////////////////////////////////////////////////
    //              Signature Functions
    // ///////////////////////////////////////////////////////

    function getMessageHash(
        string memory message,
        string memory _nonce
    ) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(message, _nonce));
    }

    function getEthSignedMessageHash(
        bytes32 _messageHash
    ) public pure returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(
                    "\x19Ethereum Signed Message:\n32",
                    _messageHash
                )
            );
    }

    function getSigner(
        bytes32 _ethSignedMessageHash,
        bytes memory _signature
    ) public pure returns (address) {
        (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);

        return ecrecover(_ethSignedMessageHash, v, r, s);
    }

    function splitSignature(
        bytes memory sig
    ) public pure returns (bytes32 r, bytes32 s, uint8 v) {
        if (sig.length != 65) revert ALPHABET_InvalidSignatureLength();

        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            v := byte(0, mload(add(sig, 96)))
        }
    }

    ///////////////////////////////////////////////////////////
    //              Get Functions
    // ///////////////////////////////////////////////////////

    function isPaused() public view returns (bool) {
        return saleConfig == SaleConfig.PAUSED;
    }

    function isSaleActive() public view returns (bool) {
        return saleConfig == SaleConfig.ACTIVE;
    }

    function initialCost() public view returns (uint256) {
        return s_cost;
    }

    function maxMintAmount() public view returns (uint256) {
        return s_maxmintAmount;
    }

    function isSpecialEventActive() public view returns (bool) {
        return s_specialEvent == SpecialEvent.ACTIVE;
    }

    function cost(
        string memory _word,
        address _minter
    ) public view returns (uint256) {
        uint256 numberMinted = getNumbersMinted(_word);
        if (numberMinted == 0 && numberOfWordMinted[_minter] == 0) return 0;
        return getCurrentCost(_word) + s_cost;
    }

    function getCurrentCost(string memory _word) public view returns (uint256) {
        return mintedWord[_word].currentCost;
    }

    function getNumbersMinted(
        string memory _word
    ) public view returns (uint256) {
        return mintedWord[_word].numbersMinted;
    }

    function totalSupply() public view returns (uint256) {
        return _tokenIdCounter.current();
    }

    function getTos() public view returns (string memory) {
        return s_tos;
    }

    ///////////////////////////////////////////////////////////
    //             Update Functions
    // ///////////////////////////////////////////////////////
    function setSaleConfig(SaleConfig _status) external onlyOwner {
        saleConfig = _status;
        emit SaleConfigSet(_status);
    }

    function setSpecialEvent(SpecialEvent _status) external onlyOwner {
        s_specialEvent = _status;
        emit SpecialEventSet(_status);
    }

    function setInitialCost(uint256 _cost) external onlyOwner {
        if (_cost == 0) revert ALPHABET_CannotBeZero();
        s_cost = _cost;
        emit IntialCostSet(_cost);
    }

    function setMaxMintAmount(uint256 _maxMintAmount) external onlyOwner {
        if (_maxMintAmount == 0) revert ALPHABET_CannotBeZero();
        s_maxmintAmount = _maxMintAmount;
        emit MaxMintAmountSet(_maxMintAmount);
    }

    // The following functions are overrides required by Solidity.
    function _burn(
        uint256 tokenId
    ) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    /// @inheritdoc IERC165
    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override(ERC721, ERC2981) returns (bool) {
        return
            ERC721.supportsInterface(interfaceId) ||
            ERC2981.supportsInterface(interfaceId);
    }

    function setRoyalty(
        address _receiver,
        uint96 _royaltyFeeInBips
    ) external onlyOwner {
        _setDefaultRoyalty(_receiver, _royaltyFeeInBips);
        emit RoyaltyUpdated(_receiver, _royaltyFeeInBips);
    }

    function setTos(string memory _tos) external onlyOwner {
        s_tos = _tos;
        emit TOSUpdated(_tos);
    }

    function setApprovalForAll(
        address operator,
        bool approved
    ) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(
        address operator,
        uint256 tokenId
    ) public override onlyAllowedOperatorApproval(operator) {
        super.approve(operator, tokenId);
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId, data);
    }

    ///////////////////////////////////////////////////////////
    //              METADATA URI
    // ///////////////////////////////////////////////////////

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

    ///////////////////////////////////////////////////////////
    //              MINT FUNCTIONS
    // ///////////////////////////////////////////////////////

    function mint(
        string memory _word,
        string memory uri,
        bytes32 _ethSignedMessageHash,
        bytes memory _signature
    )
        external
        payable
        mintCompliance(_word)
        isSigned(_ethSignedMessageHash, _signature, msg.sender)
    {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(msg.sender, tokenId);
        _setTokenURI(tokenId, uri);
        mintedWord[_word].currentCost = cost(_word, msg.sender);
        mintedWord[_word].numbersMinted++;
        mintedWord[_word].addressMinted.push(msg.sender);
        numberOfWordMinted[msg.sender]++;
        emit Minted(msg.sender, _word, uri, tokenId);
    }

    ///////////////////////////////////////////////////////////
    //              MINT FUNCTIONS
    // ///////////////////////////////////////////////////////
    function withdrawFunds() external onlyOwner {
        if (address(this).balance == 0) revert ALPHABET_BalanceIsZero();
        uint256 balance = address(this).balance;
        (bool success, ) = owner().call{value: balance}("");
        if (!success) revert ALPHABET_FailedToWithdraw();
        emit Withdrawn(owner(), balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ALPHABET_BalanceIsZero","type":"error"},{"inputs":[],"name":"ALPHABET_CannotBeZero","type":"error"},{"inputs":[],"name":"ALPHABET_FailedToWithdraw","type":"error"},{"inputs":[],"name":"ALPHABET_InsufficientFunds","type":"error"},{"inputs":[],"name":"ALPHABET_InvalidSignature","type":"error"},{"inputs":[],"name":"ALPHABET_InvalidSignatureLength","type":"error"},{"inputs":[],"name":"ALPHABET_MaxMintLimitReached","type":"error"},{"inputs":[],"name":"ALPHABET_SaleNotActive","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"IntialCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_maxMintAmount","type":"uint256"}],"name":"MaxMintAmountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"},{"indexed":true,"internalType":"string","name":"_word","type":"string"},{"indexed":false,"internalType":"string","name":"_uri","type":"string"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_royaltyAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_royaltyBips","type":"uint256"}],"name":"RoyaltyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum AlphaBet.SaleConfig","name":"_saleConfig","type":"uint8"}],"name":"SaleConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum AlphaBet.SpecialEvent","name":"_specialEvent","type":"uint8"}],"name":"SpecialEventSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_tos","type":"string"}],"name":"TOSUpdated","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":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","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":"_word","type":"string"},{"internalType":"address","name":"_minter","type":"address"}],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_word","type":"string"}],"name":"getCurrentCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_messageHash","type":"bytes32"}],"name":"getEthSignedMessageHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"message","type":"string"},{"internalType":"string","name":"_nonce","type":"string"}],"name":"getMessageHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"_word","type":"string"}],"name":"getNumbersMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_ethSignedMessageHash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"getSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTos","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSpecialEventActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_word","type":"string"},{"internalType":"string","name":"uri","type":"string"},{"internalType":"bytes32","name":"_ethSignedMessageHash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"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":"uint256","name":"_cost","type":"uint256"}],"name":"setInitialCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMintAmount","type":"uint256"}],"name":"setMaxMintAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint96","name":"_royaltyFeeInBips","type":"uint96"}],"name":"setRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum AlphaBet.SaleConfig","name":"_status","type":"uint8"}],"name":"setSaleConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum AlphaBet.SpecialEvent","name":"_status","type":"uint8"}],"name":"setSpecialEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_tos","type":"string"}],"name":"setTos","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"splitSignature","outputs":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600a805460ff1990811690915566470de4df820000600c55670de0b6b3a7640000600d55600f805490911690553480156200003e57600080fd5b506040805180820182526008815267105314121050915560c21b602080830191909152825180840190935260048352631050915560e21b9083015290733cc6cdda760b79bafa08df41ecfa224f810dceb660016daaeb6d7670e522a718067333cd4e3b15620001d65780156200012457604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200010557600080fd5b505af11580156200011a573d6000803e3d6000fd5b50505050620001d6565b6001600160a01b03821615620001755760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af290390604401620000ea565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620001bc57600080fd5b505af1158015620001d1573d6000803e3d6000fd5b505050505b50508151620001ed9060009060208501906200038f565b508051620002039060019060208401906200038f565b505050620002206200021a6200023460201b60201c565b62000238565b6200022e336103e86200028a565b62000471565b3390565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b0382161115620002fe5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620003565760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401620002f5565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b8280546200039d9062000435565b90600052602060002090601f016020900481019282620003c157600085556200040c565b82601f10620003dc57805160ff19168380011785556200040c565b828001600101855582156200040c579182015b828111156200040c578251825591602001919060010190620003ef565b506200041a9291506200041e565b5090565b5b808211156200041a57600081556001016200041f565b600181811c908216806200044a57607f821691505b6020821081036200046b57634e487b7160e01b600052602260045260246000fd5b50919050565b61295180620004816000396000f3fe60806040526004361061023b5760003560e01c806363107da41161012e578063a7bb5803116100ab578063e985e9c51161006f578063e985e9c5146106a1578063f1432f9d146106ea578063f2fde38b1461070a578063f7b2ec0d1461072a578063fa5408011461074a57600080fd5b8063a7bb5803146105ee578063b187bd261461062c578063b88d4fde14610641578063c87b56dd14610661578063cb19d5b51461068157600080fd5b80638da5cb5b116100f25780638da5cb5b146105665780638f2fc60b1461058457806395d89b41146105a45780639b4f1ecb146105b9578063a22cb465146105ce57600080fd5b806363107da4146104e95780636352211e146104fe57806370a082311461051e578063715018a61461053e5780637cd989c01461055357600080fd5b806324600fc3116101bc57806341f434341161018057806341f434341461045257806342842e0e146104745780634ce98417146104945780634d92ff28146104b4578063564566a8146104d457600080fd5b806324600fc31461039e5780632a55205a146103b35780633631cd3f146103f25780633be4c4771461041257806340af91ec1461043257600080fd5b806318160ddd1161020357806318160ddd14610311578063183b695e146103345780631a4b3c1214610354578063239c70ae1461036957806323b872dd1461037e57600080fd5b806301ffc9a71461024057806306fdde0314610275578063081812fc14610297578063088a4ed0146102cf578063095ea7b3146102f1575b600080fd5b34801561024c57600080fd5b5061026061025b366004612181565b6107b8565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b5061028a6107d8565b60405161026c91906121f6565b3480156102a357600080fd5b506102b76102b2366004612209565b61086a565b6040516001600160a01b03909116815260200161026c565b3480156102db57600080fd5b506102ef6102ea366004612209565b610891565b005b3480156102fd57600080fd5b506102ef61030c36600461223e565b6108f6565b34801561031d57600080fd5b5061032661090f565b60405190815260200161026c565b34801561034057600080fd5b5061032661034f36600461230b565b61091f565b34801561036057600080fd5b5061028a61094a565b34801561037557600080fd5b50600d54610326565b34801561038a57600080fd5b506102ef610399366004612340565b610959565b3480156103aa57600080fd5b506102ef610984565b3480156103bf57600080fd5b506103d36103ce36600461237c565b610a8c565b604080516001600160a01b03909316835260208301919091520161026c565b3480156103fe57600080fd5b506102ef61040d3660046123ab565b610b38565b34801561041e57600080fd5b5061032661042d3660046123c8565b610b92565b34801561043e57600080fd5b506102ef61044d3660046123ab565b610bf1565b34801561045e57600080fd5b506102b76daaeb6d7670e522a718067333cd4e81565b34801561048057600080fd5b506102ef61048f366004612340565b610c4b565b3480156104a057600080fd5b506103266104af366004612416565b610c70565b3480156104c057600080fd5b506103266104cf36600461230b565b610ca3565b3480156104e057600080fd5b50610260610ccb565b3480156104f557600080fd5b50610260610ced565b34801561050a57600080fd5b506102b7610519366004612209565b610d08565b34801561052a57600080fd5b5061032661053936600461247a565b610d6d565b34801561054a57600080fd5b506102ef610df3565b6102ef610561366004612495565b610e07565b34801561057257600080fd5b506007546001600160a01b03166102b7565b34801561059057600080fd5b506102ef61059f366004612527565b61102d565b3480156105b057600080fd5b5061028a611086565b3480156105c557600080fd5b50600c54610326565b3480156105da57600080fd5b506102ef6105e9366004612578565b611095565b3480156105fa57600080fd5b5061060e61060936600461230b565b6110a9565b60408051938452602084019290925260ff169082015260600161026c565b34801561063857600080fd5b506102606110ee565b34801561064d57600080fd5b506102ef61065c3660046125a4565b6110f6565b34801561066d57600080fd5b5061028a61067c366004612209565b611123565b34801561068d57600080fd5b506102ef61069c36600461230b565b61112e565b3480156106ad57600080fd5b506102606106bc366004612600565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156106f657600080fd5b506102ef610705366004612209565b611179565b34801561071657600080fd5b506102ef61072536600461247a565b6111d7565b34801561073657600080fd5b506102b761074536600461262a565b611250565b34801561075657600080fd5b50610326610765366004612209565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b60006107c3826112cf565b806107d257506107d28261131f565b92915050565b6060600080546107e790612667565b80601f016020809104026020016040519081016040528092919081815260200182805461081390612667565b80156108605780601f1061083557610100808354040283529160200191610860565b820191906000526020600020905b81548152906001019060200180831161084357829003601f168201915b5050505050905090565b600061087582611344565b506000908152600460205260409020546001600160a01b031690565b6108996113a3565b806000036108ba576040516327c3ca8f60e01b815260040160405180910390fd5b600d8190556040518181527fb76de10430cfde1d7dd54e1e915f8f57ec2a4ae0e29ebb4ff6a8694aeb2f9bfb906020015b60405180910390a150565b81610900816113fd565b61090a83836114b6565b505050565b600061091a600b5490565b905090565b600060108260405161093191906126a1565b9081526020016040518091039020600101549050919050565b6060600e80546107e790612667565b826001600160a01b038116331461097357610973336113fd565b61097e8484846115c6565b50505050565b61098c6113a3565b476000036109ad576040516371bec8b360e01b815260040160405180910390fd5b4760006109c26007546001600160a01b031690565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610a0c576040519150601f19603f3d011682016040523d82523d6000602084013e610a11565b606091505b5050905080610a33576040516322f4ec0f60e11b815260040160405180910390fd5b7f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5610a666007546001600160a01b031690565b604080516001600160a01b03909216825260208201859052015b60405180910390a15050565b60008281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610b015750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610b20906001600160601b0316876126d3565b610b2a9190612708565b915196919550909350505050565b610b406113a3565b600f805482919060ff191660018381811115610b5e57610b5e61271c565b02179055507fd64e77d0e3733743cb4a55b7d0ed4735b2fcc1d9ed4d52afc74f19ef3575016b816040516108eb9190612750565b600080610b9e8461091f565b905080158015610bc457506001600160a01b038316600090815260116020526040902054155b15610bd35760009150506107d2565b600c54610bdf85610ca3565b610be99190612763565b949350505050565b610bf96113a3565b600a805482919060ff191660018381811115610c1757610c1761271c565b02179055507fd90ea9ea059fcc79787986dd24a3e6da93c5f73c09e2669ac4ea7bbfec0a6cdb816040516108eb9190612750565b826001600160a01b0381163314610c6557610c65336113fd565b61097e8484846115f7565b60008282604051602001610c8592919061277b565b60405160208183030381529060405280519060200120905092915050565b6000601082604051610cb591906126a1565b9081526040519081900360200190205492915050565b600060015b600a5460ff166001811115610ce757610ce761271c565b14905090565b60006001600f5460ff166001811115610ce757610ce761271c565b6000818152600260205260408120546001600160a01b0316806107d25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064015b60405180910390fd5b60006001600160a01b038216610dd75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610d64565b506001600160a01b031660009081526003602052604090205490565b610dfb6113a3565b610e056000611612565b565b83610e10610ccb565b610e2d57604051636be5929360e01b815260040160405180910390fd5b6000610e388261091f565b90506000610e468333610b92565b9050610e51600d5490565b811115610e7157604051636c5a84a760e11b815260040160405180910390fd5b80341015610e9257604051633d61be4960e11b815260040160405180910390fd5b8484336000610ea18484611250565b9050816001600160a01b0316816001600160a01b031614610ed5576040516351a01e6f60e11b815260040160405180910390fd5b6000610ee0600b5490565b9050610ef0600b80546001019055565b610efa3382611664565b610f04818c611682565b610f0e8c33610b92565b60108d604051610f1e91906126a1565b90815260405190819003602001812091909155601090610f3f908e906126a1565b9081526040519081900360200190206001018054906000610f5f836127aa565b919050555060108c604051610f7491906126a1565b908152604080516020928190038301902060020180546001810182556000918252838220018054336001600160a01b03199091168117909155815260119092528120805491610fc2836127aa565b9190505550808c604051610fd691906126a1565b6040518091039020336001600160a01b03167f20015b06791b1d5d4cd9dcc64f5b2c746e6fbc352a1e2cd26e70a97518f2fbcd8e60405161101791906121f6565b60405180910390a4505050505050505050505050565b6110356113a3565b61103f828261171c565b604080516001600160a01b03841681526001600160601b03831660208201527faf1c0be9124aef2948fc934d6013ed3f705d2869bc4955cb4f655b0bc2952f659101610a80565b6060600180546107e790612667565b8161109f816113fd565b61090a8383611819565b600080600083516041146110d05760405163ef050af560e01b815260040160405180910390fd5b50505060208101516040820151606090920151909260009190911a90565b600080610cd0565b836001600160a01b038116331461111057611110336113fd565b61111c85858585611824565b5050505050565b60606107d282611856565b6111366113a3565b805161114990600e9060208401906120d2565b507f8443181362f5511dca63ecf006a0d7fa9421f538cb685ab89745d1e23824400d816040516108eb91906121f6565b6111816113a3565b806000036111a2576040516327c3ca8f60e01b815260040160405180910390fd5b600c8190556040518181527f507cd20c9be029443f99076cb7b67f1fe31d40192ac4308445e2b9004618a2ab906020016108eb565b6111df6113a3565b6001600160a01b0381166112445760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d64565b61124d81611612565b50565b60008060008061125f856110a9565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa1580156112ba573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006001600160e01b031982166380ac58cd60e01b148061130057506001600160e01b03198216635b5e139f60e01b145b806107d257506301ffc9a760e01b6001600160e01b03198316146107d2565b60006001600160e01b0319821663152a902d60e11b14806107d257506107d2826112cf565b6000818152600260205260409020546001600160a01b031661124d5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d64565b6007546001600160a01b03163314610e055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d64565b6daaeb6d7670e522a718067333cd4e3b1561124d57604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa15801561146a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148e91906127c3565b61124d57604051633b79c77360e21b81526001600160a01b0382166004820152602401610d64565b60006114c182610d08565b9050806001600160a01b0316836001600160a01b03160361152e5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610d64565b336001600160a01b038216148061154a575061154a81336106bc565b6115bc5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610d64565b61090a838361195e565b6115d033826119cc565b6115ec5760405162461bcd60e51b8152600401610d64906127e0565b61090a838383611a4a565b61090a838383604051806020016040528060008152506110f6565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61167e828260405180602001604052806000815250611be6565b5050565b6000828152600260205260409020546001600160a01b03166116fd5760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610d64565b6000828152600660209081526040909120825161090a928401906120d2565b6127106001600160601b038216111561178a5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610d64565b6001600160a01b0382166117e05760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610d64565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b61167e338383611c19565b61182e33836119cc565b61184a5760405162461bcd60e51b8152600401610d64906127e0565b61097e84848484611ce7565b606061186182611344565b6000828152600660205260408120805461187a90612667565b80601f01602080910402602001604051908101604052809291908181526020018280546118a690612667565b80156118f35780601f106118c8576101008083540402835291602001916118f3565b820191906000526020600020905b8154815290600101906020018083116118d657829003601f168201915b50505050509050600061191160408051602081019091526000815290565b90508051600003611923575092915050565b81511561195557808260405160200161193d92919061277b565b60405160208183030381529060405292505050919050565b610be984611d1a565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061199382610d08565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806119d883610d08565b9050806001600160a01b0316846001600160a01b03161480611a1f57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80610be95750836001600160a01b0316611a388461086a565b6001600160a01b031614949350505050565b826001600160a01b0316611a5d82610d08565b6001600160a01b031614611ac15760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610d64565b6001600160a01b038216611b235760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d64565b611b2e60008261195e565b6001600160a01b0383166000908152600360205260408120805460019290611b5790849061282e565b90915550506001600160a01b0382166000908152600360205260408120805460019290611b85908490612763565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b611bf08383611d8e565b611bfd6000848484611ed0565b61090a5760405162461bcd60e51b8152600401610d6490612845565b816001600160a01b0316836001600160a01b031603611c7a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d64565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611cf2848484611a4a565b611cfe84848484611ed0565b61097e5760405162461bcd60e51b8152600401610d6490612845565b6060611d2582611344565b6000611d3c60408051602081019091526000815290565b90506000815111611d5c5760405180602001604052806000815250611d87565b80611d6684611fd1565b604051602001611d7792919061277b565b6040516020818303038152906040525b9392505050565b6001600160a01b038216611de45760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d64565b6000818152600260205260409020546001600160a01b031615611e495760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d64565b6001600160a01b0382166000908152600360205260408120805460019290611e72908490612763565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b15611fc657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611f14903390899088908890600401612897565b6020604051808303816000875af1925050508015611f4f575060408051601f3d908101601f19168201909252611f4c918101906128d4565b60015b611fac573d808015611f7d576040519150601f19603f3d011682016040523d82523d6000602084013e611f82565b606091505b508051600003611fa45760405162461bcd60e51b8152600401610d6490612845565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610be9565b506001949350505050565b606081600003611ff85750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612022578061200c816127aa565b915061201b9050600a83612708565b9150611ffc565b60008167ffffffffffffffff81111561203d5761203d612268565b6040519080825280601f01601f191660200182016040528015612067576020820181803683370190505b5090505b8415610be95761207c60018361282e565b9150612089600a866128f1565b612094906030612763565b60f81b8183815181106120a9576120a9612905565b60200101906001600160f81b031916908160001a9053506120cb600a86612708565b945061206b565b8280546120de90612667565b90600052602060002090601f0160209004810192826121005760008555612146565b82601f1061211957805160ff1916838001178555612146565b82800160010185558215612146579182015b8281111561214657825182559160200191906001019061212b565b50612152929150612156565b5090565b5b808211156121525760008155600101612157565b6001600160e01b03198116811461124d57600080fd5b60006020828403121561219357600080fd5b8135611d878161216b565b60005b838110156121b95781810151838201526020016121a1565b8381111561097e5750506000910152565b600081518084526121e281602086016020860161219e565b601f01601f19169290920160200192915050565b602081526000611d8760208301846121ca565b60006020828403121561221b57600080fd5b5035919050565b80356001600160a01b038116811461223957600080fd5b919050565b6000806040838503121561225157600080fd5b61225a83612222565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261228f57600080fd5b813567ffffffffffffffff808211156122aa576122aa612268565b604051601f8301601f19908116603f011681019082821181831017156122d2576122d2612268565b816040528381528660208588010111156122eb57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561231d57600080fd5b813567ffffffffffffffff81111561233457600080fd5b610be98482850161227e565b60008060006060848603121561235557600080fd5b61235e84612222565b925061236c60208501612222565b9150604084013590509250925092565b6000806040838503121561238f57600080fd5b50508035926020909101359150565b6002811061124d57600080fd5b6000602082840312156123bd57600080fd5b8135611d878161239e565b600080604083850312156123db57600080fd5b823567ffffffffffffffff8111156123f257600080fd5b6123fe8582860161227e565b92505061240d60208401612222565b90509250929050565b6000806040838503121561242957600080fd5b823567ffffffffffffffff8082111561244157600080fd5b61244d8683870161227e565b9350602085013591508082111561246357600080fd5b506124708582860161227e565b9150509250929050565b60006020828403121561248c57600080fd5b611d8782612222565b600080600080608085870312156124ab57600080fd5b843567ffffffffffffffff808211156124c357600080fd5b6124cf8883890161227e565b955060208701359150808211156124e557600080fd5b6124f18883890161227e565b945060408701359350606087013591508082111561250e57600080fd5b5061251b8782880161227e565b91505092959194509250565b6000806040838503121561253a57600080fd5b61254383612222565b915060208301356001600160601b038116811461255f57600080fd5b809150509250929050565b801515811461124d57600080fd5b6000806040838503121561258b57600080fd5b61259483612222565b9150602083013561255f8161256a565b600080600080608085870312156125ba57600080fd5b6125c385612222565b93506125d160208601612222565b925060408501359150606085013567ffffffffffffffff8111156125f457600080fd5b61251b8782880161227e565b6000806040838503121561261357600080fd5b61261c83612222565b915061240d60208401612222565b6000806040838503121561263d57600080fd5b82359150602083013567ffffffffffffffff81111561265b57600080fd5b6124708582860161227e565b600181811c9082168061267b57607f821691505b60208210810361269b57634e487b7160e01b600052602260045260246000fd5b50919050565b600082516126b381846020870161219e565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156126ed576126ed6126bd565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612717576127176126f2565b500490565b634e487b7160e01b600052602160045260246000fd5b6002811061124d57634e487b7160e01b600052602160045260246000fd5b6020810161275d83612732565b91905290565b60008219821115612776576127766126bd565b500190565b6000835161278d81846020880161219e565b8351908301906127a181836020880161219e565b01949350505050565b6000600182016127bc576127bc6126bd565b5060010190565b6000602082840312156127d557600080fd5b8151611d878161256a565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b600082821015612840576128406126bd565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906128ca908301846121ca565b9695505050505050565b6000602082840312156128e657600080fd5b8151611d878161216b565b600082612900576129006126f2565b500690565b634e487b7160e01b600052603260045260246000fdfea264697066735822122016c2e5fdb0ab2ab0a6b943c677705dc48694a6c160626d3a315e88933acde8b664736f6c634300080e0033

Deployed Bytecode

0x60806040526004361061023b5760003560e01c806363107da41161012e578063a7bb5803116100ab578063e985e9c51161006f578063e985e9c5146106a1578063f1432f9d146106ea578063f2fde38b1461070a578063f7b2ec0d1461072a578063fa5408011461074a57600080fd5b8063a7bb5803146105ee578063b187bd261461062c578063b88d4fde14610641578063c87b56dd14610661578063cb19d5b51461068157600080fd5b80638da5cb5b116100f25780638da5cb5b146105665780638f2fc60b1461058457806395d89b41146105a45780639b4f1ecb146105b9578063a22cb465146105ce57600080fd5b806363107da4146104e95780636352211e146104fe57806370a082311461051e578063715018a61461053e5780637cd989c01461055357600080fd5b806324600fc3116101bc57806341f434341161018057806341f434341461045257806342842e0e146104745780634ce98417146104945780634d92ff28146104b4578063564566a8146104d457600080fd5b806324600fc31461039e5780632a55205a146103b35780633631cd3f146103f25780633be4c4771461041257806340af91ec1461043257600080fd5b806318160ddd1161020357806318160ddd14610311578063183b695e146103345780631a4b3c1214610354578063239c70ae1461036957806323b872dd1461037e57600080fd5b806301ffc9a71461024057806306fdde0314610275578063081812fc14610297578063088a4ed0146102cf578063095ea7b3146102f1575b600080fd5b34801561024c57600080fd5b5061026061025b366004612181565b6107b8565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b5061028a6107d8565b60405161026c91906121f6565b3480156102a357600080fd5b506102b76102b2366004612209565b61086a565b6040516001600160a01b03909116815260200161026c565b3480156102db57600080fd5b506102ef6102ea366004612209565b610891565b005b3480156102fd57600080fd5b506102ef61030c36600461223e565b6108f6565b34801561031d57600080fd5b5061032661090f565b60405190815260200161026c565b34801561034057600080fd5b5061032661034f36600461230b565b61091f565b34801561036057600080fd5b5061028a61094a565b34801561037557600080fd5b50600d54610326565b34801561038a57600080fd5b506102ef610399366004612340565b610959565b3480156103aa57600080fd5b506102ef610984565b3480156103bf57600080fd5b506103d36103ce36600461237c565b610a8c565b604080516001600160a01b03909316835260208301919091520161026c565b3480156103fe57600080fd5b506102ef61040d3660046123ab565b610b38565b34801561041e57600080fd5b5061032661042d3660046123c8565b610b92565b34801561043e57600080fd5b506102ef61044d3660046123ab565b610bf1565b34801561045e57600080fd5b506102b76daaeb6d7670e522a718067333cd4e81565b34801561048057600080fd5b506102ef61048f366004612340565b610c4b565b3480156104a057600080fd5b506103266104af366004612416565b610c70565b3480156104c057600080fd5b506103266104cf36600461230b565b610ca3565b3480156104e057600080fd5b50610260610ccb565b3480156104f557600080fd5b50610260610ced565b34801561050a57600080fd5b506102b7610519366004612209565b610d08565b34801561052a57600080fd5b5061032661053936600461247a565b610d6d565b34801561054a57600080fd5b506102ef610df3565b6102ef610561366004612495565b610e07565b34801561057257600080fd5b506007546001600160a01b03166102b7565b34801561059057600080fd5b506102ef61059f366004612527565b61102d565b3480156105b057600080fd5b5061028a611086565b3480156105c557600080fd5b50600c54610326565b3480156105da57600080fd5b506102ef6105e9366004612578565b611095565b3480156105fa57600080fd5b5061060e61060936600461230b565b6110a9565b60408051938452602084019290925260ff169082015260600161026c565b34801561063857600080fd5b506102606110ee565b34801561064d57600080fd5b506102ef61065c3660046125a4565b6110f6565b34801561066d57600080fd5b5061028a61067c366004612209565b611123565b34801561068d57600080fd5b506102ef61069c36600461230b565b61112e565b3480156106ad57600080fd5b506102606106bc366004612600565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156106f657600080fd5b506102ef610705366004612209565b611179565b34801561071657600080fd5b506102ef61072536600461247a565b6111d7565b34801561073657600080fd5b506102b761074536600461262a565b611250565b34801561075657600080fd5b50610326610765366004612209565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b60006107c3826112cf565b806107d257506107d28261131f565b92915050565b6060600080546107e790612667565b80601f016020809104026020016040519081016040528092919081815260200182805461081390612667565b80156108605780601f1061083557610100808354040283529160200191610860565b820191906000526020600020905b81548152906001019060200180831161084357829003601f168201915b5050505050905090565b600061087582611344565b506000908152600460205260409020546001600160a01b031690565b6108996113a3565b806000036108ba576040516327c3ca8f60e01b815260040160405180910390fd5b600d8190556040518181527fb76de10430cfde1d7dd54e1e915f8f57ec2a4ae0e29ebb4ff6a8694aeb2f9bfb906020015b60405180910390a150565b81610900816113fd565b61090a83836114b6565b505050565b600061091a600b5490565b905090565b600060108260405161093191906126a1565b9081526020016040518091039020600101549050919050565b6060600e80546107e790612667565b826001600160a01b038116331461097357610973336113fd565b61097e8484846115c6565b50505050565b61098c6113a3565b476000036109ad576040516371bec8b360e01b815260040160405180910390fd5b4760006109c26007546001600160a01b031690565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610a0c576040519150601f19603f3d011682016040523d82523d6000602084013e610a11565b606091505b5050905080610a33576040516322f4ec0f60e11b815260040160405180910390fd5b7f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5610a666007546001600160a01b031690565b604080516001600160a01b03909216825260208201859052015b60405180910390a15050565b60008281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610b015750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610b20906001600160601b0316876126d3565b610b2a9190612708565b915196919550909350505050565b610b406113a3565b600f805482919060ff191660018381811115610b5e57610b5e61271c565b02179055507fd64e77d0e3733743cb4a55b7d0ed4735b2fcc1d9ed4d52afc74f19ef3575016b816040516108eb9190612750565b600080610b9e8461091f565b905080158015610bc457506001600160a01b038316600090815260116020526040902054155b15610bd35760009150506107d2565b600c54610bdf85610ca3565b610be99190612763565b949350505050565b610bf96113a3565b600a805482919060ff191660018381811115610c1757610c1761271c565b02179055507fd90ea9ea059fcc79787986dd24a3e6da93c5f73c09e2669ac4ea7bbfec0a6cdb816040516108eb9190612750565b826001600160a01b0381163314610c6557610c65336113fd565b61097e8484846115f7565b60008282604051602001610c8592919061277b565b60405160208183030381529060405280519060200120905092915050565b6000601082604051610cb591906126a1565b9081526040519081900360200190205492915050565b600060015b600a5460ff166001811115610ce757610ce761271c565b14905090565b60006001600f5460ff166001811115610ce757610ce761271c565b6000818152600260205260408120546001600160a01b0316806107d25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064015b60405180910390fd5b60006001600160a01b038216610dd75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610d64565b506001600160a01b031660009081526003602052604090205490565b610dfb6113a3565b610e056000611612565b565b83610e10610ccb565b610e2d57604051636be5929360e01b815260040160405180910390fd5b6000610e388261091f565b90506000610e468333610b92565b9050610e51600d5490565b811115610e7157604051636c5a84a760e11b815260040160405180910390fd5b80341015610e9257604051633d61be4960e11b815260040160405180910390fd5b8484336000610ea18484611250565b9050816001600160a01b0316816001600160a01b031614610ed5576040516351a01e6f60e11b815260040160405180910390fd5b6000610ee0600b5490565b9050610ef0600b80546001019055565b610efa3382611664565b610f04818c611682565b610f0e8c33610b92565b60108d604051610f1e91906126a1565b90815260405190819003602001812091909155601090610f3f908e906126a1565b9081526040519081900360200190206001018054906000610f5f836127aa565b919050555060108c604051610f7491906126a1565b908152604080516020928190038301902060020180546001810182556000918252838220018054336001600160a01b03199091168117909155815260119092528120805491610fc2836127aa565b9190505550808c604051610fd691906126a1565b6040518091039020336001600160a01b03167f20015b06791b1d5d4cd9dcc64f5b2c746e6fbc352a1e2cd26e70a97518f2fbcd8e60405161101791906121f6565b60405180910390a4505050505050505050505050565b6110356113a3565b61103f828261171c565b604080516001600160a01b03841681526001600160601b03831660208201527faf1c0be9124aef2948fc934d6013ed3f705d2869bc4955cb4f655b0bc2952f659101610a80565b6060600180546107e790612667565b8161109f816113fd565b61090a8383611819565b600080600083516041146110d05760405163ef050af560e01b815260040160405180910390fd5b50505060208101516040820151606090920151909260009190911a90565b600080610cd0565b836001600160a01b038116331461111057611110336113fd565b61111c85858585611824565b5050505050565b60606107d282611856565b6111366113a3565b805161114990600e9060208401906120d2565b507f8443181362f5511dca63ecf006a0d7fa9421f538cb685ab89745d1e23824400d816040516108eb91906121f6565b6111816113a3565b806000036111a2576040516327c3ca8f60e01b815260040160405180910390fd5b600c8190556040518181527f507cd20c9be029443f99076cb7b67f1fe31d40192ac4308445e2b9004618a2ab906020016108eb565b6111df6113a3565b6001600160a01b0381166112445760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d64565b61124d81611612565b50565b60008060008061125f856110a9565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa1580156112ba573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006001600160e01b031982166380ac58cd60e01b148061130057506001600160e01b03198216635b5e139f60e01b145b806107d257506301ffc9a760e01b6001600160e01b03198316146107d2565b60006001600160e01b0319821663152a902d60e11b14806107d257506107d2826112cf565b6000818152600260205260409020546001600160a01b031661124d5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d64565b6007546001600160a01b03163314610e055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d64565b6daaeb6d7670e522a718067333cd4e3b1561124d57604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa15801561146a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148e91906127c3565b61124d57604051633b79c77360e21b81526001600160a01b0382166004820152602401610d64565b60006114c182610d08565b9050806001600160a01b0316836001600160a01b03160361152e5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610d64565b336001600160a01b038216148061154a575061154a81336106bc565b6115bc5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610d64565b61090a838361195e565b6115d033826119cc565b6115ec5760405162461bcd60e51b8152600401610d64906127e0565b61090a838383611a4a565b61090a838383604051806020016040528060008152506110f6565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61167e828260405180602001604052806000815250611be6565b5050565b6000828152600260205260409020546001600160a01b03166116fd5760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610d64565b6000828152600660209081526040909120825161090a928401906120d2565b6127106001600160601b038216111561178a5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610d64565b6001600160a01b0382166117e05760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610d64565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b61167e338383611c19565b61182e33836119cc565b61184a5760405162461bcd60e51b8152600401610d64906127e0565b61097e84848484611ce7565b606061186182611344565b6000828152600660205260408120805461187a90612667565b80601f01602080910402602001604051908101604052809291908181526020018280546118a690612667565b80156118f35780601f106118c8576101008083540402835291602001916118f3565b820191906000526020600020905b8154815290600101906020018083116118d657829003601f168201915b50505050509050600061191160408051602081019091526000815290565b90508051600003611923575092915050565b81511561195557808260405160200161193d92919061277b565b60405160208183030381529060405292505050919050565b610be984611d1a565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061199382610d08565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806119d883610d08565b9050806001600160a01b0316846001600160a01b03161480611a1f57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80610be95750836001600160a01b0316611a388461086a565b6001600160a01b031614949350505050565b826001600160a01b0316611a5d82610d08565b6001600160a01b031614611ac15760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610d64565b6001600160a01b038216611b235760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d64565b611b2e60008261195e565b6001600160a01b0383166000908152600360205260408120805460019290611b5790849061282e565b90915550506001600160a01b0382166000908152600360205260408120805460019290611b85908490612763565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b611bf08383611d8e565b611bfd6000848484611ed0565b61090a5760405162461bcd60e51b8152600401610d6490612845565b816001600160a01b0316836001600160a01b031603611c7a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d64565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611cf2848484611a4a565b611cfe84848484611ed0565b61097e5760405162461bcd60e51b8152600401610d6490612845565b6060611d2582611344565b6000611d3c60408051602081019091526000815290565b90506000815111611d5c5760405180602001604052806000815250611d87565b80611d6684611fd1565b604051602001611d7792919061277b565b6040516020818303038152906040525b9392505050565b6001600160a01b038216611de45760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d64565b6000818152600260205260409020546001600160a01b031615611e495760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d64565b6001600160a01b0382166000908152600360205260408120805460019290611e72908490612763565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b15611fc657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611f14903390899088908890600401612897565b6020604051808303816000875af1925050508015611f4f575060408051601f3d908101601f19168201909252611f4c918101906128d4565b60015b611fac573d808015611f7d576040519150601f19603f3d011682016040523d82523d6000602084013e611f82565b606091505b508051600003611fa45760405162461bcd60e51b8152600401610d6490612845565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610be9565b506001949350505050565b606081600003611ff85750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612022578061200c816127aa565b915061201b9050600a83612708565b9150611ffc565b60008167ffffffffffffffff81111561203d5761203d612268565b6040519080825280601f01601f191660200182016040528015612067576020820181803683370190505b5090505b8415610be95761207c60018361282e565b9150612089600a866128f1565b612094906030612763565b60f81b8183815181106120a9576120a9612905565b60200101906001600160f81b031916908160001a9053506120cb600a86612708565b945061206b565b8280546120de90612667565b90600052602060002090601f0160209004810192826121005760008555612146565b82601f1061211957805160ff1916838001178555612146565b82800160010185558215612146579182015b8281111561214657825182559160200191906001019061212b565b50612152929150612156565b5090565b5b808211156121525760008155600101612157565b6001600160e01b03198116811461124d57600080fd5b60006020828403121561219357600080fd5b8135611d878161216b565b60005b838110156121b95781810151838201526020016121a1565b8381111561097e5750506000910152565b600081518084526121e281602086016020860161219e565b601f01601f19169290920160200192915050565b602081526000611d8760208301846121ca565b60006020828403121561221b57600080fd5b5035919050565b80356001600160a01b038116811461223957600080fd5b919050565b6000806040838503121561225157600080fd5b61225a83612222565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261228f57600080fd5b813567ffffffffffffffff808211156122aa576122aa612268565b604051601f8301601f19908116603f011681019082821181831017156122d2576122d2612268565b816040528381528660208588010111156122eb57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561231d57600080fd5b813567ffffffffffffffff81111561233457600080fd5b610be98482850161227e565b60008060006060848603121561235557600080fd5b61235e84612222565b925061236c60208501612222565b9150604084013590509250925092565b6000806040838503121561238f57600080fd5b50508035926020909101359150565b6002811061124d57600080fd5b6000602082840312156123bd57600080fd5b8135611d878161239e565b600080604083850312156123db57600080fd5b823567ffffffffffffffff8111156123f257600080fd5b6123fe8582860161227e565b92505061240d60208401612222565b90509250929050565b6000806040838503121561242957600080fd5b823567ffffffffffffffff8082111561244157600080fd5b61244d8683870161227e565b9350602085013591508082111561246357600080fd5b506124708582860161227e565b9150509250929050565b60006020828403121561248c57600080fd5b611d8782612222565b600080600080608085870312156124ab57600080fd5b843567ffffffffffffffff808211156124c357600080fd5b6124cf8883890161227e565b955060208701359150808211156124e557600080fd5b6124f18883890161227e565b945060408701359350606087013591508082111561250e57600080fd5b5061251b8782880161227e565b91505092959194509250565b6000806040838503121561253a57600080fd5b61254383612222565b915060208301356001600160601b038116811461255f57600080fd5b809150509250929050565b801515811461124d57600080fd5b6000806040838503121561258b57600080fd5b61259483612222565b9150602083013561255f8161256a565b600080600080608085870312156125ba57600080fd5b6125c385612222565b93506125d160208601612222565b925060408501359150606085013567ffffffffffffffff8111156125f457600080fd5b61251b8782880161227e565b6000806040838503121561261357600080fd5b61261c83612222565b915061240d60208401612222565b6000806040838503121561263d57600080fd5b82359150602083013567ffffffffffffffff81111561265b57600080fd5b6124708582860161227e565b600181811c9082168061267b57607f821691505b60208210810361269b57634e487b7160e01b600052602260045260246000fd5b50919050565b600082516126b381846020870161219e565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156126ed576126ed6126bd565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612717576127176126f2565b500490565b634e487b7160e01b600052602160045260246000fd5b6002811061124d57634e487b7160e01b600052602160045260246000fd5b6020810161275d83612732565b91905290565b60008219821115612776576127766126bd565b500190565b6000835161278d81846020880161219e565b8351908301906127a181836020880161219e565b01949350505050565b6000600182016127bc576127bc6126bd565b5060010190565b6000602082840312156127d557600080fd5b8151611d878161256a565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b600082821015612840576128406126bd565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906128ca908301846121ca565b9695505050505050565b6000602082840312156128e657600080fd5b8151611d878161216b565b600082612900576129006126f2565b500690565b634e487b7160e01b600052603260045260246000fdfea264697066735822122016c2e5fdb0ab2ab0a6b943c677705dc48694a6c160626d3a315e88933acde8b664736f6c634300080e0033

Deployed Bytecode Sourcemap

60336:10464:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67342:255;;;;;;;;;;-1:-1:-1;67342:255:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;67342:255:0;;;;;;;;45024:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46600:187::-;;;;;;;;;;-1:-1:-1;46600:187:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;46600:187:0;1528:203:1;66864:234:0;;;;;;;;;;-1:-1:-1;66864:234:0;;;;;:::i;:::-;;:::i;:::-;;68184:182;;;;;;;;;;-1:-1:-1;68184:182:0;;;;;:::i;:::-;;:::i;65997:104::-;;;;;;;;;;;;;:::i;:::-;;;2319:25:1;;;2307:2;2292:18;65997:104:0;2173:177:1;65839:150:0;;;;;;;;;;-1:-1:-1;65839:150:0;;;;;:::i;:::-;;:::i;66109:85::-;;;;;;;;;;;;;:::i;65161:96::-;;;;;;;;;;-1:-1:-1;65234:15:0;;65161:96;;68374:197;;;;;;;;;;-1:-1:-1;68374:197:0;;;;;:::i;:::-;;:::i;70457:340::-;;;;;;;;;;;;;:::i;6129:480::-;;;;;;;;;;-1:-1:-1;6129:480:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4316:32:1;;;4298:51;;4380:2;4365:18;;4358:34;;;;4271:18;6129:480:0;4124:274:1;66515:149:0;;;;;;;;;;-1:-1:-1;66515:149:0;;;;;:::i;:::-;;:::i;65395:298::-;;;;;;;;;;-1:-1:-1;65395:298:0;;;;;:::i;:::-;;:::i;66368:139::-;;;;;;;;;;-1:-1:-1;66368:139:0;;;;;:::i;:::-;;:::i;16967:143::-;;;;;;;;;;;;8918:42;16967:143;;68579:205;;;;;;;;;;-1:-1:-1;68579:205:0;;;;;:::i;:::-;;:::i;63521:194::-;;;;;;;;;;-1:-1:-1;63521:194:0;;;;;:::i;:::-;;:::i;65701:130::-;;;;;;;;;;-1:-1:-1;65701:130:0;;;;;:::i;:::-;;:::i;64952:108::-;;;;;;;;;;;;;:::i;65265:122::-;;;;;;;;;;;;;:::i;44719:238::-;;;;;;;;;;-1:-1:-1;44719:238:0;;;;;:::i;:::-;;:::i;44397:260::-;;;;;;;;;;-1:-1:-1;44397:260:0;;;;;:::i;:::-;;:::i;23356:103::-;;;;;;;;;;;;;:::i;69550:734::-;;;;;;:::i;:::-;;:::i;22708:87::-;;;;;;;;;;-1:-1:-1;22781:6:0;;-1:-1:-1;;;;;22781:6:0;22708:87;;67605:236;;;;;;;;;;-1:-1:-1;67605:236:0;;;;;:::i;:::-;;:::i;45193:104::-;;;;;;;;;;;;;:::i;65068:85::-;;;;;;;;;;-1:-1:-1;65139:6:0;;65068:85;;67975:201;;;;;;;;;;-1:-1:-1;67975:201:0;;;;;:::i;:::-;;:::i;64319:347::-;;;;;;;;;;-1:-1:-1;64319:347:0;;;;;:::i;:::-;;:::i;:::-;;;;8790:25:1;;;8846:2;8831:18;;8824:34;;;;8906:4;8894:17;8874:18;;;8867:45;8778:2;8763:18;64319:347:0;8592:326:1;64840:104:0;;;;;;;;;;;;;:::i;68792:239::-;;;;;;;;;;-1:-1:-1;68792:239:0;;;;;:::i;:::-;;:::i;69204:171::-;;;;;;;;;;-1:-1:-1;69204:171:0;;;;;:::i;:::-;;:::i;67849:118::-;;;;;;;;;;-1:-1:-1;67849:118:0;;;;;:::i;:::-;;:::i;47110:189::-;;;;;;;;;;-1:-1:-1;47110:189:0;;;;;:::i;:::-;-1:-1:-1;;;;;47256:25:0;;;47232:4;47256:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;47110:189;66672:184;;;;;;;;;;-1:-1:-1;66672:184:0;;;;;:::i;:::-;;:::i;23614:238::-;;;;;;;;;;-1:-1:-1;23614:238:0;;;;;:::i;:::-;;:::i;64041:270::-;;;;;;;;;;-1:-1:-1;64041:270:0;;;;;:::i;:::-;;:::i;63723:310::-;;;;;;;;;;-1:-1:-1;63723:310:0;;;;;:::i;:::-;63883:127;;15467:66:1;63883:127:0;;;15455:79:1;15550:12;;;15543:28;;;63815:7:0;;15587:12:1;;63883:127:0;;;;;;;;;;;;63855:170;;;;;;63835:190;;63723:310;;;;67342:255;67460:4;67497:37;67522:11;67497:24;:37::i;:::-;:92;;;;67551:38;67577:11;67551:25;:38::i;:::-;67477:112;67342:255;-1:-1:-1;;67342:255:0:o;45024:100::-;45078:13;45111:5;45104:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45024:100;:::o;46600:187::-;46692:7;46712:23;46727:7;46712:14;:23::i;:::-;-1:-1:-1;46755:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;46755:24:0;;46600:187::o;66864:234::-;22594:13;:11;:13::i;:::-;66948:14:::1;66966:1;66948:19:::0;66944:55:::1;;66976:23;;-1:-1:-1::0;;;66976:23:0::1;;;;;;;;;;;66944:55;67010:15;:32:::0;;;67058::::1;::::0;2319:25:1;;;67058:32:0::1;::::0;2307:2:1;2292:18;67058:32:0::1;;;;;;;;66864:234:::0;:::o;68184:182::-;68305:8;18883:30;18904:8;18883:20;:30::i;:::-;68326:32:::1;68340:8;68350:7;68326:13;:32::i;:::-;68184:182:::0;;;:::o;65997:104::-;66041:7;66068:25;:15;1064:14;;972:114;66068:25;66061:32;;65997:104;:::o;65839:150::-;65923:7;65950:10;65961:5;65950:17;;;;;;:::i;:::-;;;;;;;;;;;;;:31;;;65943:38;;65839:150;;;:::o;66109:85::-;66148:13;66181:5;66174:12;;;;;:::i;68374:197::-;68509:4;-1:-1:-1;;;;;18609:18:0;;18617:10;18609:18;18605:83;;18644:32;18665:10;18644:20;:32::i;:::-;68526:37:::1;68545:4;68551:2;68555:7;68526:18;:37::i;:::-;68374:197:::0;;;;:::o;70457:340::-;22594:13;:11;:13::i;:::-;70516:21:::1;70541:1;70516:26:::0;70512:63:::1;;70551:24;;-1:-1:-1::0;;;70551:24:0::1;;;;;;;;;;;70512:63;70604:21;70586:15;70655:7;22781:6:::0;;-1:-1:-1;;;;;22781:6:0;;22708:87;70655:7:::1;-1:-1:-1::0;;;;;70655:12:0::1;70675:7;70655:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70636:51;;;70703:7;70698:48;;70719:27;;-1:-1:-1::0;;;70719:27:0::1;;;;;;;;;;;70698:48;70762:27;70772:7;22781:6:::0;;-1:-1:-1;;;;;22781:6:0;;22708:87;70772:7:::1;70762:27;::::0;;-1:-1:-1;;;;;4316:32:1;;;4298:51;;4380:2;4365:18;;4358:34;;;4271:18;70762:27:0::1;;;;;;;;70501:296;;70457:340::o:0;6129:480::-;6251:7;6309:27;;;:17;:27;;;;;;;;6280:56;;;;;;;;;-1:-1:-1;;;;;6280:56:0;;;;;-1:-1:-1;;;6280:56:0;;;-1:-1:-1;;;;;6280:56:0;;;;;;;;6251:7;;6349:92;;-1:-1:-1;6400:29:0;;;;;;;;;6410:19;6400:29;-1:-1:-1;;;;;6400:29:0;;;;-1:-1:-1;;;6400:29:0;;-1:-1:-1;;;;;6400:29:0;;;;;6349:92;6491:23;;;;6453:21;;6975:5;;6478:36;;-1:-1:-1;;;;;6478:36:0;:10;:36;:::i;:::-;6477:71;;;;:::i;:::-;6569:16;;;;;-1:-1:-1;6129:480:0;;-1:-1:-1;;;;6129:480:0:o;66515:149::-;22594:13;:11;:13::i;:::-;66592:14:::1;:24:::0;;66609:7;;66592:14;-1:-1:-1;;66592:24:0::1;::::0;66609:7;66592:24;;::::1;;;;;;:::i;:::-;;;;;;66632;66648:7;66632:24;;;;;;:::i;65395:298::-:0;65493:7;65513:20;65536:23;65553:5;65536:16;:23::i;:::-;65513:46;-1:-1:-1;65574:17:0;;:53;;;;-1:-1:-1;;;;;;65595:27:0;;;;;;:18;:27;;;;;;:32;65574:53;65570:67;;;65636:1;65629:8;;;;;65570:67;65679:6;;65655:21;65670:5;65655:14;:21::i;:::-;:30;;;;:::i;:::-;65648:37;65395:298;-1:-1:-1;;;;65395:298:0:o;66368:139::-;22594:13;:11;:13::i;:::-;66441:10:::1;:20:::0;;66454:7;;66441:10;-1:-1:-1;;66441:20:0::1;::::0;66454:7;66441:20;;::::1;;;;;;:::i;:::-;;;;;;66477:22;66491:7;66477:22;;;;;;:::i;68579:205::-:0;68718:4;-1:-1:-1;;;;;18609:18:0;;18617:10;18609:18;18605:83;;18644:32;18665:10;18644:20;:32::i;:::-;68735:41:::1;68758:4;68764:2;68768:7;68735:22;:41::i;63521:194::-:0;63636:7;63690;63699:6;63673:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;63663:44;;;;;;63656:51;;63521:194;;;;:::o;65701:130::-;65767:7;65794:10;65805:5;65794:17;;;;;;:::i;:::-;;;;;;;;;;;;;;:29;;65701:130;-1:-1:-1;;65701:130:0:o;64952:108::-;64997:4;65035:17;65021:31;:10;;;;;:31;;;;;;;:::i;:::-;;65014:38;;64952:108;:::o;65265:122::-;65318:4;65360:19;65342:14;;;;;:37;;;;;;;:::i;44719:238::-;44807:7;44843:16;;;:7;:16;;;;;;-1:-1:-1;;;;;44843:16:0;;44870:56;;;;-1:-1:-1;;;44870:56:0;;13403:2:1;44870:56:0;;;13385:21:1;13442:2;13422:18;;;13415:30;-1:-1:-1;;;13461:18:1;;;13454:54;13525:18;;44870:56:0;;;;;;;;44397:260;44485:7;-1:-1:-1;;;;;44527:19:0;;44505:110;;;;-1:-1:-1;;;44505:110:0;;13756:2:1;44505:110:0;;;13738:21:1;13795:2;13775:18;;;13768:30;13834:34;13814:18;;;13807:62;-1:-1:-1;;;13885:18:1;;;13878:39;13934:19;;44505:110:0;13554:405:1;44505:110:0;-1:-1:-1;;;;;;44633:16:0;;;;;:9;:16;;;;;;;44397:260::o;23356:103::-;22594:13;:11;:13::i;:::-;23421:30:::1;23448:1;23421:18;:30::i;:::-;23356:103::o:0;69550:734::-;69762:5;62714:14;:12;:14::i;:::-;62709:52;;62737:24;;-1:-1:-1;;;62737:24:0;;;;;;;;;;;62709:52;62772:19;62794:23;62811:5;62794:16;:23::i;:::-;62772:45;;62828:18;62849:23;62854:5;62861:10;62849:4;:23::i;:::-;62828:44;;62900:15;65234;;;65161:96;62900:15;62887:10;:28;62883:71;;;62924:30;;-1:-1:-1;;;62924:30:0;;;;;;;;;;;62883:71;62981:10;62969:9;:22;62965:63;;;63000:28;;-1:-1:-1;;;63000:28:0;;;;;;;;;;;62965:63;69787:21:::1;69810:10;69822;63192:14;63209:44;63219:21;63242:10;63209:9;:44::i;:::-;63192:61;;63278:7;-1:-1:-1::0;;;;;63268:17:0::1;:6;-1:-1:-1::0;;;;;63268:17:0::1;;63264:57;;63294:27;;-1:-1:-1::0;;;63294:27:0::1;;;;;;;;;;;63264:57;69850:15:::2;69868:25;:15;1064:14:::0;;972:114;69868:25:::2;69850:43;;69904:27;:15;1183:19:::0;;1201:1;1183:19;;;1094:127;69904:27:::2;69942:30;69952:10;69964:7;69942:9;:30::i;:::-;69983:26;69996:7;70005:3;69983:12;:26::i;:::-;70052:23;70057:5;70064:10;70052:4;:23::i;:::-;70020:10;70031:5;70020:17;;;;;;:::i;:::-;::::0;;;::::2;::::0;;;;;::::2;::::0;;;:55;;;;70086:10:::2;::::0;:17:::2;::::0;70097:5;;70086:17:::2;:::i;:::-;::::0;;;::::2;::::0;;;;;::::2;::::0;;;:31:::2;;:33:::0;;;:31:::2;:33;::::0;::::2;:::i;:::-;;;;;;70130:10;70141:5;70130:17;;;;;;:::i;:::-;::::0;;;::::2;::::0;;::::2;::::0;;;;;;;;:31:::2;;:48:::0;;::::2;::::0;::::2;::::0;;-1:-1:-1;70130:48:0;;;;;;::::2;::::0;;70167:10:::2;-1:-1:-1::0;;;;;;70130:48:0;;::::2;::::0;::::2;::::0;;;70189:30;;:18:::2;:30:::0;;;;;:32;;;::::2;::::0;::::2;:::i;:::-;;;;;;70268:7;70256:5;70237:39;;;;;;:::i;:::-;;;;;;;;70244:10;-1:-1:-1::0;;;;;70237:39:0::2;;70263:3;70237:39;;;;;;:::i;:::-;;;;;;;;69839:445;63181:160:::1;63039:1;;;62698:350:::0;;69550:734;;;;;:::o;67605:236::-;22594:13;:11;:13::i;:::-;67725:48:::1;67744:9;67755:17;67725:18;:48::i;:::-;67789:44;::::0;;-1:-1:-1;;;;;14295:32:1;;14277:51;;-1:-1:-1;;;;;14364:39:1;;14359:2;14344:18;;14337:67;67789:44:0::1;::::0;14250:18:1;67789:44:0::1;14104:306:1::0;45193:104:0;45249:13;45282:7;45275:14;;;;;:::i;67975:201::-;68104:8;18883:30;18904:8;18883:20;:30::i;:::-;68125:43:::1;68149:8;68159;68125:23;:43::i;64319:347::-:0;64398:9;64409;64420:7;64444:3;:10;64458:2;64444:16;64440:62;;64469:33;;-1:-1:-1;;;64469:33:0;;;;;;;;;;;64440:62;-1:-1:-1;;;64559:2:0;64550:12;;64544:19;64597:2;64588:12;;64582:19;64643:2;64634:12;;;64628:19;64544;;64625:1;64620:28;;;;;64319:347::o;64840:104::-;64881:4;;64905:31;;68792:239;68959:4;-1:-1:-1;;;;;18609:18:0;;18617:10;18609:18;18605:83;;18644:32;18665:10;18644:20;:32::i;:::-;68976:47:::1;68999:4;69005:2;69009:7;69018:4;68976:22;:47::i;:::-;68792:239:::0;;;;;:::o;69204:171::-;69311:13;69344:23;69359:7;69344:14;:23::i;67849:118::-;22594:13;:11;:13::i;:::-;67915:12;;::::1;::::0;:5:::1;::::0;:12:::1;::::0;::::1;::::0;::::1;:::i;:::-;;67943:16;67954:4;67943:16;;;;;;:::i;66672:184::-:0;22594:13;:11;:13::i;:::-;66745:5:::1;66754:1;66745:10:::0;66741:46:::1;;66764:23;;-1:-1:-1::0;;;66764:23:0::1;;;;;;;;;;;66741:46;66798:6;:14:::0;;;66828:20:::1;::::0;2319:25:1;;;66828:20:0::1;::::0;2307:2:1;2292:18;66828:20:0::1;2173:177:1::0;23614:238:0;22594:13;:11;:13::i;:::-;-1:-1:-1;;;;;23717:22:0;::::1;23695:110;;;::::0;-1:-1:-1;;;23695:110:0;;14617:2:1;23695:110:0::1;::::0;::::1;14599:21:1::0;14656:2;14636:18;;;14629:30;14695:34;14675:18;;;14668:62;-1:-1:-1;;;14746:18:1;;;14739:36;14792:19;;23695:110:0::1;14415:402:1::0;23695:110:0::1;23816:28;23835:8;23816:18;:28::i;:::-;23614:238:::0;:::o;64041:270::-;64162:7;64183:9;64194;64205:7;64216:26;64231:10;64216:14;:26::i;:::-;64262:41;;;;;;;;;;;;15049:25:1;;;15122:4;15110:17;;15090:18;;;15083:45;;;;15144:18;;;15137:34;;;15187:18;;;15180:34;;;64182:60:0;;-1:-1:-1;64182:60:0;;-1:-1:-1;64182:60:0;-1:-1:-1;64262:41:0;;15021:19:1;;64262:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;64262:41:0;;-1:-1:-1;;64262:41:0;;;64041:270;-1:-1:-1;;;;;;;64041:270:0:o;44012:321::-;44130:4;-1:-1:-1;;;;;;44167:40:0;;-1:-1:-1;;;44167:40:0;;:105;;-1:-1:-1;;;;;;;44224:48:0;;-1:-1:-1;;;44224:48:0;44167:105;:158;;;-1:-1:-1;;;;;;;;;;4376:40:0;;;44289:36;4251:173;5817:257;5935:4;-1:-1:-1;;;;;;5972:41:0;;-1:-1:-1;;;5972:41:0;;:94;;;6030:36;6054:11;6030:23;:36::i;54840:135::-;50035:4;50059:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50059:16:0;54914:53;;;;-1:-1:-1;;;54914:53:0;;13403:2:1;54914:53:0;;;13385:21:1;13442:2;13422:18;;;13415:30;-1:-1:-1;;;13461:18:1;;;13454:54;13525:18;;54914:53:0;13201:348:1;22873:132:0;22781:6;;-1:-1:-1;;;;;22781:6:0;21312:10;22937:23;22929:68;;;;-1:-1:-1;;;22929:68:0;;15812:2:1;22929:68:0;;;15794:21:1;;;15831:18;;;15824:30;15890:34;15870:18;;;15863:62;15942:18;;22929:68:0;15610:356:1;19026:740:0;8918:42;19217:45;:49;19213:546;;19534:128;;-1:-1:-1;;;19534:128:0;;19607:4;19534:128;;;16183:34:1;-1:-1:-1;;;;;16253:15:1;;16233:18;;;16226:43;8918:42:0;;19534;;16118:18:1;;19534:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19511:237;;19704:28;;-1:-1:-1;;;19704:28:0;;-1:-1:-1;;;;;1692:32:1;;19704:28:0;;;1674:51:1;1647:18;;19704:28:0;1528:203:1;46117:417:0;46198:13;46214:23;46229:7;46214:14;:23::i;:::-;46198:39;;46262:5;-1:-1:-1;;;;;46256:11:0;:2;-1:-1:-1;;;;;46256:11:0;;46248:57;;;;-1:-1:-1;;;46248:57:0;;16732:2:1;46248:57:0;;;16714:21:1;16771:2;16751:18;;;16744:30;16810:34;16790:18;;;16783:62;-1:-1:-1;;;16861:18:1;;;16854:31;16902:19;;46248:57:0;16530:397:1;46248:57:0;21312:10;-1:-1:-1;;;;;46340:21:0;;;;:62;;-1:-1:-1;46365:37:0;46382:5;21312:10;47110:189;:::i;46365:37::-;46318:174;;;;-1:-1:-1;;;46318:174:0;;17134:2:1;46318:174:0;;;17116:21:1;17173:2;17153:18;;;17146:30;17212:34;17192:18;;;17185:62;17283:32;17263:18;;;17256:60;17333:19;;46318:174:0;16932:426:1;46318:174:0;46505:21;46514:2;46518:7;46505:8;:21::i;47366:373::-;47575:41;21312:10;47608:7;47575:18;:41::i;:::-;47553:137;;;;-1:-1:-1;;;47553:137:0;;;;;;;:::i;:::-;47703:28;47713:4;47719:2;47723:7;47703:9;:28::i;47810:185::-;47948:39;47965:4;47971:2;47975:7;47948:39;;;;;;;;;;;;:16;:39::i;24012:191::-;24105:6;;;-1:-1:-1;;;;;24122:17:0;;;-1:-1:-1;;;;;;24122:17:0;;;;;;;24155:40;;24105:6;;;24122:17;24105:6;;24155:40;;24086:16;;24155:40;24075:128;24012:191;:::o;50921:110::-;50997:26;51007:2;51011:7;50997:26;;;;;;;;;;;;:9;:26::i;:::-;50921:110;;:::o;59112:279::-;50035:4;50059:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50059:16:0;59229:112;;;;-1:-1:-1;;;59229:112:0;;17980:2:1;59229:112:0;;;17962:21:1;18019:2;17999:18;;;17992:30;18058:34;18038:18;;;18031:62;-1:-1:-1;;;18109:18:1;;;18102:44;18163:19;;59229:112:0;17778:410:1;59229:112:0;59352:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;7259:394::-;6975:5;-1:-1:-1;;;;;7401:33:0;;;;7379:125;;;;-1:-1:-1;;;7379:125:0;;18395:2:1;7379:125:0;;;18377:21:1;18434:2;18414:18;;;18407:30;18473:34;18453:18;;;18446:62;-1:-1:-1;;;18524:18:1;;;18517:40;18574:19;;7379:125:0;18193:406:1;7379:125:0;-1:-1:-1;;;;;7523:22:0;;7515:60;;;;-1:-1:-1;;;7515:60:0;;18806:2:1;7515:60:0;;;18788:21:1;18845:2;18825:18;;;18818:30;18884:27;18864:18;;;18857:55;18929:18;;7515:60:0;18604:349:1;7515:60:0;7610:35;;;;;;;;;-1:-1:-1;;;;;7610:35:0;;;;;;-1:-1:-1;;;;;7610:35:0;;;;;;;;;;-1:-1:-1;;;7588:57:0;;;;:19;:57;7259:394::o;46859:180::-;46979:52;21312:10;47012:8;47022;46979:18;:52::i;48066:360::-;48254:41;21312:10;48287:7;48254:18;:41::i;:::-;48232:137;;;;-1:-1:-1;;;48232:137:0;;;;;;;:::i;:::-;48380:38;48394:4;48400:2;48404:7;48413:4;48380:13;:38::i;58316:640::-;58405:13;58431:23;58446:7;58431:14;:23::i;:::-;58467;58493:19;;;:10;:19;;;;;58467:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58523:18;58544:10;46038:9;;;;;;;;;-1:-1:-1;46038:9:0;;;45961:94;58544:10;58523:31;;58636:4;58630:18;58652:1;58630:23;58626:72;;-1:-1:-1;58677:9:0;58316:640;-1:-1:-1;;58316:640:0:o;58626:72::-;58802:23;;:27;58798:108;;58877:4;58883:9;58860:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;58846:48;;;;58316:640;;;:::o;58798:108::-;58925:23;58940:7;58925:14;:23::i;54119:174::-;54194:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;54194:29:0;-1:-1:-1;;;;;54194:29:0;;;;;;;;:24;;54248:23;54194:24;54248:14;:23::i;:::-;-1:-1:-1;;;;;54239:46:0;;;;;;;;;;;54119:174;;:::o;50264:315::-;50382:4;50399:13;50415:23;50430:7;50415:14;:23::i;:::-;50399:39;;50468:5;-1:-1:-1;;;;;50457:16:0;:7;-1:-1:-1;;;;;50457:16:0;;:65;;;-1:-1:-1;;;;;;47256:25:0;;;47232:4;47256:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;50490:32;50457:113;;;;50563:7;-1:-1:-1;;;;;50539:31:0;:20;50551:7;50539:11;:20::i;:::-;-1:-1:-1;;;;;50539:31:0;;;50264:315;-1:-1:-1;;;;50264:315:0:o;53338:662::-;53511:4;-1:-1:-1;;;;;53484:31:0;:23;53499:7;53484:14;:23::i;:::-;-1:-1:-1;;;;;53484:31:0;;53462:118;;;;-1:-1:-1;;;53462:118:0;;19160:2:1;53462:118:0;;;19142:21:1;19199:2;19179:18;;;19172:30;19238:34;19218:18;;;19211:62;-1:-1:-1;;;19289:18:1;;;19282:35;19334:19;;53462:118:0;18958:401:1;53462:118:0;-1:-1:-1;;;;;53599:16:0;;53591:65;;;;-1:-1:-1;;;53591:65:0;;19566:2:1;53591:65:0;;;19548:21:1;19605:2;19585:18;;;19578:30;19644:34;19624:18;;;19617:62;-1:-1:-1;;;19695:18:1;;;19688:34;19739:19;;53591:65:0;19364:400:1;53591:65:0;53773:29;53790:1;53794:7;53773:8;:29::i;:::-;-1:-1:-1;;;;;53815:15:0;;;;;;:9;:15;;;;;:20;;53834:1;;53815:15;:20;;53834:1;;53815:20;:::i;:::-;;;;-1:-1:-1;;;;;;;53846:13:0;;;;;;:9;:13;;;;;:18;;53863:1;;53846:13;:18;;53863:1;;53846:18;:::i;:::-;;;;-1:-1:-1;;53875:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;53875:21:0;-1:-1:-1;;;;;53875:21:0;;;;;;;;;53914:27;;53875:16;;53914:27;;;;;;;68184:182;;;:::o;51258:319::-;51387:18;51393:2;51397:7;51387:5;:18::i;:::-;51438:53;51469:1;51473:2;51477:7;51486:4;51438:22;:53::i;:::-;51416:153;;;;-1:-1:-1;;;51416:153:0;;;;;;;:::i;54436:315::-;54591:8;-1:-1:-1;;;;;54582:17:0;:5;-1:-1:-1;;;;;54582:17:0;;54574:55;;;;-1:-1:-1;;;54574:55:0;;20520:2:1;54574:55:0;;;20502:21:1;20559:2;20539:18;;;20532:30;20598:27;20578:18;;;20571:55;20643:18;;54574:55:0;20318:349:1;54574:55:0;-1:-1:-1;;;;;54640:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;54640:46:0;;;;;;;;;;54702:41;;540::1;;;54702::0;;513:18:1;54702:41:0;;;;;;;54436:315;;;:::o;49307:350::-;49463:28;49473:4;49479:2;49483:7;49463:9;:28::i;:::-;49524:47;49547:4;49553:2;49557:7;49566:4;49524:22;:47::i;:::-;49502:147;;;;-1:-1:-1;;;49502:147:0;;;;;;;:::i;45368:344::-;45457:13;45483:23;45498:7;45483:14;:23::i;:::-;45519:21;45543:10;46038:9;;;;;;;;;-1:-1:-1;46038:9:0;;;45961:94;45543:10;45519:34;;45608:1;45590:7;45584:21;:25;:120;;;;;;;;;;;;;;;;;45653:7;45662:18;:7;:16;:18::i;:::-;45636:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;45584:120;45564:140;45368:344;-1:-1:-1;;;45368:344:0:o;51913:439::-;-1:-1:-1;;;;;51993:16:0;;51985:61;;;;-1:-1:-1;;;51985:61:0;;20874:2:1;51985:61:0;;;20856:21:1;;;20893:18;;;20886:30;20952:34;20932:18;;;20925:62;21004:18;;51985:61:0;20672:356:1;51985:61:0;50035:4;50059:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50059:16:0;:30;52057:58;;;;-1:-1:-1;;;52057:58:0;;21235:2:1;52057:58:0;;;21217:21:1;21274:2;21254:18;;;21247:30;21313;21293:18;;;21286:58;21361:18;;52057:58:0;21033:352:1;52057:58:0;-1:-1:-1;;;;;52186:13:0;;;;;;:9;:13;;;;;:18;;52203:1;;52186:13;:18;;52203:1;;52186:18;:::i;:::-;;;;-1:-1:-1;;52215:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;52215:21:0;-1:-1:-1;;;;;52215:21:0;;;;;;;;52254:33;;52215:16;;;52254:33;;52215:16;;52254:33;50921:110;;:::o;55539:1034::-;55693:4;-1:-1:-1;;;;;55714:13:0;;25742:19;:23;55710:856;;55767:174;;-1:-1:-1;;;55767:174:0;;-1:-1:-1;;;;;55767:36:0;;;;;:174;;21312:10;;55861:4;;55888:7;;55918:4;;55767:174;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55767:174:0;;;;;;;;-1:-1:-1;;55767:174:0;;;;;;;;;;;;:::i;:::-;;;55746:765;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56124:6;:13;56141:1;56124:18;56120:376;;56167:108;;-1:-1:-1;;;56167:108:0;;;;;;;:::i;56120:376::-;56446:6;56440:13;56431:6;56427:2;56423:15;56416:38;55746:765;-1:-1:-1;;;;;;56005:51:0;-1:-1:-1;;;56005:51:0;;-1:-1:-1;55998:58:0;;55710:856;-1:-1:-1;56550:4:0;55539:1034;;;;;;:::o;33665:723::-;33721:13;33942:5;33951:1;33942:10;33938:53;;-1:-1:-1;;33969:10:0;;;;;;;;;;;;-1:-1:-1;;;33969:10:0;;;;;33665:723::o;33938:53::-;34016:5;34001:12;34057:78;34064:9;;34057:78;;34090:8;;;;:::i;:::-;;-1:-1:-1;34113:10:0;;-1:-1:-1;34121:2:0;34113:10;;:::i;:::-;;;34057:78;;;34145:19;34177:6;34167:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34167:17:0;;34145:39;;34195:154;34202:10;;34195:154;;34229:11;34239:1;34229:11;;:::i;:::-;;-1:-1:-1;34298:10:0;34306:2;34298:5;:10;:::i;:::-;34285:24;;:2;:24;:::i;:::-;34272:39;;34255:6;34262;34255:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;34255:56:0;;;;;;;;-1:-1:-1;34326:11:0;34335:2;34326:11;;:::i;:::-;;;34195:154;;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2355:127::-;2416:10;2411:3;2407:20;2404:1;2397:31;2447:4;2444:1;2437:15;2471:4;2468:1;2461:15;2487:719;2530:5;2583:3;2576:4;2568:6;2564:17;2560:27;2550:55;;2601:1;2598;2591:12;2550:55;2637:6;2624:20;2663:18;2700:2;2696;2693:10;2690:36;;;2706:18;;:::i;:::-;2781:2;2775:9;2749:2;2835:13;;-1:-1:-1;;2831:22:1;;;2855:2;2827:31;2823:40;2811:53;;;2879:18;;;2899:22;;;2876:46;2873:72;;;2925:18;;:::i;:::-;2965:10;2961:2;2954:22;3000:2;2992:6;2985:18;3046:3;3039:4;3034:2;3026:6;3022:15;3018:26;3015:35;3012:55;;;3063:1;3060;3053:12;3012:55;3127:2;3120:4;3112:6;3108:17;3101:4;3093:6;3089:17;3076:54;3174:1;3167:4;3162:2;3154:6;3150:15;3146:26;3139:37;3194:6;3185:15;;;;;;2487:719;;;;:::o;3211:322::-;3280:6;3333:2;3321:9;3312:7;3308:23;3304:32;3301:52;;;3349:1;3346;3339:12;3301:52;3389:9;3376:23;3422:18;3414:6;3411:30;3408:50;;;3454:1;3451;3444:12;3408:50;3477;3519:7;3510:6;3499:9;3495:22;3477:50;:::i;3538:328::-;3615:6;3623;3631;3684:2;3672:9;3663:7;3659:23;3655:32;3652:52;;;3700:1;3697;3690:12;3652:52;3723:29;3742:9;3723:29;:::i;:::-;3713:39;;3771:38;3805:2;3794:9;3790:18;3771:38;:::i;:::-;3761:48;;3856:2;3845:9;3841:18;3828:32;3818:42;;3538:328;;;;;:::o;3871:248::-;3939:6;3947;4000:2;3988:9;3979:7;3975:23;3971:32;3968:52;;;4016:1;4013;4006:12;3968:52;-1:-1:-1;;4039:23:1;;;4109:2;4094:18;;;4081:32;;-1:-1:-1;3871:248:1:o;4403:111::-;4488:1;4481:5;4478:12;4468:40;;4504:1;4501;4494:12;4519:274;4595:6;4648:2;4636:9;4627:7;4623:23;4619:32;4616:52;;;4664:1;4661;4654:12;4616:52;4703:9;4690:23;4722:41;4757:5;4722:41;:::i;4798:396::-;4876:6;4884;4937:2;4925:9;4916:7;4912:23;4908:32;4905:52;;;4953:1;4950;4943:12;4905:52;4993:9;4980:23;5026:18;5018:6;5015:30;5012:50;;;5058:1;5055;5048:12;5012:50;5081;5123:7;5114:6;5103:9;5099:22;5081:50;:::i;:::-;5071:60;;;5150:38;5184:2;5173:9;5169:18;5150:38;:::i;:::-;5140:48;;4798:396;;;;;:::o;5715:543::-;5803:6;5811;5864:2;5852:9;5843:7;5839:23;5835:32;5832:52;;;5880:1;5877;5870:12;5832:52;5920:9;5907:23;5949:18;5990:2;5982:6;5979:14;5976:34;;;6006:1;6003;5996:12;5976:34;6029:50;6071:7;6062:6;6051:9;6047:22;6029:50;:::i;:::-;6019:60;;6132:2;6121:9;6117:18;6104:32;6088:48;;6161:2;6151:8;6148:16;6145:36;;;6177:1;6174;6167:12;6145:36;;6200:52;6244:7;6233:8;6222:9;6218:24;6200:52;:::i;:::-;6190:62;;;5715:543;;;;;:::o;6445:186::-;6504:6;6557:2;6545:9;6536:7;6532:23;6528:32;6525:52;;;6573:1;6570;6563:12;6525:52;6596:29;6615:9;6596:29;:::i;6636:811::-;6751:6;6759;6767;6775;6828:3;6816:9;6807:7;6803:23;6799:33;6796:53;;;6845:1;6842;6835:12;6796:53;6885:9;6872:23;6914:18;6955:2;6947:6;6944:14;6941:34;;;6971:1;6968;6961:12;6941:34;6994:50;7036:7;7027:6;7016:9;7012:22;6994:50;:::i;:::-;6984:60;;7097:2;7086:9;7082:18;7069:32;7053:48;;7126:2;7116:8;7113:16;7110:36;;;7142:1;7139;7132:12;7110:36;7165:52;7209:7;7198:8;7187:9;7183:24;7165:52;:::i;:::-;7155:62;;7264:2;7253:9;7249:18;7236:32;7226:42;;7321:2;7310:9;7306:18;7293:32;7277:48;;7350:2;7340:8;7337:16;7334:36;;;7366:1;7363;7356:12;7334:36;;7389:52;7433:7;7422:8;7411:9;7407:24;7389:52;:::i;:::-;7379:62;;;6636:811;;;;;;;:::o;7452:366::-;7519:6;7527;7580:2;7568:9;7559:7;7555:23;7551:32;7548:52;;;7596:1;7593;7586:12;7548:52;7619:29;7638:9;7619:29;:::i;:::-;7609:39;;7698:2;7687:9;7683:18;7670:32;-1:-1:-1;;;;;7735:5:1;7731:38;7724:5;7721:49;7711:77;;7784:1;7781;7774:12;7711:77;7807:5;7797:15;;;7452:366;;;;;:::o;7823:118::-;7909:5;7902:13;7895:21;7888:5;7885:32;7875:60;;7931:1;7928;7921:12;7946:315;8011:6;8019;8072:2;8060:9;8051:7;8047:23;8043:32;8040:52;;;8088:1;8085;8078:12;8040:52;8111:29;8130:9;8111:29;:::i;:::-;8101:39;;8190:2;8179:9;8175:18;8162:32;8203:28;8225:5;8203:28;:::i;8923:538::-;9018:6;9026;9034;9042;9095:3;9083:9;9074:7;9070:23;9066:33;9063:53;;;9112:1;9109;9102:12;9063:53;9135:29;9154:9;9135:29;:::i;:::-;9125:39;;9183:38;9217:2;9206:9;9202:18;9183:38;:::i;:::-;9173:48;;9268:2;9257:9;9253:18;9240:32;9230:42;;9323:2;9312:9;9308:18;9295:32;9350:18;9342:6;9339:30;9336:50;;;9382:1;9379;9372:12;9336:50;9405;9447:7;9438:6;9427:9;9423:22;9405:50;:::i;9466:260::-;9534:6;9542;9595:2;9583:9;9574:7;9570:23;9566:32;9563:52;;;9611:1;9608;9601:12;9563:52;9634:29;9653:9;9634:29;:::i;:::-;9624:39;;9682:38;9716:2;9705:9;9701:18;9682:38;:::i;9731:389::-;9808:6;9816;9869:2;9857:9;9848:7;9844:23;9840:32;9837:52;;;9885:1;9882;9875:12;9837:52;9921:9;9908:23;9898:33;;9982:2;9971:9;9967:18;9954:32;10009:18;10001:6;9998:30;9995:50;;;10041:1;10038;10031:12;9995:50;10064;10106:7;10097:6;10086:9;10082:22;10064:50;:::i;10310:380::-;10389:1;10385:12;;;;10432;;;10453:61;;10507:4;10499:6;10495:17;10485:27;;10453:61;10560:2;10552:6;10549:14;10529:18;10526:38;10523:161;;10606:10;10601:3;10597:20;10594:1;10587:31;10641:4;10638:1;10631:15;10669:4;10666:1;10659:15;10523:161;;10310:380;;;:::o;10695:276::-;10826:3;10864:6;10858:13;10880:53;10926:6;10921:3;10914:4;10906:6;10902:17;10880:53;:::i;:::-;10949:16;;;;;10695:276;-1:-1:-1;;10695:276:1:o;11186:127::-;11247:10;11242:3;11238:20;11235:1;11228:31;11278:4;11275:1;11268:15;11302:4;11299:1;11292:15;11318:168;11358:7;11424:1;11420;11416:6;11412:14;11409:1;11406:21;11401:1;11394:9;11387:17;11383:45;11380:71;;;11431:18;;:::i;:::-;-1:-1:-1;11471:9:1;;11318:168::o;11491:127::-;11552:10;11547:3;11543:20;11540:1;11533:31;11583:4;11580:1;11573:15;11607:4;11604:1;11597:15;11623:120;11663:1;11689;11679:35;;11694:18;;:::i;:::-;-1:-1:-1;11728:9:1;;11623:120::o;11748:127::-;11809:10;11804:3;11800:20;11797:1;11790:31;11840:4;11837:1;11830:15;11864:4;11861:1;11854:15;11880:214;11965:1;11958:5;11955:12;11945:143;;12010:10;12005:3;12001:20;11998:1;11991:31;12045:4;12042:1;12035:15;12073:4;12070:1;12063:15;12099:243;12248:2;12233:18;;12260:42;12295:6;12260:42;:::i;:::-;12311:25;;;12099:243;:::o;12347:128::-;12387:3;12418:1;12414:6;12411:1;12408:13;12405:39;;;12424:18;;:::i;:::-;-1:-1:-1;12460:9:1;;12347:128::o;12726:470::-;12905:3;12943:6;12937:13;12959:53;13005:6;13000:3;12993:4;12985:6;12981:17;12959:53;:::i;:::-;13075:13;;13034:16;;;;13097:57;13075:13;13034:16;13131:4;13119:17;;13097:57;:::i;:::-;13170:20;;12726:470;-1:-1:-1;;;;12726:470:1:o;13964:135::-;14003:3;14024:17;;;14021:43;;14044:18;;:::i;:::-;-1:-1:-1;14091:1:1;14080:13;;13964:135::o;16280:245::-;16347:6;16400:2;16388:9;16379:7;16375:23;16371:32;16368:52;;;16416:1;16413;16406:12;16368:52;16448:9;16442:16;16467:28;16489:5;16467:28;:::i;17363:410::-;17565:2;17547:21;;;17604:2;17584:18;;;17577:30;17643:34;17638:2;17623:18;;17616:62;-1:-1:-1;;;17709:2:1;17694:18;;17687:44;17763:3;17748:19;;17363:410::o;19769:125::-;19809:4;19837:1;19834;19831:8;19828:34;;;19842:18;;:::i;:::-;-1:-1:-1;19879:9:1;;19769:125::o;19899:414::-;20101:2;20083:21;;;20140:2;20120:18;;;20113:30;20179:34;20174:2;20159:18;;20152:62;-1:-1:-1;;;20245:2:1;20230:18;;20223:48;20303:3;20288:19;;19899:414::o;21390:489::-;-1:-1:-1;;;;;21659:15:1;;;21641:34;;21711:15;;21706:2;21691:18;;21684:43;21758:2;21743:18;;21736:34;;;21806:3;21801:2;21786:18;;21779:31;;;21584:4;;21827:46;;21853:19;;21845:6;21827:46;:::i;:::-;21819:54;21390:489;-1:-1:-1;;;;;;21390:489:1:o;21884:249::-;21953:6;22006:2;21994:9;21985:7;21981:23;21977:32;21974:52;;;22022:1;22019;22012:12;21974:52;22054:9;22048:16;22073:30;22097:5;22073:30;:::i;22138:112::-;22170:1;22196;22186:35;;22201:18;;:::i;:::-;-1:-1:-1;22235:9:1;;22138:112::o;22255:127::-;22316:10;22311:3;22307:20;22304:1;22297:31;22347:4;22344:1;22337:15;22371:4;22368:1;22361:15

Swarm Source

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