ETH Price: $2,575.24 (+0.80%)

Mental College (MentalCollege)
 

Overview

TokenID

3416

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
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:
MentalCollege

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 15 : MentalCollege.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./SignatureChecker.sol";
import "operator-filter-registry/src/DefaultOperatorFilterer.sol";

contract MentalCollege is ERC721, ReentrancyGuard ,DefaultOperatorFilterer{
    address private _owner;

    address private _permitOwner;

    address private _recipient;

    bytes32 public immutable DOMAIN_SEPARATOR;

    mapping(address => mapping(bytes4 => uint128)) private _mintedNumber;

    //Mint Role => Allowed Mint Amount => Discount Factor
    mapping(bytes4 => uint256) private _mintInfo;

    uint256 public totalSupply;

    uint256 private _price;

    uint256 private _startIndex;

    uint256 private _timeSet;

    string private _baseTokenURI;

    bytes4 public constant PRIVILEGEROLENAME = 0x64730000;

    uint256 public constant COLLECTIONSIZE = 6000;

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

    constructor(
        address permitOwner_,
        string memory name_,
        string memory symbol_
    ) ERC721(name_, symbol_) {
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,
                0x4726992d1c50f778516dd5a087ee7ccb94b41129cf51e555af6bb742a3ca7a4a,
                0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6,
                block.chainid,
                address(this)
            )
        );
        _owner = msg.sender;
        _permitOwner = permitOwner_;
    }

    modifier onlyOwner() {
        require(_owner == msg.sender, "Caller is not the owner");
        _;
    }

    modifier isMintOn() {
        require(
            isEarlyMint() || isPublicMint() || isDsMint(),
            "Mental: Mint Is Not On"
        );
        _;
    }

    function _baseURI() internal view virtual override returns (string memory) {
        if (bytes(_baseTokenURI).length > 0) return _baseTokenURI;
        else return "Waiting...";
    }

    function setBaseURI(string memory _uri) external onlyOwner {
        _baseTokenURI = _uri;
    }

    //Transfer Contract Ownership
    function transferOwnership(address newOwner) external onlyOwner {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }

    //Tranfer Signature Permit Ownership
    function transferPermitOwnership(address newPermitOwner)
        external
        onlyOwner
    {
        address oldPermitOwner = _permitOwner;
        _permitOwner = newPermitOwner;
        emit OwnershipTransferred(oldPermitOwner, newPermitOwner);
    }

    //Set Mint Role & Allowed Mint Count & Discount Factor
    function setMintRoleInfo(
        string[] memory roleNames,
        uint128[] memory allowedMintCounts,
        uint128[] memory discountFactors
    ) external onlyOwner {
        require(
            roleNames.length == allowedMintCounts.length &&
                allowedMintCounts.length == discountFactors.length,
            "Data Mismatch"
        );
        for (uint256 i = 0; i < roleNames.length; i++) {
            require(
                allowedMintCounts[i] > 0 && discountFactors[i] > 0,
                "Info Error"
            );
            _mintInfo[bytes4(bytes(roleNames[i]))] =
                uint256(allowedMintCounts[i]) |
                (uint256(discountFactors[i]) << 128);
        }
    }

    //Get Allowed Mint Number & Discount Factoe for Roles ["og","wh","ds"]
    function getRoleInfo(string calldata roleName)
        public
        view
        returns (uint128, uint128)
    {
        require(_mintInfo[bytes4(bytes(roleName))] > 0, "Limit Error");
        return (
            uint128(_mintInfo[bytes4(bytes(roleName))]),
            uint128(_mintInfo[bytes4(bytes(roleName))] >> 128)
        );
    }

    //Set Early Mint & Public Mint Time
    function setMintTime(
        uint48 dsMintStart,
        uint48 dsDuration,
        uint48 earlyMintStart,
        uint48 earlyDuration,
        uint32 publicMintStart,
        uint32 publicDuration
    ) external onlyOwner {
        require(
            dsMintStart > 0 &&
                earlyMintStart >= dsMintStart + dsDuration &&
                publicMintStart >= earlyMintStart + earlyDuration,
            "Mint Time Slots Not In Order"
        );
        _timeSet =
            uint256(dsMintStart) |
            (uint256(dsDuration) << 48) |
            (uint256(earlyMintStart) << 96) |
            (uint256(earlyDuration) << 144) |
            (uint256(publicMintStart) << 192) |
            (uint256(publicDuration) << 224);
    }

    //Get Mint Times & Price
    function getMintInfo()
        public
        view
        returns (SignatureInfo.InfoSet memory info)
    {
        info = SignatureInfo.InfoSet(
            uint48(_timeSet),
            uint48(_timeSet >> 48),
            uint48(_timeSet >> 96),
            uint48(_timeSet >> 144),
            uint32(_timeSet >> 192),
            uint32(_timeSet >> 224),
            _price
        );
    }

    //Set Public Mint Price & Recipient Of Funds
    function setMintPriceAndRecipient(uint256 price_, address recipient_)
        external
        onlyOwner
    {
        require(
            price_ > 0 && recipient_ != address(0x0),
            "Must be greater than 0"
        );
        _price = price_;
        _recipient = recipient_;
    }

    function isDsMint() internal view returns (bool) {
        SignatureInfo.InfoSet memory info = getMintInfo();
        return
            info.dsMintStart <= block.timestamp &&
            info.dsMintStart + info.dsDuration >= block.timestamp;
    }

    function isPublicMint() internal view returns (bool) {
        SignatureInfo.InfoSet memory info = getMintInfo();
        return
            info.publicMintStart <= block.timestamp &&
            info.publicMintStart + info.publicMintDuration >= block.timestamp;
    }

    function isEarlyMint() internal view returns (bool) {
        SignatureInfo.InfoSet memory info = getMintInfo();
        return
            info.earlyMintStart <= block.timestamp &&
            info.earlyMintStart + info.earlyMintDuration >= block.timestamp;
    }

    function validateContentSignature(SignatureInfo.Content calldata content)
        internal
        view
        returns (uint256)
    {
        require(
            SignatureChecker.verify(
                SignatureInfo.getContentHash(content),
                _permitOwner,
                content.v,
                content.r,
                content.s,
                DOMAIN_SEPARATOR
            ),
            "Authentication Fails"
        );

        if (isDsMint()) {
            require(
                bytes4(bytes(content.identity)) == PRIVILEGEROLENAME,
                "You Need DS Role For Privilege Mint"
            );
        }
        (uint128 amount, uint128 discountFactor) = getRoleInfo(
            content.identity
        );
        require(discountFactor > 0, "Discount Information Is Not Set");
        require(
            _mintedNumber[content.holder][bytes4(bytes(content.identity))] +
                content.amount <=
                amount,
            "Exceeds The Allowed Amount"
        );
        return (_price - (_price * discountFactor) / 100) * content.amount;
    }

    function getMintPrice(SignatureInfo.Content calldata content)
        public
        view
        returns (uint256)
    {
        if (isEarlyMint() || isDsMint())
            return validateContentSignature(content);
        else return content.amount * _price;
    }

    function batchMint(SignatureInfo.Content calldata content)
        external
        payable
        isMintOn
    {
        require(content.holder != address(0), "Zero Address");
        require(
            totalSupply + content.amount <= COLLECTIONSIZE,
            "Exceeds Collection Size"
        );
        uint256 mintCost = getMintPrice(content);
        require(msg.value >= mintCost && mintCost > 0, "Insufficient Fund");

        _safeTransferETH(_recipient, msg.value);
        for (uint256 i = 0; i < content.amount; i++) {
            _safeMint(content.holder, _startIndex);
            _startIndex++;
        }
        totalSupply += content.amount;
        if (isEarlyMint() || isDsMint())
            _mintedNumber[content.holder][
                bytes4(bytes(content.identity))
            ] += content.amount;
    }

    //Tranfer Fund To Wallet
    function _safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "ETH_TRANSFER_FAILED");
    }

    function devMint(uint256 amount) external onlyOwner {
        require(amount > 0, "Mental: Quantity Should Be Bigger Than Zero.");
        require(
            totalSupply + amount <= COLLECTIONSIZE,
            "Mental: It Will Exceed Max Supply."
        );
        require(
            _recipient != address(0x0),
            "Mental: The Recipient Address Is Not Set"
        );
        for (uint256 i = 0; i < amount; i++) {
            _safeMint(_recipient, _startIndex);
            _startIndex++;
        }
        totalSupply += amount;
    }

    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);
    }
}

File 2 of 15 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

File 3 of 15 : ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @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 4 of 15 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @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 5 of 15 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @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 6 of 15 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// 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 7 of 15 : Address.sol
// SPDX-License-Identifier: MIT
// 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 8 of 15 : Context.sol
// SPDX-License-Identifier: MIT
// 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 9 of 15 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @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 10 of 15 : IERC165.sol
// SPDX-License-Identifier: MIT
// 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 11 of 15 : Strings.sol
// SPDX-License-Identifier: MIT
// 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 12 of 15 : SignatureChecker.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library SignatureInfo {
    bytes32 constant CONTENT_HASH =
        0x58e2f0ec35eb789493367bbd774d478d0e7e6916118069574ff2690b38004245;

    struct Content {
        address holder;
        uint128 amount;
        string identity;
        uint8 v; // v: parameter (27 or 28)
        bytes32 r; // r: parameter
        bytes32 s;
    }

    function getContentHash(Content calldata content)
        internal
        pure
        returns (bytes32)
    {
        return
            keccak256(
                abi.encode(
                    CONTENT_HASH,
                    content.holder,
                    content.amount,
                    keccak256(bytes(content.identity))
                )
            );
    }

    struct InfoSet {
        uint48 dsMintStart;
        uint48 dsDuration;
        uint48 earlyMintStart;
        uint48 earlyMintDuration;
        uint32 publicMintStart;
        uint32 publicMintDuration;
        uint256 price;
    }
}

library SignatureChecker {
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        require(
            uint256(s) <=
                0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
            "Signature: Invalid s parameter"
        );

        require(v == 27 || v == 28, "Signature: Invalid v parameter");
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "Signature: Invalid signer");

        return signer;
    }

    function verify(
        bytes32 hash,
        address signer,
        uint8 v,
        bytes32 r,
        bytes32 s,
        bytes32 domainSeparator
    ) internal pure returns (bool) {
        bytes32 digest = keccak256(
            abi.encodePacked("\x19\x01", domainSeparator, hash)
        );
        return recover(digest, v, r, s) == signer;
    }
}

File 13 of 15 : DefaultOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {OperatorFilterer} from "./OperatorFilterer.sol";

/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

File 14 of 15 : IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

File 15 of 15 : OperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @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.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    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));
                }
            }
        }
    }

    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);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    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) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"permitOwner_","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"COLLECTIONSIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRIVILEGEROLENAME","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"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":[{"components":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"string","name":"identity","type":"string"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureInfo.Content","name":"content","type":"tuple"}],"name":"batchMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"devMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMintInfo","outputs":[{"components":[{"internalType":"uint48","name":"dsMintStart","type":"uint48"},{"internalType":"uint48","name":"dsDuration","type":"uint48"},{"internalType":"uint48","name":"earlyMintStart","type":"uint48"},{"internalType":"uint48","name":"earlyMintDuration","type":"uint48"},{"internalType":"uint32","name":"publicMintStart","type":"uint32"},{"internalType":"uint32","name":"publicMintDuration","type":"uint32"},{"internalType":"uint256","name":"price","type":"uint256"}],"internalType":"struct SignatureInfo.InfoSet","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"string","name":"identity","type":"string"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureInfo.Content","name":"content","type":"tuple"}],"name":"getMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"roleName","type":"string"}],"name":"getRoleInfo","outputs":[{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"},{"internalType":"address","name":"recipient_","type":"address"}],"name":"setMintPriceAndRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"roleNames","type":"string[]"},{"internalType":"uint128[]","name":"allowedMintCounts","type":"uint128[]"},{"internalType":"uint128[]","name":"discountFactors","type":"uint128[]"}],"name":"setMintRoleInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"dsMintStart","type":"uint48"},{"internalType":"uint48","name":"dsDuration","type":"uint48"},{"internalType":"uint48","name":"earlyMintStart","type":"uint48"},{"internalType":"uint48","name":"earlyDuration","type":"uint48"},{"internalType":"uint32","name":"publicMintStart","type":"uint32"},{"internalType":"uint32","name":"publicDuration","type":"uint32"}],"name":"setMintTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPermitOwner","type":"address"}],"name":"transferPermitOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b506040516200664238038062006642833981810160405281019062000037919062000658565b733cc6cdda760b79bafa08df41ecfa224f810dceb660018383816000908051906020019062000068929190620003a6565b50806001908051906020019062000081929190620003a6565b505050600160068190555060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200028157801562000147576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200010d92919062000703565b600060405180830381600087803b1580156200012857600080fd5b505af11580156200013d573d6000803e3d6000fd5b5050505062000280565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000201576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620001c792919062000703565b600060405180830381600087803b158015620001e257600080fd5b505af1158015620001f7573d6000803e3d6000fd5b505050506200027f565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b81526004016200024a919062000730565b600060405180830381600087803b1580156200026557600080fd5b505af11580156200027a573d6000803e3d6000fd5b505050505b5b5b50507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f4726992d1c50f778516dd5a087ee7ccb94b41129cf51e555af6bb742a3ca7a4a7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc64630604051602001620002fe9594939291906200083b565b604051602081830303815290604052805190602001206080818152505033600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050620008fc565b828054620003b490620008c7565b90600052602060002090601f016020900481019282620003d8576000855562000424565b82601f10620003f357805160ff191683800117855562000424565b8280016001018555821562000424579182015b828111156200042357825182559160200191906001019062000406565b5b50905062000433919062000437565b5090565b5b808211156200045257600081600090555060010162000438565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000497826200046a565b9050919050565b620004a9816200048a565b8114620004b557600080fd5b50565b600081519050620004c9816200049e565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200052482620004d9565b810181811067ffffffffffffffff82111715620005465762000545620004ea565b5b80604052505050565b60006200055b62000456565b905062000569828262000519565b919050565b600067ffffffffffffffff8211156200058c576200058b620004ea565b5b6200059782620004d9565b9050602081019050919050565b60005b83811015620005c4578082015181840152602081019050620005a7565b83811115620005d4576000848401525b50505050565b6000620005f1620005eb846200056e565b6200054f565b90508281526020810184848401111562000610576200060f620004d4565b5b6200061d848285620005a4565b509392505050565b600082601f8301126200063d576200063c620004cf565b5b81516200064f848260208601620005da565b91505092915050565b60008060006060848603121562000674576200067362000460565b5b60006200068486828701620004b8565b935050602084015167ffffffffffffffff811115620006a857620006a762000465565b5b620006b68682870162000625565b925050604084015167ffffffffffffffff811115620006da57620006d962000465565b5b620006e88682870162000625565b9150509250925092565b620006fd816200048a565b82525050565b60006040820190506200071a6000830185620006f2565b620007296020830184620006f2565b9392505050565b6000602082019050620007476000830184620006f2565b92915050565b6000819050919050565b6000819050919050565b6000819050919050565b60006200078c6200078662000780846200074d565b62000761565b62000757565b9050919050565b6200079e816200076b565b82525050565b6000819050919050565b6000620007cf620007c9620007c384620007a4565b62000761565b62000757565b9050919050565b620007e181620007ae565b82525050565b6000819050919050565b6000620008126200080c6200080684620007e7565b62000761565b62000757565b9050919050565b6200082481620007f1565b82525050565b620008358162000757565b82525050565b600060a08201905062000852600083018862000793565b620008616020830187620007d6565b62000870604083018662000819565b6200087f60608301856200082a565b6200088e6080830184620006f2565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620008e057607f821691505b602082108103620008f657620008f562000898565b5b50919050565b608051615d236200091f60003960008181610a9001526126b30152615d236000f3fe6080604052600436106101c25760003560e01c80636352211e116100f7578063b88d4fde11610095578063e985e9c511610064578063e985e9c514610644578063ea0f434314610681578063ef6eff45146106aa578063f2fde38b146106e7576101c2565b8063b88d4fde14610597578063baac5a11146105c0578063c87b56dd146105dc578063d0520c2314610619576101c2565b806395d89b41116100d157806395d89b41146104ed5780639eaa656c14610518578063a22cb46514610543578063b3d5adf41461056c576101c2565b80636352211e1461044a57806370a082311461048757806380b15659146104c4576101c2565b80633644e5151161016457806341f434341161013e57806341f434341461038f57806342842e0e146103ba57806355f804b3146103e35780635d055fcd1461040c576101c2565b80633644e5151461031257806336f5511b1461033d578063375a069a14610366576101c2565b8063095ea7b3116101a0578063095ea7b31461026c57806309cae1531461029557806318160ddd146102be57806323b872dd146102e9576101c2565b806301ffc9a7146101c757806306fdde0314610204578063081812fc1461022f575b600080fd5b3480156101d357600080fd5b506101ee60048036038101906101e991906137f5565b610710565b6040516101fb919061383d565b60405180910390f35b34801561021057600080fd5b506102196107f2565b60405161022691906138f1565b60405180910390f35b34801561023b57600080fd5b5061025660048036038101906102519190613949565b610884565b60405161026391906139b7565b60405180910390f35b34801561027857600080fd5b50610293600480360381019061028e91906139fe565b6108ca565b005b3480156102a157600080fd5b506102bc60048036038101906102b79190613a3e565b6108e3565b005b3480156102ca57600080fd5b506102d3610a39565b6040516102e09190613a7a565b60405180910390f35b3480156102f557600080fd5b50610310600480360381019061030b9190613a95565b610a3f565b005b34801561031e57600080fd5b50610327610a8e565b6040516103349190613b01565b60405180910390f35b34801561034957600080fd5b50610364600480360381019061035f9190613e42565b610ab2565b005b34801561037257600080fd5b5061038d60048036038101906103889190613949565b610d36565b005b34801561039b57600080fd5b506103a4610f6d565b6040516103b19190613f48565b60405180910390f35b3480156103c657600080fd5b506103e160048036038101906103dc9190613a95565b610f7f565b005b3480156103ef57600080fd5b5061040a60048036038101906104059190613f63565b610fce565b005b34801561041857600080fd5b50610433600480360381019061042e9190614007565b611078565b604051610441929190614063565b60405180910390f35b34801561045657600080fd5b50610471600480360381019061046c9190613949565b6111e6565b60405161047e91906139b7565b60405180910390f35b34801561049357600080fd5b506104ae60048036038101906104a99190613a3e565b611297565b6040516104bb9190613a7a565b60405180910390f35b3480156104d057600080fd5b506104eb60048036038101906104e6919061408c565b61134e565b005b3480156104f957600080fd5b506105026114a6565b60405161050f91906138f1565b60405180910390f35b34801561052457600080fd5b5061052d611538565b60405161053a91906140db565b60405180910390f35b34801561054f57600080fd5b5061056a60048036038101906105659190614122565b611543565b005b34801561057857600080fd5b5061058161155c565b60405161058e9190613a7a565b60405180910390f35b3480156105a357600080fd5b506105be60048036038101906105b99190614203565b611562565b005b6105da60048036038101906105d591906142aa565b6115b3565b005b3480156105e857600080fd5b5061060360048036038101906105fe9190613949565b61199b565b60405161061091906138f1565b60405180910390f35b34801561062557600080fd5b5061062e611a03565b60405161063b91906143d0565b60405180910390f35b34801561065057600080fd5b5061066b600480360381019061066691906143eb565b611a91565b604051610678919061383d565b60405180910390f35b34801561068d57600080fd5b506106a860048036038101906106a39190614483565b611b25565b005b3480156106b657600080fd5b506106d160048036038101906106cc91906142aa565b611ca5565b6040516106de9190613a7a565b60405180910390f35b3480156106f357600080fd5b5061070e60048036038101906107099190613a3e565b611d0d565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107db57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107eb57506107ea82611e63565b5b9050919050565b6060600080546108019061453f565b80601f016020809104026020016040519081016040528092919081815260200182805461082d9061453f565b801561087a5780601f1061084f5761010080835404028352916020019161087a565b820191906000526020600020905b81548152906001019060200180831161085d57829003601f168201915b5050505050905090565b600061088f82611ecd565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b816108d481611f18565b6108de8383612015565b505050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610973576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096a906145bc565b60405180910390fd5b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600c5481565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a7d57610a7c33611f18565b5b610a8884848461212c565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b39906145bc565b60405180910390fd5b81518351148015610b54575080518251145b610b93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8a90614628565b60405180910390fd5b60005b8351811015610d30576000838281518110610bb457610bb3614648565b5b60200260200101516fffffffffffffffffffffffffffffffff16118015610c0757506000828281518110610beb57610bea614648565b5b60200260200101516fffffffffffffffffffffffffffffffff16115b610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d906146c3565b60405180910390fd5b6080828281518110610c5b57610c5a614648565b5b60200260200101516fffffffffffffffffffffffffffffffff16901b838281518110610c8a57610c89614648565b5b60200260200101516fffffffffffffffffffffffffffffffff1617600b6000868481518110610cbc57610cbb614648565b5b6020026020010151610ccd90614720565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055508080610d28906147b6565b915050610b96565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610dc6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbd906145bc565b60405180910390fd5b60008111610e09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0090614870565b60405180910390fd5b61177081600c54610e1a9190614890565b1115610e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5290614958565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610eec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee3906149ea565b60405180910390fd5b60005b81811015610f5057610f25600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600e5461218c565b600e6000815480929190610f38906147b6565b91905055508080610f48906147b6565b915050610eef565b5080600c6000828254610f639190614890565b9250508190555050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610fbd57610fbc33611f18565b5b610fc88484846121aa565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461105e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611055906145bc565b60405180910390fd5b806010908051906020019061107492919061367d565b5050565b6000806000600b600086869061108e9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020541161111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111290614ac0565b60405180910390fd5b600b600085859061112c9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546080600b600087879061118c9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054901c915091509250929050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361128e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128590614b2c565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611307576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fe90614bbe565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146113de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d5906145bc565b60405180910390fd5b60008211801561141b5750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61145a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145190614c2a565b60405180910390fd5b81600d8190555080600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6060600180546114b59061453f565b80601f01602080910402602001604051908101604052809291908181526020018280546114e19061453f565b801561152e5780601f106115035761010080835404028352916020019161152e565b820191906000526020600020905b81548152906001019060200180831161151157829003601f168201915b5050505050905090565b636473000060e01b81565b8161154d81611f18565b61155783836121ca565b505050565b61177081565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146115a05761159f33611f18565b5b6115ac858585856121e0565b5050505050565b6115bb612242565b806115ca57506115c961228c565b5b806115d957506115d86122d2565b5b611618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160f90614c96565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168160000160208101906116439190613a3e565b73ffffffffffffffffffffffffffffffffffffffff1603611699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169090614d02565b60405180910390fd5b6117708160200160208101906116af9190614d22565b6fffffffffffffffffffffffffffffffff16600c546116ce9190614890565b111561170f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170690614d9b565b60405180910390fd5b600061171a82611ca5565b905080341015801561172c5750600081115b61176b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176290614e07565b60405180910390fd5b611797600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff163461231c565b60005b8260200160208101906117ad9190614d22565b6fffffffffffffffffffffffffffffffff1681101561180f576117e48360000160208101906117dc9190613a3e565b600e5461218c565b600e60008154809291906117f7906147b6565b91905055508080611807906147b6565b91505061179a565b508160200160208101906118239190614d22565b6fffffffffffffffffffffffffffffffff16600c60008282546118469190614890565b92505081905550611855612242565b8061186457506118636122d2565b5b156119975781602001602081019061187c9190614d22565b600a60008460000160208101906118939190613a3e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008480604001906118df9190614e36565b906118ea9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060008282829054906101000a90046fffffffffffffffffffffffffffffffff166119609190614e99565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b5050565b60606119a682611ecd565b60006119b061241c565b905060008151116119d057604051806020016040528060008152506119fb565b806119da84612503565b6040516020016119eb929190614f1b565b6040516020818303038152906040525b915050919050565b611a0b613703565b6040518060e00160405280600f5465ffffffffffff1681526020016030600f54901c65ffffffffffff1681526020016060600f54901c65ffffffffffff1681526020016090600f54901c65ffffffffffff16815260200160c0600f54901c63ffffffff16815260200160e0600f54901c63ffffffff168152602001600d54815250905090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bac906145bc565b60405180910390fd5b60008665ffffffffffff16118015611be857508486611bd49190614f3f565b65ffffffffffff168465ffffffffffff1610155b8015611c0d57508284611bfb9190614f3f565b65ffffffffffff168263ffffffff1610155b611c4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4390614fc7565b60405180910390fd5b60e08163ffffffff16901b60c08363ffffffff16901b60908565ffffffffffff16901b60608765ffffffffffff16901b60308965ffffffffffff16901b8a65ffffffffffff161717171717600f81905550505050505050565b6000611caf612242565b80611cbe5750611cbd6122d2565b5b15611cd357611ccc82612663565b9050611d08565b600d54826020016020810190611ce99190614d22565b6fffffffffffffffffffffffffffffffff16611d059190614fe7565b90505b919050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611d9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d94906145bc565b60405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611ed681612a04565b611f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0c90614b2c565b60405180910390fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612012576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611f8f929190615041565b602060405180830381865afa158015611fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd0919061507f565b61201157806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161200891906139b7565b60405180910390fd5b5b50565b6000612020826111e6565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612090576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120879061511e565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166120af612a70565b73ffffffffffffffffffffffffffffffffffffffff1614806120de57506120dd816120d8612a70565b611a91565b5b61211d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612114906151b0565b60405180910390fd5b6121278383612a78565b505050565b61213d612137612a70565b82612b31565b61217c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217390615242565b60405180910390fd5b612187838383612bc6565b505050565b6121a6828260405180602001604052806000815250612e2c565b5050565b6121c583838360405180602001604052806000815250611562565b505050565b6121dc6121d5612a70565b8383612e87565b5050565b6121f16121eb612a70565b83612b31565b612230576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222790615242565b60405180910390fd5b61223c84848484612ff3565b50505050565b60008061224d611a03565b905042816040015165ffffffffffff16111580156122865750428160600151826040015161227b9190614f3f565b65ffffffffffff1610155b91505090565b600080612297611a03565b905042816080015163ffffffff16111580156122cc5750428160a0015182608001516122c39190615262565b63ffffffff1610155b91505090565b6000806122dd611a03565b905042816000015165ffffffffffff16111580156123165750428160200151826000015161230b9190614f3f565b65ffffffffffff1610155b91505090565b60008273ffffffffffffffffffffffffffffffffffffffff1682600067ffffffffffffffff81111561235157612350613b21565b5b6040519080825280601f01601f1916602001820160405280156123835781602001600182028036833780820191505090505b5060405161239191906152d8565b60006040518083038185875af1925050503d80600081146123ce576040519150601f19603f3d011682016040523d82523d6000602084013e6123d3565b606091505b5050905080612417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240e9061533b565b60405180910390fd5b505050565b606060006010805461242d9061453f565b905011156124c757601080546124429061453f565b80601f016020809104026020016040519081016040528092919081815260200182805461246e9061453f565b80156124bb5780601f10612490576101008083540402835291602001916124bb565b820191906000526020600020905b81548152906001019060200180831161249e57829003601f168201915b50505050509050612500565b6040518060400160405280600a81526020017f57616974696e672e2e2e0000000000000000000000000000000000000000000081525090505b90565b60606000820361254a576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061265e565b600082905060005b6000821461257c578080612565906147b6565b915050600a82612575919061538a565b9150612552565b60008167ffffffffffffffff81111561259857612597613b21565b5b6040519080825280601f01601f1916602001820160405280156125ca5781602001600182028036833780820191505090505b5090505b60008514612657576001826125e391906153bb565b9150600a856125f291906153ef565b60306125fe9190614890565b60f81b81838151811061261457612613614648565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612650919061538a565b94506125ce565b8093505050505b919050565b60006126d76126718361304f565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460600160208101906126a79190615459565b85608001358660a001357f00000000000000000000000000000000000000000000000000000000000000006130f1565b612716576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270d906154d2565b60405180910390fd5b61271e6122d2565b156127c557636473000060e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191682806040019061275a9190614e36565b906127659190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146127c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127bb90615564565b60405180910390fd5b5b6000806127e08480604001906127db9190614e36565b611078565b915091506000816fffffffffffffffffffffffffffffffff1611612839576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612830906155d0565b60405180910390fd5b816fffffffffffffffffffffffffffffffff1684602001602081019061285f9190614d22565b600a60008760000160208101906128769190613a3e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008780604001906128c29190614e36565b906128cd9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166129409190614e99565b6fffffffffffffffffffffffffffffffff161115612993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298a9061563c565b60405180910390fd5b8360200160208101906129a69190614d22565b6fffffffffffffffffffffffffffffffff166064826fffffffffffffffffffffffffffffffff16600d546129da9190614fe7565b6129e4919061538a565b600d546129f191906153bb565b6129fb9190614fe7565b92505050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612aeb836111e6565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080612b3d836111e6565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612b7f5750612b7e8185611a91565b5b80612bbd57508373ffffffffffffffffffffffffffffffffffffffff16612ba584610884565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612be6826111e6565b73ffffffffffffffffffffffffffffffffffffffff1614612c3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c33906156ce565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612cab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca290615760565b60405180910390fd5b612cb6838383613166565b612cc1600082612a78565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612d1191906153bb565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612d689190614890565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612e2783838361316b565b505050565b612e368383613170565b612e436000848484613349565b612e82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e79906157f2565b60405180910390fd5b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612ef5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eec9061585e565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612fe6919061383d565b60405180910390a3505050565b612ffe848484612bc6565b61300a84848484613349565b613049576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613040906157f2565b60405180910390fd5b50505050565b60007f58e2f0ec35eb789493367bbd774d478d0e7e6916118069574ff2690b3800424560001b8260000160208101906130889190613a3e565b83602001602081019061309b9190614d22565b8480604001906130ab9190614e36565b6040516130b99291906158a3565b60405180910390206040516020016130d494939291906158bc565b604051602081830303815290604052805190602001209050919050565b600080828860405160200161310792919061596e565b6040516020818303038152906040528051906020012090508673ffffffffffffffffffffffffffffffffffffffff16613142828888886134d0565b73ffffffffffffffffffffffffffffffffffffffff16149150509695505050505050565b505050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036131df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131d6906159f1565b60405180910390fd5b6131e881612a04565b15613228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321f90615a5d565b60405180910390fd5b61323460008383613166565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546132849190614890565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46133456000838361316b565b5050565b600061336a8473ffffffffffffffffffffffffffffffffffffffff1661365a565b156134c3578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613393612a70565b8786866040518563ffffffff1660e01b81526004016133b59493929190615ac7565b6020604051808303816000875af19250505080156133f157506040513d601f19601f820116820180604052508101906133ee9190615b28565b60015b613473573d8060008114613421576040519150601f19603f3d011682016040523d82523d6000602084013e613426565b606091505b50600081510361346b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613462906157f2565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506134c8565b600190505b949350505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c1115613538576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161352f90615ba1565b60405180910390fd5b601b8460ff16148061354d5750601c8460ff16145b61358c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161358390615c0d565b60405180910390fd5b6000600186868686604051600081526020016040526040516135b19493929190615c3c565b6020604051602081039080840390855afa1580156135d3573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361364e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161364590615ccd565b60405180910390fd5b80915050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b8280546136899061453f565b90600052602060002090601f0160209004810192826136ab57600085556136f2565b82601f106136c457805160ff19168380011785556136f2565b828001600101855582156136f2579182015b828111156136f15782518255916020019190600101906136d6565b5b5090506136ff919061376c565b5090565b6040518060e00160405280600065ffffffffffff168152602001600065ffffffffffff168152602001600065ffffffffffff168152602001600065ffffffffffff168152602001600063ffffffff168152602001600063ffffffff168152602001600081525090565b5b8082111561378557600081600090555060010161376d565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6137d28161379d565b81146137dd57600080fd5b50565b6000813590506137ef816137c9565b92915050565b60006020828403121561380b5761380a613793565b5b6000613819848285016137e0565b91505092915050565b60008115159050919050565b61383781613822565b82525050565b6000602082019050613852600083018461382e565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613892578082015181840152602081019050613877565b838111156138a1576000848401525b50505050565b6000601f19601f8301169050919050565b60006138c382613858565b6138cd8185613863565b93506138dd818560208601613874565b6138e6816138a7565b840191505092915050565b6000602082019050818103600083015261390b81846138b8565b905092915050565b6000819050919050565b61392681613913565b811461393157600080fd5b50565b6000813590506139438161391d565b92915050565b60006020828403121561395f5761395e613793565b5b600061396d84828501613934565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006139a182613976565b9050919050565b6139b181613996565b82525050565b60006020820190506139cc60008301846139a8565b92915050565b6139db81613996565b81146139e657600080fd5b50565b6000813590506139f8816139d2565b92915050565b60008060408385031215613a1557613a14613793565b5b6000613a23858286016139e9565b9250506020613a3485828601613934565b9150509250929050565b600060208284031215613a5457613a53613793565b5b6000613a62848285016139e9565b91505092915050565b613a7481613913565b82525050565b6000602082019050613a8f6000830184613a6b565b92915050565b600080600060608486031215613aae57613aad613793565b5b6000613abc868287016139e9565b9350506020613acd868287016139e9565b9250506040613ade86828701613934565b9150509250925092565b6000819050919050565b613afb81613ae8565b82525050565b6000602082019050613b166000830184613af2565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613b59826138a7565b810181811067ffffffffffffffff82111715613b7857613b77613b21565b5b80604052505050565b6000613b8b613789565b9050613b978282613b50565b919050565b600067ffffffffffffffff821115613bb757613bb6613b21565b5b602082029050602081019050919050565b600080fd5b600080fd5b600067ffffffffffffffff821115613bed57613bec613b21565b5b613bf6826138a7565b9050602081019050919050565b82818337600083830152505050565b6000613c25613c2084613bd2565b613b81565b905082815260208101848484011115613c4157613c40613bcd565b5b613c4c848285613c03565b509392505050565b600082601f830112613c6957613c68613b1c565b5b8135613c79848260208601613c12565b91505092915050565b6000613c95613c9084613b9c565b613b81565b90508083825260208201905060208402830185811115613cb857613cb7613bc8565b5b835b81811015613cff57803567ffffffffffffffff811115613cdd57613cdc613b1c565b5b808601613cea8982613c54565b85526020850194505050602081019050613cba565b5050509392505050565b600082601f830112613d1e57613d1d613b1c565b5b8135613d2e848260208601613c82565b91505092915050565b600067ffffffffffffffff821115613d5257613d51613b21565b5b602082029050602081019050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b613d8881613d63565b8114613d9357600080fd5b50565b600081359050613da581613d7f565b92915050565b6000613dbe613db984613d37565b613b81565b90508083825260208201905060208402830185811115613de157613de0613bc8565b5b835b81811015613e0a5780613df68882613d96565b845260208401935050602081019050613de3565b5050509392505050565b600082601f830112613e2957613e28613b1c565b5b8135613e39848260208601613dab565b91505092915050565b600080600060608486031215613e5b57613e5a613793565b5b600084013567ffffffffffffffff811115613e7957613e78613798565b5b613e8586828701613d09565b935050602084013567ffffffffffffffff811115613ea657613ea5613798565b5b613eb286828701613e14565b925050604084013567ffffffffffffffff811115613ed357613ed2613798565b5b613edf86828701613e14565b9150509250925092565b6000819050919050565b6000613f0e613f09613f0484613976565b613ee9565b613976565b9050919050565b6000613f2082613ef3565b9050919050565b6000613f3282613f15565b9050919050565b613f4281613f27565b82525050565b6000602082019050613f5d6000830184613f39565b92915050565b600060208284031215613f7957613f78613793565b5b600082013567ffffffffffffffff811115613f9757613f96613798565b5b613fa384828501613c54565b91505092915050565b600080fd5b60008083601f840112613fc757613fc6613b1c565b5b8235905067ffffffffffffffff811115613fe457613fe3613fac565b5b60208301915083600182028301111561400057613fff613bc8565b5b9250929050565b6000806020838503121561401e5761401d613793565b5b600083013567ffffffffffffffff81111561403c5761403b613798565b5b61404885828601613fb1565b92509250509250929050565b61405d81613d63565b82525050565b60006040820190506140786000830185614054565b6140856020830184614054565b9392505050565b600080604083850312156140a3576140a2613793565b5b60006140b185828601613934565b92505060206140c2858286016139e9565b9150509250929050565b6140d58161379d565b82525050565b60006020820190506140f060008301846140cc565b92915050565b6140ff81613822565b811461410a57600080fd5b50565b60008135905061411c816140f6565b92915050565b6000806040838503121561413957614138613793565b5b6000614147858286016139e9565b92505060206141588582860161410d565b9150509250929050565b600067ffffffffffffffff82111561417d5761417c613b21565b5b614186826138a7565b9050602081019050919050565b60006141a66141a184614162565b613b81565b9050828152602081018484840111156141c2576141c1613bcd565b5b6141cd848285613c03565b509392505050565b600082601f8301126141ea576141e9613b1c565b5b81356141fa848260208601614193565b91505092915050565b6000806000806080858703121561421d5761421c613793565b5b600061422b878288016139e9565b945050602061423c878288016139e9565b935050604061424d87828801613934565b925050606085013567ffffffffffffffff81111561426e5761426d613798565b5b61427a878288016141d5565b91505092959194509250565b600080fd5b600060c082840312156142a1576142a0614286565b5b81905092915050565b6000602082840312156142c0576142bf613793565b5b600082013567ffffffffffffffff8111156142de576142dd613798565b5b6142ea8482850161428b565b91505092915050565b600065ffffffffffff82169050919050565b61430e816142f3565b82525050565b600063ffffffff82169050919050565b61432d81614314565b82525050565b61433c81613913565b82525050565b60e0820160008201516143586000850182614305565b50602082015161436b6020850182614305565b50604082015161437e6040850182614305565b5060608201516143916060850182614305565b5060808201516143a46080850182614324565b5060a08201516143b760a0850182614324565b5060c08201516143ca60c0850182614333565b50505050565b600060e0820190506143e56000830184614342565b92915050565b6000806040838503121561440257614401613793565b5b6000614410858286016139e9565b9250506020614421858286016139e9565b9150509250929050565b614434816142f3565b811461443f57600080fd5b50565b6000813590506144518161442b565b92915050565b61446081614314565b811461446b57600080fd5b50565b60008135905061447d81614457565b92915050565b60008060008060008060c087890312156144a05761449f613793565b5b60006144ae89828a01614442565b96505060206144bf89828a01614442565b95505060406144d089828a01614442565b94505060606144e189828a01614442565b93505060806144f289828a0161446e565b92505060a061450389828a0161446e565b9150509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061455757607f821691505b60208210810361456a57614569614510565b5b50919050565b7f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000600082015250565b60006145a6601783613863565b91506145b182614570565b602082019050919050565b600060208201905081810360008301526145d581614599565b9050919050565b7f44617461204d69736d6174636800000000000000000000000000000000000000600082015250565b6000614612600d83613863565b915061461d826145dc565b602082019050919050565b6000602082019050818103600083015261464181614605565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f496e666f204572726f7200000000000000000000000000000000000000000000600082015250565b60006146ad600a83613863565b91506146b882614677565b602082019050919050565b600060208201905081810360008301526146dc816146a0565b9050919050565b600081519050919050565b6000819050602082019050919050565b600061470a825161379d565b80915050919050565b600082821b905092915050565b600061472b826146e3565b82614735846146ee565b9050614740816146fe565b925060048210156147805761477b7fffffffff0000000000000000000000000000000000000000000000000000000083600403600802614713565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006147c182613913565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036147f3576147f2614787565b5b600182019050919050565b7f4d656e74616c3a205175616e746974792053686f756c6420426520426967676560008201527f72205468616e205a65726f2e0000000000000000000000000000000000000000602082015250565b600061485a602c83613863565b9150614865826147fe565b604082019050919050565b600060208201905081810360008301526148898161484d565b9050919050565b600061489b82613913565b91506148a683613913565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156148db576148da614787565b5b828201905092915050565b7f4d656e74616c3a2049742057696c6c20457863656564204d617820537570706c60008201527f792e000000000000000000000000000000000000000000000000000000000000602082015250565b6000614942602283613863565b915061494d826148e6565b604082019050919050565b6000602082019050818103600083015261497181614935565b9050919050565b7f4d656e74616c3a2054686520526563697069656e74204164647265737320497360008201527f204e6f7420536574000000000000000000000000000000000000000000000000602082015250565b60006149d4602883613863565b91506149df82614978565b604082019050919050565b60006020820190508181036000830152614a03816149c7565b9050919050565b600082905092915050565b6000614a218383614a0a565b82614a2c813561379d565b92506004821015614a6c57614a677fffffffff0000000000000000000000000000000000000000000000000000000083600403600802614713565b831692505b505092915050565b7f4c696d6974204572726f72000000000000000000000000000000000000000000600082015250565b6000614aaa600b83613863565b9150614ab582614a74565b602082019050919050565b60006020820190508181036000830152614ad981614a9d565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614b16601883613863565b9150614b2182614ae0565b602082019050919050565b60006020820190508181036000830152614b4581614b09565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614ba8602983613863565b9150614bb382614b4c565b604082019050919050565b60006020820190508181036000830152614bd781614b9b565b9050919050565b7f4d7573742062652067726561746572207468616e203000000000000000000000600082015250565b6000614c14601683613863565b9150614c1f82614bde565b602082019050919050565b60006020820190508181036000830152614c4381614c07565b9050919050565b7f4d656e74616c3a204d696e74204973204e6f74204f6e00000000000000000000600082015250565b6000614c80601683613863565b9150614c8b82614c4a565b602082019050919050565b60006020820190508181036000830152614caf81614c73565b9050919050565b7f5a65726f20416464726573730000000000000000000000000000000000000000600082015250565b6000614cec600c83613863565b9150614cf782614cb6565b602082019050919050565b60006020820190508181036000830152614d1b81614cdf565b9050919050565b600060208284031215614d3857614d37613793565b5b6000614d4684828501613d96565b91505092915050565b7f4578636565647320436f6c6c656374696f6e2053697a65000000000000000000600082015250565b6000614d85601783613863565b9150614d9082614d4f565b602082019050919050565b60006020820190508181036000830152614db481614d78565b9050919050565b7f496e73756666696369656e742046756e64000000000000000000000000000000600082015250565b6000614df1601183613863565b9150614dfc82614dbb565b602082019050919050565b60006020820190508181036000830152614e2081614de4565b9050919050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112614e5357614e52614e27565b5b80840192508235915067ffffffffffffffff821115614e7557614e74614e2c565b5b602083019250600182023603831315614e9157614e90614e31565b5b509250929050565b6000614ea482613d63565b9150614eaf83613d63565b9250826fffffffffffffffffffffffffffffffff03821115614ed457614ed3614787565b5b828201905092915050565b600081905092915050565b6000614ef582613858565b614eff8185614edf565b9350614f0f818560208601613874565b80840191505092915050565b6000614f278285614eea565b9150614f338284614eea565b91508190509392505050565b6000614f4a826142f3565b9150614f55836142f3565b92508265ffffffffffff03821115614f7057614f6f614787565b5b828201905092915050565b7f4d696e742054696d6520536c6f7473204e6f7420496e204f7264657200000000600082015250565b6000614fb1601c83613863565b9150614fbc82614f7b565b602082019050919050565b60006020820190508181036000830152614fe081614fa4565b9050919050565b6000614ff282613913565b9150614ffd83613913565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561503657615035614787565b5b828202905092915050565b600060408201905061505660008301856139a8565b61506360208301846139a8565b9392505050565b600081519050615079816140f6565b92915050565b60006020828403121561509557615094613793565b5b60006150a38482850161506a565b91505092915050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000615108602183613863565b9150615113826150ac565b604082019050919050565b60006020820190508181036000830152615137816150fb565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b600061519a603e83613863565b91506151a58261513e565b604082019050919050565b600060208201905081810360008301526151c98161518d565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b600061522c602e83613863565b9150615237826151d0565b604082019050919050565b6000602082019050818103600083015261525b8161521f565b9050919050565b600061526d82614314565b915061527883614314565b92508263ffffffff0382111561529157615290614787565b5b828201905092915050565b600081905092915050565b60006152b2826146e3565b6152bc818561529c565b93506152cc818560208601613874565b80840191505092915050565b60006152e482846152a7565b915081905092915050565b7f4554485f5452414e534645525f4641494c454400000000000000000000000000600082015250565b6000615325601383613863565b9150615330826152ef565b602082019050919050565b6000602082019050818103600083015261535481615318565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061539582613913565b91506153a083613913565b9250826153b0576153af61535b565b5b828204905092915050565b60006153c682613913565b91506153d183613913565b9250828210156153e4576153e3614787565b5b828203905092915050565b60006153fa82613913565b915061540583613913565b9250826154155761541461535b565b5b828206905092915050565b600060ff82169050919050565b61543681615420565b811461544157600080fd5b50565b6000813590506154538161542d565b92915050565b60006020828403121561546f5761546e613793565b5b600061547d84828501615444565b91505092915050565b7f41757468656e7469636174696f6e204661696c73000000000000000000000000600082015250565b60006154bc601483613863565b91506154c782615486565b602082019050919050565b600060208201905081810360008301526154eb816154af565b9050919050565b7f596f75204e65656420445320526f6c6520466f722050726976696c656765204d60008201527f696e740000000000000000000000000000000000000000000000000000000000602082015250565b600061554e602383613863565b9150615559826154f2565b604082019050919050565b6000602082019050818103600083015261557d81615541565b9050919050565b7f446973636f756e7420496e666f726d6174696f6e204973204e6f742053657400600082015250565b60006155ba601f83613863565b91506155c582615584565b602082019050919050565b600060208201905081810360008301526155e9816155ad565b9050919050565b7f457863656564732054686520416c6c6f77656420416d6f756e74000000000000600082015250565b6000615626601a83613863565b9150615631826155f0565b602082019050919050565b6000602082019050818103600083015261565581615619565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006156b8602583613863565b91506156c38261565c565b604082019050919050565b600060208201905081810360008301526156e7816156ab565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061574a602483613863565b9150615755826156ee565b604082019050919050565b600060208201905081810360008301526157798161573d565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006157dc603283613863565b91506157e782615780565b604082019050919050565b6000602082019050818103600083015261580b816157cf565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615848601983613863565b915061585382615812565b602082019050919050565b600060208201905081810360008301526158778161583b565b9050919050565b600061588a838561529c565b9350615897838584613c03565b82840190509392505050565b60006158b082848661587e565b91508190509392505050565b60006080820190506158d16000830187613af2565b6158de60208301866139a8565b6158eb6040830185614054565b6158f86060830184613af2565b95945050505050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000615937600283614edf565b915061594282615901565b600282019050919050565b6000819050919050565b61596861596382613ae8565b61594d565b82525050565b60006159798261592a565b91506159858285615957565b6020820191506159958284615957565b6020820191508190509392505050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006159db602083613863565b91506159e6826159a5565b602082019050919050565b60006020820190508181036000830152615a0a816159ce565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615a47601c83613863565b9150615a5282615a11565b602082019050919050565b60006020820190508181036000830152615a7681615a3a565b9050919050565b600082825260208201905092915050565b6000615a99826146e3565b615aa38185615a7d565b9350615ab3818560208601613874565b615abc816138a7565b840191505092915050565b6000608082019050615adc60008301876139a8565b615ae960208301866139a8565b615af66040830185613a6b565b8181036060830152615b088184615a8e565b905095945050505050565b600081519050615b22816137c9565b92915050565b600060208284031215615b3e57615b3d613793565b5b6000615b4c84828501615b13565b91505092915050565b7f5369676e61747572653a20496e76616c6964207320706172616d657465720000600082015250565b6000615b8b601e83613863565b9150615b9682615b55565b602082019050919050565b60006020820190508181036000830152615bba81615b7e565b9050919050565b7f5369676e61747572653a20496e76616c6964207620706172616d657465720000600082015250565b6000615bf7601e83613863565b9150615c0282615bc1565b602082019050919050565b60006020820190508181036000830152615c2681615bea565b9050919050565b615c3681615420565b82525050565b6000608082019050615c516000830187613af2565b615c5e6020830186615c2d565b615c6b6040830185613af2565b615c786060830184613af2565b95945050505050565b7f5369676e61747572653a20496e76616c6964207369676e657200000000000000600082015250565b6000615cb7601983613863565b9150615cc282615c81565b602082019050919050565b60006020820190508181036000830152615ce681615caa565b905091905056fea2646970667358221220151bf16dffb93cc951553012735562c7574cb2ec8c0ac04ecab66c25b36da7b164736f6c634300080d0033000000000000000000000000c5881c58d67cf6c336f4c7e01eac9deed0892ae2000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000e4d656e74616c20436f6c6c656765000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d4d656e74616c436f6c6c65676500000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106101c25760003560e01c80636352211e116100f7578063b88d4fde11610095578063e985e9c511610064578063e985e9c514610644578063ea0f434314610681578063ef6eff45146106aa578063f2fde38b146106e7576101c2565b8063b88d4fde14610597578063baac5a11146105c0578063c87b56dd146105dc578063d0520c2314610619576101c2565b806395d89b41116100d157806395d89b41146104ed5780639eaa656c14610518578063a22cb46514610543578063b3d5adf41461056c576101c2565b80636352211e1461044a57806370a082311461048757806380b15659146104c4576101c2565b80633644e5151161016457806341f434341161013e57806341f434341461038f57806342842e0e146103ba57806355f804b3146103e35780635d055fcd1461040c576101c2565b80633644e5151461031257806336f5511b1461033d578063375a069a14610366576101c2565b8063095ea7b3116101a0578063095ea7b31461026c57806309cae1531461029557806318160ddd146102be57806323b872dd146102e9576101c2565b806301ffc9a7146101c757806306fdde0314610204578063081812fc1461022f575b600080fd5b3480156101d357600080fd5b506101ee60048036038101906101e991906137f5565b610710565b6040516101fb919061383d565b60405180910390f35b34801561021057600080fd5b506102196107f2565b60405161022691906138f1565b60405180910390f35b34801561023b57600080fd5b5061025660048036038101906102519190613949565b610884565b60405161026391906139b7565b60405180910390f35b34801561027857600080fd5b50610293600480360381019061028e91906139fe565b6108ca565b005b3480156102a157600080fd5b506102bc60048036038101906102b79190613a3e565b6108e3565b005b3480156102ca57600080fd5b506102d3610a39565b6040516102e09190613a7a565b60405180910390f35b3480156102f557600080fd5b50610310600480360381019061030b9190613a95565b610a3f565b005b34801561031e57600080fd5b50610327610a8e565b6040516103349190613b01565b60405180910390f35b34801561034957600080fd5b50610364600480360381019061035f9190613e42565b610ab2565b005b34801561037257600080fd5b5061038d60048036038101906103889190613949565b610d36565b005b34801561039b57600080fd5b506103a4610f6d565b6040516103b19190613f48565b60405180910390f35b3480156103c657600080fd5b506103e160048036038101906103dc9190613a95565b610f7f565b005b3480156103ef57600080fd5b5061040a60048036038101906104059190613f63565b610fce565b005b34801561041857600080fd5b50610433600480360381019061042e9190614007565b611078565b604051610441929190614063565b60405180910390f35b34801561045657600080fd5b50610471600480360381019061046c9190613949565b6111e6565b60405161047e91906139b7565b60405180910390f35b34801561049357600080fd5b506104ae60048036038101906104a99190613a3e565b611297565b6040516104bb9190613a7a565b60405180910390f35b3480156104d057600080fd5b506104eb60048036038101906104e6919061408c565b61134e565b005b3480156104f957600080fd5b506105026114a6565b60405161050f91906138f1565b60405180910390f35b34801561052457600080fd5b5061052d611538565b60405161053a91906140db565b60405180910390f35b34801561054f57600080fd5b5061056a60048036038101906105659190614122565b611543565b005b34801561057857600080fd5b5061058161155c565b60405161058e9190613a7a565b60405180910390f35b3480156105a357600080fd5b506105be60048036038101906105b99190614203565b611562565b005b6105da60048036038101906105d591906142aa565b6115b3565b005b3480156105e857600080fd5b5061060360048036038101906105fe9190613949565b61199b565b60405161061091906138f1565b60405180910390f35b34801561062557600080fd5b5061062e611a03565b60405161063b91906143d0565b60405180910390f35b34801561065057600080fd5b5061066b600480360381019061066691906143eb565b611a91565b604051610678919061383d565b60405180910390f35b34801561068d57600080fd5b506106a860048036038101906106a39190614483565b611b25565b005b3480156106b657600080fd5b506106d160048036038101906106cc91906142aa565b611ca5565b6040516106de9190613a7a565b60405180910390f35b3480156106f357600080fd5b5061070e60048036038101906107099190613a3e565b611d0d565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107db57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107eb57506107ea82611e63565b5b9050919050565b6060600080546108019061453f565b80601f016020809104026020016040519081016040528092919081815260200182805461082d9061453f565b801561087a5780601f1061084f5761010080835404028352916020019161087a565b820191906000526020600020905b81548152906001019060200180831161085d57829003601f168201915b5050505050905090565b600061088f82611ecd565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b816108d481611f18565b6108de8383612015565b505050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610973576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096a906145bc565b60405180910390fd5b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600c5481565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a7d57610a7c33611f18565b5b610a8884848461212c565b50505050565b7fd4485520862c1a3c1db086c50226101497a8afe88befbdbd8e21e1d6653ce6bb81565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b39906145bc565b60405180910390fd5b81518351148015610b54575080518251145b610b93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8a90614628565b60405180910390fd5b60005b8351811015610d30576000838281518110610bb457610bb3614648565b5b60200260200101516fffffffffffffffffffffffffffffffff16118015610c0757506000828281518110610beb57610bea614648565b5b60200260200101516fffffffffffffffffffffffffffffffff16115b610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d906146c3565b60405180910390fd5b6080828281518110610c5b57610c5a614648565b5b60200260200101516fffffffffffffffffffffffffffffffff16901b838281518110610c8a57610c89614648565b5b60200260200101516fffffffffffffffffffffffffffffffff1617600b6000868481518110610cbc57610cbb614648565b5b6020026020010151610ccd90614720565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055508080610d28906147b6565b915050610b96565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610dc6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbd906145bc565b60405180910390fd5b60008111610e09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0090614870565b60405180910390fd5b61177081600c54610e1a9190614890565b1115610e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5290614958565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610eec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee3906149ea565b60405180910390fd5b60005b81811015610f5057610f25600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600e5461218c565b600e6000815480929190610f38906147b6565b91905055508080610f48906147b6565b915050610eef565b5080600c6000828254610f639190614890565b9250508190555050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610fbd57610fbc33611f18565b5b610fc88484846121aa565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461105e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611055906145bc565b60405180910390fd5b806010908051906020019061107492919061367d565b5050565b6000806000600b600086869061108e9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020541161111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111290614ac0565b60405180910390fd5b600b600085859061112c9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546080600b600087879061118c9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054901c915091509250929050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361128e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128590614b2c565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611307576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fe90614bbe565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146113de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d5906145bc565b60405180910390fd5b60008211801561141b5750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61145a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145190614c2a565b60405180910390fd5b81600d8190555080600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6060600180546114b59061453f565b80601f01602080910402602001604051908101604052809291908181526020018280546114e19061453f565b801561152e5780601f106115035761010080835404028352916020019161152e565b820191906000526020600020905b81548152906001019060200180831161151157829003601f168201915b5050505050905090565b636473000060e01b81565b8161154d81611f18565b61155783836121ca565b505050565b61177081565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146115a05761159f33611f18565b5b6115ac858585856121e0565b5050505050565b6115bb612242565b806115ca57506115c961228c565b5b806115d957506115d86122d2565b5b611618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160f90614c96565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168160000160208101906116439190613a3e565b73ffffffffffffffffffffffffffffffffffffffff1603611699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169090614d02565b60405180910390fd5b6117708160200160208101906116af9190614d22565b6fffffffffffffffffffffffffffffffff16600c546116ce9190614890565b111561170f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170690614d9b565b60405180910390fd5b600061171a82611ca5565b905080341015801561172c5750600081115b61176b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176290614e07565b60405180910390fd5b611797600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff163461231c565b60005b8260200160208101906117ad9190614d22565b6fffffffffffffffffffffffffffffffff1681101561180f576117e48360000160208101906117dc9190613a3e565b600e5461218c565b600e60008154809291906117f7906147b6565b91905055508080611807906147b6565b91505061179a565b508160200160208101906118239190614d22565b6fffffffffffffffffffffffffffffffff16600c60008282546118469190614890565b92505081905550611855612242565b8061186457506118636122d2565b5b156119975781602001602081019061187c9190614d22565b600a60008460000160208101906118939190613a3e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008480604001906118df9190614e36565b906118ea9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060008282829054906101000a90046fffffffffffffffffffffffffffffffff166119609190614e99565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b5050565b60606119a682611ecd565b60006119b061241c565b905060008151116119d057604051806020016040528060008152506119fb565b806119da84612503565b6040516020016119eb929190614f1b565b6040516020818303038152906040525b915050919050565b611a0b613703565b6040518060e00160405280600f5465ffffffffffff1681526020016030600f54901c65ffffffffffff1681526020016060600f54901c65ffffffffffff1681526020016090600f54901c65ffffffffffff16815260200160c0600f54901c63ffffffff16815260200160e0600f54901c63ffffffff168152602001600d54815250905090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bac906145bc565b60405180910390fd5b60008665ffffffffffff16118015611be857508486611bd49190614f3f565b65ffffffffffff168465ffffffffffff1610155b8015611c0d57508284611bfb9190614f3f565b65ffffffffffff168263ffffffff1610155b611c4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4390614fc7565b60405180910390fd5b60e08163ffffffff16901b60c08363ffffffff16901b60908565ffffffffffff16901b60608765ffffffffffff16901b60308965ffffffffffff16901b8a65ffffffffffff161717171717600f81905550505050505050565b6000611caf612242565b80611cbe5750611cbd6122d2565b5b15611cd357611ccc82612663565b9050611d08565b600d54826020016020810190611ce99190614d22565b6fffffffffffffffffffffffffffffffff16611d059190614fe7565b90505b919050565b3373ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611d9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d94906145bc565b60405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611ed681612a04565b611f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0c90614b2c565b60405180910390fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612012576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611f8f929190615041565b602060405180830381865afa158015611fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd0919061507f565b61201157806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161200891906139b7565b60405180910390fd5b5b50565b6000612020826111e6565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612090576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120879061511e565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166120af612a70565b73ffffffffffffffffffffffffffffffffffffffff1614806120de57506120dd816120d8612a70565b611a91565b5b61211d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612114906151b0565b60405180910390fd5b6121278383612a78565b505050565b61213d612137612a70565b82612b31565b61217c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217390615242565b60405180910390fd5b612187838383612bc6565b505050565b6121a6828260405180602001604052806000815250612e2c565b5050565b6121c583838360405180602001604052806000815250611562565b505050565b6121dc6121d5612a70565b8383612e87565b5050565b6121f16121eb612a70565b83612b31565b612230576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222790615242565b60405180910390fd5b61223c84848484612ff3565b50505050565b60008061224d611a03565b905042816040015165ffffffffffff16111580156122865750428160600151826040015161227b9190614f3f565b65ffffffffffff1610155b91505090565b600080612297611a03565b905042816080015163ffffffff16111580156122cc5750428160a0015182608001516122c39190615262565b63ffffffff1610155b91505090565b6000806122dd611a03565b905042816000015165ffffffffffff16111580156123165750428160200151826000015161230b9190614f3f565b65ffffffffffff1610155b91505090565b60008273ffffffffffffffffffffffffffffffffffffffff1682600067ffffffffffffffff81111561235157612350613b21565b5b6040519080825280601f01601f1916602001820160405280156123835781602001600182028036833780820191505090505b5060405161239191906152d8565b60006040518083038185875af1925050503d80600081146123ce576040519150601f19603f3d011682016040523d82523d6000602084013e6123d3565b606091505b5050905080612417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240e9061533b565b60405180910390fd5b505050565b606060006010805461242d9061453f565b905011156124c757601080546124429061453f565b80601f016020809104026020016040519081016040528092919081815260200182805461246e9061453f565b80156124bb5780601f10612490576101008083540402835291602001916124bb565b820191906000526020600020905b81548152906001019060200180831161249e57829003601f168201915b50505050509050612500565b6040518060400160405280600a81526020017f57616974696e672e2e2e0000000000000000000000000000000000000000000081525090505b90565b60606000820361254a576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061265e565b600082905060005b6000821461257c578080612565906147b6565b915050600a82612575919061538a565b9150612552565b60008167ffffffffffffffff81111561259857612597613b21565b5b6040519080825280601f01601f1916602001820160405280156125ca5781602001600182028036833780820191505090505b5090505b60008514612657576001826125e391906153bb565b9150600a856125f291906153ef565b60306125fe9190614890565b60f81b81838151811061261457612613614648565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612650919061538a565b94506125ce565b8093505050505b919050565b60006126d76126718361304f565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460600160208101906126a79190615459565b85608001358660a001357fd4485520862c1a3c1db086c50226101497a8afe88befbdbd8e21e1d6653ce6bb6130f1565b612716576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270d906154d2565b60405180910390fd5b61271e6122d2565b156127c557636473000060e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191682806040019061275a9190614e36565b906127659190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146127c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127bb90615564565b60405180910390fd5b5b6000806127e08480604001906127db9190614e36565b611078565b915091506000816fffffffffffffffffffffffffffffffff1611612839576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612830906155d0565b60405180910390fd5b816fffffffffffffffffffffffffffffffff1684602001602081019061285f9190614d22565b600a60008760000160208101906128769190613a3e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008780604001906128c29190614e36565b906128cd9190614a15565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166129409190614e99565b6fffffffffffffffffffffffffffffffff161115612993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298a9061563c565b60405180910390fd5b8360200160208101906129a69190614d22565b6fffffffffffffffffffffffffffffffff166064826fffffffffffffffffffffffffffffffff16600d546129da9190614fe7565b6129e4919061538a565b600d546129f191906153bb565b6129fb9190614fe7565b92505050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612aeb836111e6565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080612b3d836111e6565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612b7f5750612b7e8185611a91565b5b80612bbd57508373ffffffffffffffffffffffffffffffffffffffff16612ba584610884565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612be6826111e6565b73ffffffffffffffffffffffffffffffffffffffff1614612c3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c33906156ce565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612cab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca290615760565b60405180910390fd5b612cb6838383613166565b612cc1600082612a78565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612d1191906153bb565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612d689190614890565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612e2783838361316b565b505050565b612e368383613170565b612e436000848484613349565b612e82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e79906157f2565b60405180910390fd5b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612ef5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eec9061585e565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612fe6919061383d565b60405180910390a3505050565b612ffe848484612bc6565b61300a84848484613349565b613049576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613040906157f2565b60405180910390fd5b50505050565b60007f58e2f0ec35eb789493367bbd774d478d0e7e6916118069574ff2690b3800424560001b8260000160208101906130889190613a3e565b83602001602081019061309b9190614d22565b8480604001906130ab9190614e36565b6040516130b99291906158a3565b60405180910390206040516020016130d494939291906158bc565b604051602081830303815290604052805190602001209050919050565b600080828860405160200161310792919061596e565b6040516020818303038152906040528051906020012090508673ffffffffffffffffffffffffffffffffffffffff16613142828888886134d0565b73ffffffffffffffffffffffffffffffffffffffff16149150509695505050505050565b505050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036131df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131d6906159f1565b60405180910390fd5b6131e881612a04565b15613228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321f90615a5d565b60405180910390fd5b61323460008383613166565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546132849190614890565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46133456000838361316b565b5050565b600061336a8473ffffffffffffffffffffffffffffffffffffffff1661365a565b156134c3578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613393612a70565b8786866040518563ffffffff1660e01b81526004016133b59493929190615ac7565b6020604051808303816000875af19250505080156133f157506040513d601f19601f820116820180604052508101906133ee9190615b28565b60015b613473573d8060008114613421576040519150601f19603f3d011682016040523d82523d6000602084013e613426565b606091505b50600081510361346b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613462906157f2565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506134c8565b600190505b949350505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c1115613538576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161352f90615ba1565b60405180910390fd5b601b8460ff16148061354d5750601c8460ff16145b61358c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161358390615c0d565b60405180910390fd5b6000600186868686604051600081526020016040526040516135b19493929190615c3c565b6020604051602081039080840390855afa1580156135d3573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361364e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161364590615ccd565b60405180910390fd5b80915050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b8280546136899061453f565b90600052602060002090601f0160209004810192826136ab57600085556136f2565b82601f106136c457805160ff19168380011785556136f2565b828001600101855582156136f2579182015b828111156136f15782518255916020019190600101906136d6565b5b5090506136ff919061376c565b5090565b6040518060e00160405280600065ffffffffffff168152602001600065ffffffffffff168152602001600065ffffffffffff168152602001600065ffffffffffff168152602001600063ffffffff168152602001600063ffffffff168152602001600081525090565b5b8082111561378557600081600090555060010161376d565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6137d28161379d565b81146137dd57600080fd5b50565b6000813590506137ef816137c9565b92915050565b60006020828403121561380b5761380a613793565b5b6000613819848285016137e0565b91505092915050565b60008115159050919050565b61383781613822565b82525050565b6000602082019050613852600083018461382e565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613892578082015181840152602081019050613877565b838111156138a1576000848401525b50505050565b6000601f19601f8301169050919050565b60006138c382613858565b6138cd8185613863565b93506138dd818560208601613874565b6138e6816138a7565b840191505092915050565b6000602082019050818103600083015261390b81846138b8565b905092915050565b6000819050919050565b61392681613913565b811461393157600080fd5b50565b6000813590506139438161391d565b92915050565b60006020828403121561395f5761395e613793565b5b600061396d84828501613934565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006139a182613976565b9050919050565b6139b181613996565b82525050565b60006020820190506139cc60008301846139a8565b92915050565b6139db81613996565b81146139e657600080fd5b50565b6000813590506139f8816139d2565b92915050565b60008060408385031215613a1557613a14613793565b5b6000613a23858286016139e9565b9250506020613a3485828601613934565b9150509250929050565b600060208284031215613a5457613a53613793565b5b6000613a62848285016139e9565b91505092915050565b613a7481613913565b82525050565b6000602082019050613a8f6000830184613a6b565b92915050565b600080600060608486031215613aae57613aad613793565b5b6000613abc868287016139e9565b9350506020613acd868287016139e9565b9250506040613ade86828701613934565b9150509250925092565b6000819050919050565b613afb81613ae8565b82525050565b6000602082019050613b166000830184613af2565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613b59826138a7565b810181811067ffffffffffffffff82111715613b7857613b77613b21565b5b80604052505050565b6000613b8b613789565b9050613b978282613b50565b919050565b600067ffffffffffffffff821115613bb757613bb6613b21565b5b602082029050602081019050919050565b600080fd5b600080fd5b600067ffffffffffffffff821115613bed57613bec613b21565b5b613bf6826138a7565b9050602081019050919050565b82818337600083830152505050565b6000613c25613c2084613bd2565b613b81565b905082815260208101848484011115613c4157613c40613bcd565b5b613c4c848285613c03565b509392505050565b600082601f830112613c6957613c68613b1c565b5b8135613c79848260208601613c12565b91505092915050565b6000613c95613c9084613b9c565b613b81565b90508083825260208201905060208402830185811115613cb857613cb7613bc8565b5b835b81811015613cff57803567ffffffffffffffff811115613cdd57613cdc613b1c565b5b808601613cea8982613c54565b85526020850194505050602081019050613cba565b5050509392505050565b600082601f830112613d1e57613d1d613b1c565b5b8135613d2e848260208601613c82565b91505092915050565b600067ffffffffffffffff821115613d5257613d51613b21565b5b602082029050602081019050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b613d8881613d63565b8114613d9357600080fd5b50565b600081359050613da581613d7f565b92915050565b6000613dbe613db984613d37565b613b81565b90508083825260208201905060208402830185811115613de157613de0613bc8565b5b835b81811015613e0a5780613df68882613d96565b845260208401935050602081019050613de3565b5050509392505050565b600082601f830112613e2957613e28613b1c565b5b8135613e39848260208601613dab565b91505092915050565b600080600060608486031215613e5b57613e5a613793565b5b600084013567ffffffffffffffff811115613e7957613e78613798565b5b613e8586828701613d09565b935050602084013567ffffffffffffffff811115613ea657613ea5613798565b5b613eb286828701613e14565b925050604084013567ffffffffffffffff811115613ed357613ed2613798565b5b613edf86828701613e14565b9150509250925092565b6000819050919050565b6000613f0e613f09613f0484613976565b613ee9565b613976565b9050919050565b6000613f2082613ef3565b9050919050565b6000613f3282613f15565b9050919050565b613f4281613f27565b82525050565b6000602082019050613f5d6000830184613f39565b92915050565b600060208284031215613f7957613f78613793565b5b600082013567ffffffffffffffff811115613f9757613f96613798565b5b613fa384828501613c54565b91505092915050565b600080fd5b60008083601f840112613fc757613fc6613b1c565b5b8235905067ffffffffffffffff811115613fe457613fe3613fac565b5b60208301915083600182028301111561400057613fff613bc8565b5b9250929050565b6000806020838503121561401e5761401d613793565b5b600083013567ffffffffffffffff81111561403c5761403b613798565b5b61404885828601613fb1565b92509250509250929050565b61405d81613d63565b82525050565b60006040820190506140786000830185614054565b6140856020830184614054565b9392505050565b600080604083850312156140a3576140a2613793565b5b60006140b185828601613934565b92505060206140c2858286016139e9565b9150509250929050565b6140d58161379d565b82525050565b60006020820190506140f060008301846140cc565b92915050565b6140ff81613822565b811461410a57600080fd5b50565b60008135905061411c816140f6565b92915050565b6000806040838503121561413957614138613793565b5b6000614147858286016139e9565b92505060206141588582860161410d565b9150509250929050565b600067ffffffffffffffff82111561417d5761417c613b21565b5b614186826138a7565b9050602081019050919050565b60006141a66141a184614162565b613b81565b9050828152602081018484840111156141c2576141c1613bcd565b5b6141cd848285613c03565b509392505050565b600082601f8301126141ea576141e9613b1c565b5b81356141fa848260208601614193565b91505092915050565b6000806000806080858703121561421d5761421c613793565b5b600061422b878288016139e9565b945050602061423c878288016139e9565b935050604061424d87828801613934565b925050606085013567ffffffffffffffff81111561426e5761426d613798565b5b61427a878288016141d5565b91505092959194509250565b600080fd5b600060c082840312156142a1576142a0614286565b5b81905092915050565b6000602082840312156142c0576142bf613793565b5b600082013567ffffffffffffffff8111156142de576142dd613798565b5b6142ea8482850161428b565b91505092915050565b600065ffffffffffff82169050919050565b61430e816142f3565b82525050565b600063ffffffff82169050919050565b61432d81614314565b82525050565b61433c81613913565b82525050565b60e0820160008201516143586000850182614305565b50602082015161436b6020850182614305565b50604082015161437e6040850182614305565b5060608201516143916060850182614305565b5060808201516143a46080850182614324565b5060a08201516143b760a0850182614324565b5060c08201516143ca60c0850182614333565b50505050565b600060e0820190506143e56000830184614342565b92915050565b6000806040838503121561440257614401613793565b5b6000614410858286016139e9565b9250506020614421858286016139e9565b9150509250929050565b614434816142f3565b811461443f57600080fd5b50565b6000813590506144518161442b565b92915050565b61446081614314565b811461446b57600080fd5b50565b60008135905061447d81614457565b92915050565b60008060008060008060c087890312156144a05761449f613793565b5b60006144ae89828a01614442565b96505060206144bf89828a01614442565b95505060406144d089828a01614442565b94505060606144e189828a01614442565b93505060806144f289828a0161446e565b92505060a061450389828a0161446e565b9150509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061455757607f821691505b60208210810361456a57614569614510565b5b50919050565b7f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000600082015250565b60006145a6601783613863565b91506145b182614570565b602082019050919050565b600060208201905081810360008301526145d581614599565b9050919050565b7f44617461204d69736d6174636800000000000000000000000000000000000000600082015250565b6000614612600d83613863565b915061461d826145dc565b602082019050919050565b6000602082019050818103600083015261464181614605565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f496e666f204572726f7200000000000000000000000000000000000000000000600082015250565b60006146ad600a83613863565b91506146b882614677565b602082019050919050565b600060208201905081810360008301526146dc816146a0565b9050919050565b600081519050919050565b6000819050602082019050919050565b600061470a825161379d565b80915050919050565b600082821b905092915050565b600061472b826146e3565b82614735846146ee565b9050614740816146fe565b925060048210156147805761477b7fffffffff0000000000000000000000000000000000000000000000000000000083600403600802614713565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006147c182613913565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036147f3576147f2614787565b5b600182019050919050565b7f4d656e74616c3a205175616e746974792053686f756c6420426520426967676560008201527f72205468616e205a65726f2e0000000000000000000000000000000000000000602082015250565b600061485a602c83613863565b9150614865826147fe565b604082019050919050565b600060208201905081810360008301526148898161484d565b9050919050565b600061489b82613913565b91506148a683613913565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156148db576148da614787565b5b828201905092915050565b7f4d656e74616c3a2049742057696c6c20457863656564204d617820537570706c60008201527f792e000000000000000000000000000000000000000000000000000000000000602082015250565b6000614942602283613863565b915061494d826148e6565b604082019050919050565b6000602082019050818103600083015261497181614935565b9050919050565b7f4d656e74616c3a2054686520526563697069656e74204164647265737320497360008201527f204e6f7420536574000000000000000000000000000000000000000000000000602082015250565b60006149d4602883613863565b91506149df82614978565b604082019050919050565b60006020820190508181036000830152614a03816149c7565b9050919050565b600082905092915050565b6000614a218383614a0a565b82614a2c813561379d565b92506004821015614a6c57614a677fffffffff0000000000000000000000000000000000000000000000000000000083600403600802614713565b831692505b505092915050565b7f4c696d6974204572726f72000000000000000000000000000000000000000000600082015250565b6000614aaa600b83613863565b9150614ab582614a74565b602082019050919050565b60006020820190508181036000830152614ad981614a9d565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614b16601883613863565b9150614b2182614ae0565b602082019050919050565b60006020820190508181036000830152614b4581614b09565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614ba8602983613863565b9150614bb382614b4c565b604082019050919050565b60006020820190508181036000830152614bd781614b9b565b9050919050565b7f4d7573742062652067726561746572207468616e203000000000000000000000600082015250565b6000614c14601683613863565b9150614c1f82614bde565b602082019050919050565b60006020820190508181036000830152614c4381614c07565b9050919050565b7f4d656e74616c3a204d696e74204973204e6f74204f6e00000000000000000000600082015250565b6000614c80601683613863565b9150614c8b82614c4a565b602082019050919050565b60006020820190508181036000830152614caf81614c73565b9050919050565b7f5a65726f20416464726573730000000000000000000000000000000000000000600082015250565b6000614cec600c83613863565b9150614cf782614cb6565b602082019050919050565b60006020820190508181036000830152614d1b81614cdf565b9050919050565b600060208284031215614d3857614d37613793565b5b6000614d4684828501613d96565b91505092915050565b7f4578636565647320436f6c6c656374696f6e2053697a65000000000000000000600082015250565b6000614d85601783613863565b9150614d9082614d4f565b602082019050919050565b60006020820190508181036000830152614db481614d78565b9050919050565b7f496e73756666696369656e742046756e64000000000000000000000000000000600082015250565b6000614df1601183613863565b9150614dfc82614dbb565b602082019050919050565b60006020820190508181036000830152614e2081614de4565b9050919050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112614e5357614e52614e27565b5b80840192508235915067ffffffffffffffff821115614e7557614e74614e2c565b5b602083019250600182023603831315614e9157614e90614e31565b5b509250929050565b6000614ea482613d63565b9150614eaf83613d63565b9250826fffffffffffffffffffffffffffffffff03821115614ed457614ed3614787565b5b828201905092915050565b600081905092915050565b6000614ef582613858565b614eff8185614edf565b9350614f0f818560208601613874565b80840191505092915050565b6000614f278285614eea565b9150614f338284614eea565b91508190509392505050565b6000614f4a826142f3565b9150614f55836142f3565b92508265ffffffffffff03821115614f7057614f6f614787565b5b828201905092915050565b7f4d696e742054696d6520536c6f7473204e6f7420496e204f7264657200000000600082015250565b6000614fb1601c83613863565b9150614fbc82614f7b565b602082019050919050565b60006020820190508181036000830152614fe081614fa4565b9050919050565b6000614ff282613913565b9150614ffd83613913565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561503657615035614787565b5b828202905092915050565b600060408201905061505660008301856139a8565b61506360208301846139a8565b9392505050565b600081519050615079816140f6565b92915050565b60006020828403121561509557615094613793565b5b60006150a38482850161506a565b91505092915050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000615108602183613863565b9150615113826150ac565b604082019050919050565b60006020820190508181036000830152615137816150fb565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b600061519a603e83613863565b91506151a58261513e565b604082019050919050565b600060208201905081810360008301526151c98161518d565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b600061522c602e83613863565b9150615237826151d0565b604082019050919050565b6000602082019050818103600083015261525b8161521f565b9050919050565b600061526d82614314565b915061527883614314565b92508263ffffffff0382111561529157615290614787565b5b828201905092915050565b600081905092915050565b60006152b2826146e3565b6152bc818561529c565b93506152cc818560208601613874565b80840191505092915050565b60006152e482846152a7565b915081905092915050565b7f4554485f5452414e534645525f4641494c454400000000000000000000000000600082015250565b6000615325601383613863565b9150615330826152ef565b602082019050919050565b6000602082019050818103600083015261535481615318565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061539582613913565b91506153a083613913565b9250826153b0576153af61535b565b5b828204905092915050565b60006153c682613913565b91506153d183613913565b9250828210156153e4576153e3614787565b5b828203905092915050565b60006153fa82613913565b915061540583613913565b9250826154155761541461535b565b5b828206905092915050565b600060ff82169050919050565b61543681615420565b811461544157600080fd5b50565b6000813590506154538161542d565b92915050565b60006020828403121561546f5761546e613793565b5b600061547d84828501615444565b91505092915050565b7f41757468656e7469636174696f6e204661696c73000000000000000000000000600082015250565b60006154bc601483613863565b91506154c782615486565b602082019050919050565b600060208201905081810360008301526154eb816154af565b9050919050565b7f596f75204e65656420445320526f6c6520466f722050726976696c656765204d60008201527f696e740000000000000000000000000000000000000000000000000000000000602082015250565b600061554e602383613863565b9150615559826154f2565b604082019050919050565b6000602082019050818103600083015261557d81615541565b9050919050565b7f446973636f756e7420496e666f726d6174696f6e204973204e6f742053657400600082015250565b60006155ba601f83613863565b91506155c582615584565b602082019050919050565b600060208201905081810360008301526155e9816155ad565b9050919050565b7f457863656564732054686520416c6c6f77656420416d6f756e74000000000000600082015250565b6000615626601a83613863565b9150615631826155f0565b602082019050919050565b6000602082019050818103600083015261565581615619565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006156b8602583613863565b91506156c38261565c565b604082019050919050565b600060208201905081810360008301526156e7816156ab565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061574a602483613863565b9150615755826156ee565b604082019050919050565b600060208201905081810360008301526157798161573d565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006157dc603283613863565b91506157e782615780565b604082019050919050565b6000602082019050818103600083015261580b816157cf565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615848601983613863565b915061585382615812565b602082019050919050565b600060208201905081810360008301526158778161583b565b9050919050565b600061588a838561529c565b9350615897838584613c03565b82840190509392505050565b60006158b082848661587e565b91508190509392505050565b60006080820190506158d16000830187613af2565b6158de60208301866139a8565b6158eb6040830185614054565b6158f86060830184613af2565b95945050505050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000615937600283614edf565b915061594282615901565b600282019050919050565b6000819050919050565b61596861596382613ae8565b61594d565b82525050565b60006159798261592a565b91506159858285615957565b6020820191506159958284615957565b6020820191508190509392505050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006159db602083613863565b91506159e6826159a5565b602082019050919050565b60006020820190508181036000830152615a0a816159ce565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615a47601c83613863565b9150615a5282615a11565b602082019050919050565b60006020820190508181036000830152615a7681615a3a565b9050919050565b600082825260208201905092915050565b6000615a99826146e3565b615aa38185615a7d565b9350615ab3818560208601613874565b615abc816138a7565b840191505092915050565b6000608082019050615adc60008301876139a8565b615ae960208301866139a8565b615af66040830185613a6b565b8181036060830152615b088184615a8e565b905095945050505050565b600081519050615b22816137c9565b92915050565b600060208284031215615b3e57615b3d613793565b5b6000615b4c84828501615b13565b91505092915050565b7f5369676e61747572653a20496e76616c6964207320706172616d657465720000600082015250565b6000615b8b601e83613863565b9150615b9682615b55565b602082019050919050565b60006020820190508181036000830152615bba81615b7e565b9050919050565b7f5369676e61747572653a20496e76616c6964207620706172616d657465720000600082015250565b6000615bf7601e83613863565b9150615c0282615bc1565b602082019050919050565b60006020820190508181036000830152615c2681615bea565b9050919050565b615c3681615420565b82525050565b6000608082019050615c516000830187613af2565b615c5e6020830186615c2d565b615c6b6040830185613af2565b615c786060830184613af2565b95945050505050565b7f5369676e61747572653a20496e76616c6964207369676e657200000000000000600082015250565b6000615cb7601983613863565b9150615cc282615c81565b602082019050919050565b60006020820190508181036000830152615ce681615caa565b905091905056fea2646970667358221220151bf16dffb93cc951553012735562c7574cb2ec8c0ac04ecab66c25b36da7b164736f6c634300080d0033

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

000000000000000000000000c5881c58d67cf6c336f4c7e01eac9deed0892ae2000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000e4d656e74616c20436f6c6c656765000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d4d656e74616c436f6c6c65676500000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : permitOwner_ (address): 0xc5881C58d67cF6c336f4C7E01eaC9deED0892ae2
Arg [1] : name_ (string): Mental College
Arg [2] : symbol_ (string): MentalCollege

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000c5881c58d67cf6c336f4c7e01eac9deed0892ae2
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [3] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [4] : 4d656e74616c20436f6c6c656765000000000000000000000000000000000000
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [6] : 4d656e74616c436f6c6c65676500000000000000000000000000000000000000


Loading...
Loading
Loading...
Loading
[ 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.