ETH Price: $3,078.20 (+2.68%)
Gas: 4 Gwei

Token

Fluffy PunkCats (FPC)
 

Overview

Max Total Supply

472 FPC

Holders

78

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
brymnr.eth
Balance
4 FPC
0x089d3d1a1d25f565bc556d7f10b0fb35ddfd2ce4
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

10,000 Fluffy PunkCats happily meowing run to the blockchain to find their owners, curl up on their knees and purr.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
SingleCollection

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 6 of 6: SingleCollection.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;

import "./libs.sol";
import "./Roles.sol";
import "./ERC721.sol";

/**
 * @title MintableOwnableToken
 * @dev anyone can mint token.
 */
contract SingleCollection is Ownable, ERC721Base, SignerRole, MinterRole {
    using BytesLibrary for bytes32;
    using StringLibrary for string;
    /// @notice Token minting event.
    event CreateERC721_v4(address indexed creator, string name, string symbol);
    
    struct MintingBatch{
        address payable owner;
        uint256 tokenId;
        Fee[] fees;
        string tokenURI;
    }

    address payable public beneficiary;

    /// @notice The contract constructor.
    /// @param name - The value for the `name`.
    /// @param symbol - The value for the `symbol`.
    /// @param contractURI - The URI with contract metadata.
    ///        The metadata should be a JSON object with fields: `id, name, description, image, external_link`.
    ///        If the URI containts `{address}` template in its body, then the template must be substituted with the contract address.
    /// @param tokenURIPrefix - The URI prefix for all the tokens. Usually set to ipfs gateway.
    /// @param signer - The address of the initial signer.
    constructor (string memory name, string memory symbol, string memory contractURI, string memory tokenURIPrefix, address signer, address payable _beneficiary) ERC721Base(name, symbol, contractURI, tokenURIPrefix) {
        emit CreateERC721_v4(msg.sender, name, symbol);
        _addSigner(signer);
        _registerInterface(bytes4(keccak256('MINT_WITH_ADDRESS')));
        beneficiary = _beneficiary;
    }

    /// @notice The function for token minting. It creates a new token.
    ///         Must contain the signature of the format: `sha3(tokenContract.address.toLowerCase() + tokenId)`.
    ///         Where `tokenContract.address` is the address of the contract and tokenId is the id in uint256 hex format.
    ///         0 as uint256 must look like this: `0000000000000000000000000000000000000000000000000000000000000000`.
    ///         The message **must not contain** the standard prefix.
    /// @param tokenId - The id of a new token.
    /// @param v - v parameter of the ECDSA signature.
    /// @param r - r parameter of the ECDSA signature.
    /// @param s - s parameter of the ECDSA signature.
    /// @param _fees - An array of the secondary fees for this token.
    /// @param tokenURI - The suffix with `tokenURIPrefix` usually complements ipfs link to metadata object.
    ///        The URI must link to JSON object with various fields: `name, description, image, external_url, attributes`.
    ///        Can also contain another various fields.
    function mint(uint256[] calldata tokenId, uint8 v, bytes32 r, bytes32 s, Fee[][] calldata _fees, string[] calldata tokenURI) public payable {
        require(isSigner(prepareMessage(tokenId, this, tokenURI).recover(v, r, s)), "signer should sign tokenId");
        require(msg.value == 3e16*tokenId.length, "(mint) incorrect msg.value");
        for (uint i = 0; i < tokenId.length; i++) {
            _mint(msg.sender, tokenId[i], _fees[i]);
            _setTokenURI(tokenId[i], tokenURI[i]);
        }

        beneficiary.transfer(msg.value);
    }
    
    function mintBatch(MintingBatch[] memory mintingBatch) public {
        require(isOwner() || isMinter(msg.sender), "Only for owner and minters minting");
        for (uint i = 0; i < mintingBatch.length; i++){
            address payable owner = mintingBatch[i].owner;
            uint256 tokenId = mintingBatch[i].tokenId;
            Fee[] memory fees = mintingBatch[i].fees;
            string memory tokenURI = mintingBatch[i].tokenURI;
            
            _mint(owner, tokenId, fees, tokenURI);
        }
    }
    
    function _mint(address payable to, uint256 tokenId, Fee[] memory fees, string memory tokenURI) private {
        super._mint(to, tokenId, fees);
        _setTokenURI(tokenId, tokenURI);
    }
    
    function prepareMessage(uint256[] calldata _id, SingleCollection _contAddr, string[] calldata tokenURI) private pure returns (string memory) {
        return keccak256(abi.encode(_id, address(_contAddr), tokenURI)).toString();
    }

    /// @notice This function can be called by the contract owner and it adds an address as a new signer.
    ///         The signer will authorize token minting by signing token ids.
    /// @param account - The address of a new signer.
    function addSigner(address account) public override onlyOwner {
        _addSigner(account);
    }

    /// @notice This function can be called by the contract owner and it removes an address from signers pool.
    /// @param account - The address of a signer to remove.
    function removeSigner(address account) public onlyOwner {
        _removeSigner(account);
    }


    /// @notice Sets the URI prefix for all tokens.
    function setTokenURIPrefix(string memory tokenURIPrefix) public onlyOwner {
        _setTokenURIPrefix(tokenURIPrefix);
    }


    /// @notice Sets the URI for the contract metadata.
    function setContractURI(string memory contractURI) public onlyOwner {
        _setContractURI(contractURI);
    }
    
    function addMinter(address account) public onlyOwner {
        _addMinter(account);
    }
    
    function removeMinter(address account) public onlyOwner{
        _removeMinter(account);
    }
}

File 1 of 6: ERC165.sol
// SPDX-License-Identifier: MIT
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);
}

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

/**
 * @dev Storage based implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165Storage is ERC165 {
    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

contract HasContractURI is ERC165Storage {

    string public contractURI;

    /*
     * bytes4(keccak256('contractURI()')) == 0xe8a3d485
     */
    bytes4 private constant _INTERFACE_ID_CONTRACT_URI = 0xe8a3d485;

    constructor(string memory _contractURI)  {
        contractURI = _contractURI;
        _registerInterface(_INTERFACE_ID_CONTRACT_URI);
    }

    /**
     * @dev Internal function to set the contract URI
     * @param _contractURI string URI prefix to assign
     */
    function _setContractURI(string memory _contractURI) internal {
        contractURI = _contractURI;
    }
}

abstract contract HasSecondarySaleFees is ERC165Storage {

    event SecondarySaleFees(uint256 tokenId, address[] recipients, uint[] bps);

    /*
     * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f
     * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb
     *
     * => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584
     */
    bytes4 private constant _INTERFACE_ID_FEES = 0xb7799584;

    constructor() {
        _registerInterface(_INTERFACE_ID_FEES);
    }

    function getFeeRecipients(uint256 id) public virtual view returns (address payable[] memory);
    function getFeeBps(uint256 id) public virtual view returns (uint[] memory);
}

File 2 of 6: ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.3.2 (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

import "./libs.sol";
import "./Roles.sol";
import "./HasTokenURI.sol";
import "./ERC165.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`, 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 be 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 Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

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

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


/**
 * @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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @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, ERC165Storage, IERC721, IERC721Metadata {
    using Address for address;
    using UintLibrary 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(ERC165Storage, 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: balance query for the zero address");
        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: owner query for nonexistent token");
        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) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        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 overriden 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 owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        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: transfer caller is not 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: transfer caller is not 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) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, 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);
    }

    /**
     * @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);
    }
    
    function _burn(address owner, uint256 tokenId) internal virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(owner, tokenId), "ERC721Burnable: caller is not owner nor approved");
    }
    /**
     * @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 of token that is not own");
        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);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {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 a {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 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 {
                    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 {}
}

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

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

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



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

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

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

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


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

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

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

    /**
     * @dev 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` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * 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 override {
        super._beforeTokenTransfer(from, to, tokenId);

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * @title Full ERC721 Token with support for tokenURIPrefix
 * This implementation includes all the required and some optional functionality of the ERC721 standard
 * Moreover, it includes approve all functionality using operator terminology
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721Base is HasSecondarySaleFees, HasContractURI, HasTokenURI, ERC721Enumerable {

    /**
        @notice Describes a fee.
        @param recipient - Fee recipient address.
        @param value - Fee amount in percents * 100.
    */
    struct Fee {
        address payable recipient;
        uint256 value;
    }

    // id => fees
    mapping (uint256 => Fee[]) public fees;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /**
     * @dev Constructor function
     */
    constructor (string memory _name, string memory _symbol, string memory contractURI, string memory _tokenURIPrefix)  ERC721(_name, _symbol) HasContractURI(contractURI) HasTokenURI(_tokenURIPrefix) {


        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
    }

    /**
        @notice     Get the secondary fee recipients of the token.
        @param id - The id of the token.
        @return     An array of fee recipient addresses.
    */
    function getFeeRecipients(uint256 id) public override view returns (address payable[] memory) {
        Fee[] memory _fees = fees[id];
        address payable[] memory result = new address payable[](_fees.length);
        for (uint i = 0; i < _fees.length; i++) {
            result[i] = _fees[i].recipient;
        }
        return result;
    }

    /**
        @notice     Get the secondary fee amounts of the token.
        @param id - The id of the token.
        @return     An array of fee amount values.
    */
    function getFeeBps(uint256 id) public override view returns (uint[] memory) {
        Fee[] memory _fees = fees[id];
        uint[] memory result = new uint[](_fees.length);
        for (uint i = 0; i < _fees.length; i++) {
            result[i] = _fees[i].value;
        }
        return result;
    }

    function _mint(address to, uint256 tokenId, Fee[] memory _fees) internal virtual  {
        _mint(to, tokenId);
        address[] memory recipients = new address[](_fees.length);
        uint[] memory bps = new uint[](_fees.length);
        for (uint i = 0; i < _fees.length; i++) {
            require(_fees[i].recipient != address(0x0), "Recipient should be present");
            require(_fees[i].value != 0, "Fee value should be positive");
            fees[tokenId].push(_fees[i]);
            recipients[i] = _fees[i].recipient;
            bps[i] = _fees[i].value;
        }
        if (_fees.length > 0) {
            emit SecondarySaleFees(tokenId, recipients, bps);
        }
    }

    /**
     * @dev Returns an URI for a given token ID.
     * Throws if the token ID does not exist. May return an empty string.
     * @param tokenId uint256 ID of the token to query
     */
    function tokenURI(uint256 tokenId) public override view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        return super._tokenURI(tokenId);
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to set its URI
     * @param uri string URI to assign
     */
    function _setTokenURI(uint256 tokenId, string memory uri) override internal {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        super._setTokenURI(tokenId, uri);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal override {
        super._burn(owner, tokenId);
        _clearTokenURI(tokenId);
    }
    
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC165Storage) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }
}

/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721Base {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

File 3 of 6: HasTokenURI.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./libs.sol";

contract HasTokenURI {
    using StringLibrary for string;

    //Token URI prefix
    string public tokenURIPrefix;

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

    constructor(string memory _tokenURIPrefix) {
        tokenURIPrefix = _tokenURIPrefix;
    }

    /**
     * @dev Returns an URI for a given token ID.
     * Throws if the token ID does not exist. May return an empty string.
     * @param tokenId uint256 ID of the token to query
     */
    function _tokenURI(uint256 tokenId) internal view returns (string memory) {
        return tokenURIPrefix.append(_tokenURIs[tokenId]);
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to set its URI
     * @param uri string URI to assign
     */
    function _setTokenURI(uint256 tokenId, string memory uri) internal virtual {
        _tokenURIs[tokenId] = uri;
    }

    /**
     * @dev Internal function to set the token URI prefix.
     * @param _tokenURIPrefix string URI prefix to assign
     */
    function _setTokenURIPrefix(string memory _tokenURIPrefix) internal {
        tokenURIPrefix = _tokenURIPrefix;
    }

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

File 4 of 6: libs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }


    /**
     * @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].
     *
     * _Available since v2.4.0._
     */
    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");
    }
}

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

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

    function increment(Counter storage counter) internal {
        // The {SafeMath} overflow check can be skipped here, see the comment at the top
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}

library UintLibrary {
    using SafeMath for uint;

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

    function bp(uint value, uint bpValue) internal pure returns (uint) {
        return value.mul(bpValue).div(10000);
    }
}

library StringLibrary {
    using UintLibrary for uint256;

    function append(string memory _a, string memory _b) internal pure returns (string memory) {
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
        bytes memory bab = new bytes(_ba.length + _bb.length);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++) bab[k++] = _ba[i];
        for (uint i = 0; i < _bb.length; i++) bab[k++] = _bb[i];
        return string(bab);
    }

    function append(string memory _a, string memory _b, string memory _c) internal pure returns (string memory) {
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
        bytes memory _bc = bytes(_c);
        bytes memory bbb = new bytes(_ba.length + _bb.length + _bc.length);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++) bbb[k++] = _ba[i];
        for (uint i = 0; i < _bb.length; i++) bbb[k++] = _bb[i];
        for (uint i = 0; i < _bc.length; i++) bbb[k++] = _bc[i];
        return string(bbb);
    }

    function recover(string memory message, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        bytes memory msgBytes = bytes(message);
        bytes memory fullMessage = concat(
            bytes("\x19Ethereum Signed Message:\n"),
            bytes(msgBytes.length.toString()),
            msgBytes,
            new bytes(0), new bytes(0), new bytes(0), new bytes(0)
        );
        return ecrecover(keccak256(fullMessage), v, r, s);
    }

    function concat(bytes memory _ba, bytes memory _bb, bytes memory _bc, bytes memory _bd, bytes memory _be, bytes memory _bf, bytes memory _bg) internal pure returns (bytes memory) {
        bytes memory resultBytes = new bytes(_ba.length + _bb.length + _bc.length + _bd.length + _be.length + _bf.length + _bg.length);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++) resultBytes[k++] = _ba[i];
        for (uint i = 0; i < _bb.length; i++) resultBytes[k++] = _bb[i];
        for (uint i = 0; i < _bc.length; i++) resultBytes[k++] = _bc[i];
        for (uint i = 0; i < _bd.length; i++) resultBytes[k++] = _bd[i];
        for (uint i = 0; i < _be.length; i++) resultBytes[k++] = _be[i];
        for (uint i = 0; i < _bf.length; i++) resultBytes[k++] = _bf[i];
        for (uint i = 0; i < _bg.length; i++) resultBytes[k++] = _bg[i];
        return resultBytes;
    }
}

library AddressLibrary {
    function toString(address _addr) internal pure returns (string memory) {
        uint256 i = uint256(uint160(_addr));
        bytes32 value = bytes32(i);
        bytes memory alphabet = "0123456789abcdef";
        bytes memory str = new bytes(42);
        str[0] = '0';
        str[1] = 'x';
        for (uint256 ind = 0; ind < 20; ind++) {
            str[2+ind*2] = alphabet[uint8(value[ind + 12] >> 4)];
            str[3+ind*2] = alphabet[uint8(value[ind + 12] & 0x0f)];
        }
        return string(str);
    }
}

library BytesLibrary {
    function toString(bytes32 value) internal pure returns (string memory) {
        bytes memory alphabet = "0123456789abcdef";
        bytes memory str = new bytes(64);
        for (uint256 i = 0; i < 32; i++) {
            str[i*2] = alphabet[uint8(value[i] >> 4)];
            str[1+i*2] = alphabet[uint8(value[i] & 0x0f)];
        }
        return string(str);
    }
}

library ECDSA {
    /**
     * @dev Recover signer address from a message by using their signature
     * @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address.
     * @param signature bytes signature, the signature is generated using web3.eth.sign()
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        bytes32 r;
        bytes32 s;
        uint8 v;

        // Check the signature length
        if (signature.length != 65) {
            return (address(0));
        }

        // Divide the signature in r, s and v variables
        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            r := mload(add(signature, 0x20))
            s := mload(add(signature, 0x40))
            v := byte(0, mload(add(signature, 0x60)))
        }

        // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
        if (v < 27) {
            v += 27;
        }

        // If the version is correct return the signer address
        if (v != 27 && v != 28) {
            return (address(0));
        } else {
            return ecrecover(hash, v, r, s);
        }
    }

    /**
     * toEthSignedMessageHash
     * @dev prefix a bytes32 value with "\x19Ethereum Signed Message:"
     * and hash the result
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }
}

File 5 of 6: Roles.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

/*
 * @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 GSN 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.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return payable(msg.sender);
    }

    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor ()  {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _owner;
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

/**
 * @title SignerRole
 * @dev A signer role contract.
 */
contract SignerRole is Context {
    using Roles for Roles.Role;

    event SignerAdded(address indexed account);
    event SignerRemoved(address indexed account);

    Roles.Role private _signers;

    constructor () {
        _addSigner(_msgSender());
    }

    /**
     * @dev Makes function callable only if sender is a signer.
     */
    modifier onlySigner() {
        require(isSigner(_msgSender()), "SignerRole: caller does not have the Signer role");
        _;
    }

    /**
     * @dev Checks if the address is a signer.
     */
    function isSigner(address account) public view returns (bool) {
        return _signers.has(account);
    }

    /**
     * @dev Makes the address a signer. Only other signers can add new signers.
     */
    function addSigner(address account) public virtual onlySigner {
        _addSigner(account);
    }

    /**
     * @dev Removes the address from signers. Signer can be renounced only by himself.
     */
    function renounceSigner() public {
        _removeSigner(_msgSender());
    }

    function _addSigner(address account) internal {
        _signers.add(account);
        emit SignerAdded(account);
    }

    function _removeSigner(address account) internal {
        _signers.remove(account);
        emit SignerRemoved(account);
    }
}

/**
 * @title OperatorRole
 * @dev An operator role contract.
 */
contract OperatorRole is Context {
    using Roles for Roles.Role;

    event OperatorAdded(address indexed account);
    event OperatorRemoved(address indexed account);

    Roles.Role private _operators;

    constructor () {

    }

    /**
     * @dev Makes function callable only if sender is an operator.
     */
    modifier onlyOperator() {
        require(isOperator(_msgSender()), "OperatorRole: caller does not have the Operator role");
        _;
    }

    /**
     * @dev Checks if the address is an operator.
     */
    function isOperator(address account) public view returns (bool) {
        return _operators.has(account);
    }

    function _addOperator(address account) internal {
        _operators.add(account);
        emit OperatorAdded(account);
    }

    function _removeOperator(address account) internal {
        _operators.remove(account);
        emit OperatorRemoved(account);
    }
}

/**
 * @title OwnableOperatorRole
 * @dev Allows owner to add and remove operators.
 */
contract OwnableOperatorRole is Ownable, OperatorRole {
    /**
     * @dev Makes the address an operator. Only owner can call this function.
     */
    function addOperator(address account) public onlyOwner {
        _addOperator(account);
    }

    /**
     * @dev Removes the address from operators. Only owner can call this function.
     */
    function removeOperator(address account) public onlyOwner {
        _removeOperator(account);
    }
}

contract PauserRole {
    using Roles for Roles.Role;

    event PauserAdded(address indexed account);
    event PauserRemoved(address indexed account);

    Roles.Role private _pausers;

    constructor () {
        _addPauser(msg.sender);
    }

    modifier onlyPauser() {
        require(isPauser(msg.sender));
        _;
    }

    function isPauser(address account) public view returns (bool) {
        return _pausers.has(account);
    }

    function addPauser(address account) public onlyPauser {
        _addPauser(account);
    }

    function renouncePauser() public {
        _removePauser(msg.sender);
    }

    function _addPauser(address account) internal {
        _pausers.add(account);
        emit PauserAdded(account);
    }

    function _removePauser(address account) internal {
        _pausers.remove(account);
        emit PauserRemoved(account);
    }
}

/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is PauserRole {
    event Paused(address account);
    event Unpaused(address account);

    bool private _paused;

    constructor () {
        _paused = false;
    }

    /**
     * @return true if the contract is paused, false otherwise.
     */
    function paused() public view returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     */
    modifier whenNotPaused() {
        require(!_paused);
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     */
    modifier whenPaused() {
        require(_paused);
        _;
    }

    /**
     * @dev called by the owner to pause, triggers stopped state
     */
    function pause() public onlyPauser whenNotPaused {
        _paused = true;
        emit Paused(msg.sender);
    }

    /**
     * @dev called by the owner to unpause, returns to normal state
     */
    function unpause() public onlyPauser whenPaused {
        _paused = false;
        emit Unpaused(msg.sender);
    }
}

contract MinterRole is Context {
    using Roles for Roles.Role;

    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);

    Roles.Role private _minters;
    
    constructor () {
        _addMinter(_msgSender());
    }

    /**
     * @dev Checks if the address is a signer.
     */
    function isMinter(address account) public view returns (bool) {
        return _minters.has(account);
    }

    /**
     * @dev Removes the address from Minters. Minter can be renounced only by himself.
     */
    function renounceMinter() public {
        _removeMinter(_msgSender());
    }

    function _addMinter(address account) internal {
        _minters.add(account);
        emit MinterAdded(account);
    }

    function _removeMinter(address account) internal {
        _minters.remove(account);
        emit MinterRemoved(account);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"contractURI","type":"string"},{"internalType":"string","name":"tokenURIPrefix","type":"string"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address payable","name":"_beneficiary","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"}],"name":"CreateERC721_v4","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"recipients","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"bps","type":"uint256[]"}],"name":"SecondarySaleFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"SignerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"SignerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"fees","outputs":[{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getFeeBps","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getFeeRecipients","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenId","type":"uint256[]"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"components":[{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct ERC721Base.Fee[][]","name":"_fees","type":"tuple[][]"},{"internalType":"string[]","name":"tokenURI","type":"string[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address payable","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct ERC721Base.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"string","name":"tokenURI","type":"string"}],"internalType":"struct SingleCollection.MintingBatch[]","name":"mintingBatch","type":"tuple[]"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"contractURI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"tokenURIPrefix","type":"string"}],"name":"setTokenURIPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenURIPrefix","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"}]

60806040523480156200001157600080fd5b5060405162004394380380620043948339810160408190526200003491620005bf565b8585858583838284600033600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506200009b632dde656160e21b620001f1565b8051620000b090600290602084019062000422565b50620000c363e8a3d48560e01b620001f1565b508051620000d990600390602084019062000422565b50508151620000f090600590602085019062000422565b5080516200010690600690602084019062000422565b506200011d9150635b5e139f60e01b9050620001f1565b505050506200013b62000135620001ed60201b60201c565b62000279565b6200014633620002cb565b336001600160a01b03167f565f2552ba3b09c1a27ca36ec97f816d9f12f464c3f7f145c28b527057df0ac7878760405162000183929190620006ca565b60405180910390a2620001968262000279565b620001c17fe37243f27916e395706434720b54132b80ef5cc8c56f39b0df6485e8dfb697cf620001f1565b601280546001600160a01b0319166001600160a01b039290921691909117905550620007399350505050565b3390565b6001600160e01b03198082161415620002515760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e746572666163652069640000000060448201526064015b60405180910390fd5b6001600160e01b0319166000908152600160208190526040909120805460ff19169091179055565b620002948160106200031d60201b6200159e1790919060201c565b6040516001600160a01b038216907f47d1c22a25bb3a5d4e481b9b1e6944c2eade3181a0a20b495ed61d35b5323f2490600090a250565b620002e68160116200031d60201b6200159e1790919060201c565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b6200032982826200039d565b15620003785760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015260640162000248565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60006001600160a01b038216620004025760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b606482015260840162000248565b506001600160a01b03166000908152602091909152604090205460ff1690565b8280546200043090620006fc565b90600052602060002090601f0160209004810192826200045457600085556200049f565b82601f106200046f57805160ff19168380011785556200049f565b828001600101855582156200049f579182015b828111156200049f57825182559160200191906001019062000482565b50620004ad929150620004b1565b5090565b5b80821115620004ad5760008155600101620004b2565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004fb578181015183820152602001620004e1565b838111156200050b576000848401525b50505050565b600082601f8301126200052357600080fd5b81516001600160401b0380821115620005405762000540620004c8565b604051601f8301601f19908116603f011681019082821181831017156200056b576200056b620004c8565b816040528381528660208588010111156200058557600080fd5b62000598846020830160208901620004de565b9695505050505050565b80516001600160a01b0381168114620005ba57600080fd5b919050565b60008060008060008060c08789031215620005d957600080fd5b86516001600160401b0380821115620005f157600080fd5b620005ff8a838b0162000511565b975060208901519150808211156200061657600080fd5b620006248a838b0162000511565b965060408901519150808211156200063b57600080fd5b620006498a838b0162000511565b955060608901519150808211156200066057600080fd5b506200066f89828a0162000511565b9350506200068060808801620005a2565b91506200069060a08801620005a2565b90509295509295509295565b60008151808452620006b6816020860160208601620004de565b601f01601f19169290920160200192915050565b604081526000620006df60408301856200069c565b8281036020840152620006f381856200069c565b95945050505050565b600181811c908216806200071157607f821691505b602082108114156200073357634e487b7160e01b600052602260045260246000fd5b50919050565b613c4b80620007496000396000f3fe6080604052600436106102255760003560e01c80638f32d59b11610123578063b9465edf116100ab578063e5c8b03d1161006f578063e5c8b03d14610678578063e8a3d4851461068d578063e985e9c5146106a2578063eb12d61e146106eb578063f2fde38b1461070b57600080fd5b8063b9465edf146105e3578063b9c4d9fb146105f6578063c0ac998314610623578063c87b56dd14610638578063e3c0cee51461065857600080fd5b806398650275116100f2578063986502751461054e57806399e0dd7c14610563578063a22cb46514610583578063aa271e1a146105a3578063b88d4fde146105c357600080fd5b80638f32d59b146104d9578063938e3d7b146104f957806395d89b4114610519578063983b2d561461052e57600080fd5b80633092afd5116101b15780636352211e116101755780636352211e1461044657806370a0823114610466578063715018a6146104865780637df73e271461049b5780638da5cb5b146104bb57600080fd5b80633092afd51461038757806338af3eed146103a757806342842e0e146103c75780634f6ccce7146103e75780636308f1cd1461040757600080fd5b80630e316ab7116101f85780630e316ab7146102db5780630ebd4c7f146102fb57806318160ddd1461032857806323b872dd146103475780632f745c591461036757600080fd5b806301ffc9a71461022a57806306fdde031461025f578063081812fc14610281578063095ea7b3146102b9575b600080fd5b34801561023657600080fd5b5061024a61024536600461309a565b61072b565b60405190151581526020015b60405180910390f35b34801561026b57600080fd5b50610274610771565b604051610256919061310b565b34801561028d57600080fd5b506102a161029c36600461311e565b610803565b6040516001600160a01b039091168152602001610256565b3480156102c557600080fd5b506102d96102d436600461314c565b61089d565b005b3480156102e757600080fd5b506102d96102f6366004613178565b6109b3565b34801561030757600080fd5b5061031b61031636600461311e565b6109e9565b60405161025691906131d0565b34801561033457600080fd5b50600d545b604051908152602001610256565b34801561035357600080fd5b506102d96103623660046131e3565b610b0a565b34801561037357600080fd5b5061033961038236600461314c565b610b3b565b34801561039357600080fd5b506102d96103a2366004613178565b610bd1565b3480156103b357600080fd5b506012546102a1906001600160a01b031681565b3480156103d357600080fd5b506102d96103e23660046131e3565b610c04565b3480156103f357600080fd5b5061033961040236600461311e565b610c1f565b34801561041357600080fd5b50610427610422366004613224565b610cb2565b604080516001600160a01b039093168352602083019190915201610256565b34801561045257600080fd5b506102a161046136600461311e565b610cf8565b34801561047257600080fd5b50610339610481366004613178565b610d6f565b34801561049257600080fd5b506102d9610df6565b3480156104a757600080fd5b5061024a6104b6366004613178565b610e6a565b3480156104c757600080fd5b506000546001600160a01b03166102a1565b3480156104e557600080fd5b506000546001600160a01b0316331461024a565b34801561050557600080fd5b506102d961051436600461332b565b610e77565b34801561052557600080fd5b50610274610eaa565b34801561053a57600080fd5b506102d9610549366004613178565b610eb9565b34801561055a57600080fd5b506102d9610eec565b34801561056f57600080fd5b506102d961057e36600461332b565b610ef7565b34801561058f57600080fd5b506102d961059e36600461335f565b610f2a565b3480156105af57600080fd5b5061024a6105be366004613178565b610f39565b3480156105cf57600080fd5b506102d96105de36600461339d565b610f46565b6102d96105f1366004613467565b610f7e565b34801561060257600080fd5b5061061661061136600461311e565b6111bb565b6040516102569190613530565b34801561062f57600080fd5b506102746112e1565b34801561064457600080fd5b5061027461065336600461311e565b61136f565b34801561066457600080fd5b506102d96106733660046135ec565b6113f7565b34801561068457600080fd5b506102d9611522565b34801561069957600080fd5b5061027461152b565b3480156106ae57600080fd5b5061024a6106bd366004613779565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b3480156106f757600080fd5b506102d9610706366004613178565b611538565b34801561071757600080fd5b506102d9610726366004613178565b61156b565b60006001600160e01b031982166380ac58cd60e01b148061075c57506001600160e01b03198216635b5e139f60e01b145b8061076b575061076b8261161a565b92915050565b606060058054610780906137a7565b80601f01602080910402602001604051908101604052809291908181526020018280546107ac906137a7565b80156107f95780601f106107ce576101008083540402835291602001916107f9565b820191906000526020600020905b8154815290600101906020018083116107dc57829003601f168201915b5050505050905090565b6000818152600760205260408120546001600160a01b03166108815760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600960205260409020546001600160a01b031690565b60006108a882610cf8565b9050806001600160a01b0316836001600160a01b031614156109165760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610878565b336001600160a01b0382161480610932575061093281336106bd565b6109a45760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610878565b6109ae838361165a565b505050565b6000546001600160a01b031633146109dd5760405162461bcd60e51b8152600401610878906137e2565b6109e6816116c8565b50565b6000818152600f60209081526040808320805482518185028101850190935280835260609493849084015b82821015610a5c576000848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610a14565b505050509050600081516001600160401b03811115610a7d57610a7d613246565b604051908082528060200260200182016040528015610aa6578160200160208202803683370190505b50905060005b8251811015610b0257828181518110610ac757610ac7613817565b602002602001015160200151828281518110610ae557610ae5613817565b602090810291909101015280610afa81613843565b915050610aac565b509392505050565b610b14338261170a565b610b305760405162461bcd60e51b81526004016108789061385e565b6109ae838383611801565b6000610b4683610d6f565b8210610ba85760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610878565b506001600160a01b03919091166000908152600b60209081526040808320938352929052205490565b6000546001600160a01b03163314610bfb5760405162461bcd60e51b8152600401610878906137e2565b6109e6816119ac565b6109ae83838360405180602001604052806000815250610f46565b6000610c2a600d5490565b8210610c8d5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610878565b600d8281548110610ca057610ca0613817565b90600052602060002001549050919050565b600f6020528160005260406000208181548110610cce57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b039091169250905082565b6000818152600760205260408120546001600160a01b03168061076b5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610878565b60006001600160a01b038216610dda5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610878565b506001600160a01b031660009081526008602052604090205490565b6000546001600160a01b03163314610e205760405162461bcd60e51b8152600401610878906137e2565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600061076b6010836119ee565b6000546001600160a01b03163314610ea15760405162461bcd60e51b8152600401610878906137e2565b6109e681611a71565b606060068054610780906137a7565b6000546001600160a01b03163314610ee35760405162461bcd60e51b8152600401610878906137e2565b6109e681611a84565b610ef5336119ac565b565b6000546001600160a01b03163314610f215760405162461bcd60e51b8152600401610878906137e2565b6109e681611ac6565b610f35338383611ad9565b5050565b600061076b6011836119ee565b610f50338361170a565b610f6c5760405162461bcd60e51b81526004016108789061385e565b610f7884848484611ba8565b50505050565b610f9c6104b6888888610f948e8e308a8a611bdb565b929190611c1e565b610fe85760405162461bcd60e51b815260206004820152601a60248201527f7369676e65722073686f756c64207369676e20746f6b656e49640000000000006044820152606401610878565b610ff988666a94d74f4300006138af565b34146110475760405162461bcd60e51b815260206004820152601a60248201527f286d696e742920696e636f7272656374206d73672e76616c75650000000000006044820152606401610878565b60005b88811015611175576110e9338b8b8481811061106857611068613817565b9050602002013587878581811061108157611081613817565b905060200281019061109391906138ce565b808060200260200160405190810160405280939291908181526020016000905b828210156110df576110d060408302860136819003810190613917565b815260200190600101906110b3565b5050505050611d13565b6111638a8a838181106110fe576110fe613817565b9050602002013584848481811061111757611117613817565b90506020028101906111299190613933565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ffa92505050565b8061116d81613843565b91505061104a565b506012546040516001600160a01b03909116903480156108fc02916000818181858888f193505050501580156111af573d6000803e3d6000fd5b50505050505050505050565b6000818152600f60209081526040808320805482518185028101850190935280835260609493849084015b8282101561122e576000848152602090819020604080518082019091526002850290910180546001600160a01b031682526001908101548284015290835290920191016111e6565b505050509050600081516001600160401b0381111561124f5761124f613246565b604051908082528060200260200182016040528015611278578160200160208202803683370190505b50905060005b8251811015610b025782818151811061129957611299613817565b6020026020010151600001518282815181106112b7576112b7613817565b6001600160a01b0390921660209283029190910190910152806112d981613843565b91505061127e565b600380546112ee906137a7565b80601f016020809104026020016040519081016040528092919081815260200182805461131a906137a7565b80156113675780601f1061133c57610100808354040283529160200191611367565b820191906000526020600020905b81548152906001019060200180831161134a57829003601f168201915b505050505081565b6000818152600760205260409020546060906001600160a01b03166113ee5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610878565b61076b8261207d565b6000546001600160a01b0316331480611414575061141433610f39565b61146b5760405162461bcd60e51b815260206004820152602260248201527f4f6e6c7920666f72206f776e657220616e64206d696e74657273206d696e74696044820152616e6760f01b6064820152608401610878565b60005b8151811015610f3557600082828151811061148b5761148b613817565b602002602001015160000151905060008383815181106114ad576114ad613817565b602002602001015160200151905060008484815181106114cf576114cf613817565b602002602001015160400151905060008585815181106114f1576114f1613817565b602002602001015160600151905061150b848484846121b4565b50505050808061151a90613843565b91505061146e565b610ef5336116c8565b600280546112ee906137a7565b6000546001600160a01b031633146115625760405162461bcd60e51b8152600401610878906137e2565b6109e6816121c9565b6000546001600160a01b031633146115955760405162461bcd60e51b8152600401610878906137e2565b6109e68161220b565b6115a882826119ee565b156115f55760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006044820152606401610878565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60006001600160e01b031982166380ac58cd60e01b148061164b57506001600160e01b03198216635b5e139f60e01b145b8061076b575061076b826122cb565b600081815260096020526040902080546001600160a01b0319166001600160a01b038416908117909155819061168f82610cf8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6116d3601082612307565b6040516001600160a01b038216907f3525e22824a8a7df2c9a6029941c824cf95b6447f1e13d5128fd3826d35afe8b90600090a250565b6000818152600760205260408120546001600160a01b03166117835760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610878565b600061178e83610cf8565b9050806001600160a01b0316846001600160a01b031614806117c95750836001600160a01b03166117be84610803565b6001600160a01b0316145b806117f957506001600160a01b038082166000908152600a602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661181482610cf8565b6001600160a01b03161461187c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610878565b6001600160a01b0382166118de5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610878565b6118e9838383612389565b6118f460008261165a565b6001600160a01b038316600090815260086020526040812080546001929061191d908490613979565b90915550506001600160a01b038216600090815260086020526040812080546001929061194b908490613990565b909155505060008181526007602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6119b7601182612307565b6040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b60006001600160a01b038216611a515760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b6064820152608401610878565b506001600160a01b03166000908152602091909152604090205460ff1690565b8051610f35906002906020840190612feb565b611a8f60118261159e565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b8051610f35906003906020840190612feb565b816001600160a01b0316836001600160a01b03161415611b3b5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610878565b6001600160a01b038381166000818152600a6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611bb3848484611801565b611bbf84848484612441565b610f785760405162461bcd60e51b8152600401610878906139a8565b6060611c148686868686604051602001611bf9959493929190613a23565b60405160208183030381529060405280519060200120612543565b9695505050505050565b6000808590506000611c966040518060400160405280601a81526020017f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250611c69845161269b565b60408051600080825260208201818152828401828152606084019283526080840190945288939091612798565b90506001818051906020012087878760405160008152602001604052604051611cdb949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611cfd573d6000803e3d6000fd5b5050604051601f19015198975050505050505050565b611d1d8383612b65565b600081516001600160401b03811115611d3857611d38613246565b604051908082528060200260200182016040528015611d61578160200160208202803683370190505b509050600082516001600160401b03811115611d7f57611d7f613246565b604051908082528060200260200182016040528015611da8578160200160208202803683370190505b50905060005b8351811015611faf5760006001600160a01b0316848281518110611dd457611dd4613817565b6020026020010151600001516001600160a01b03161415611e375760405162461bcd60e51b815260206004820152601b60248201527f526563697069656e742073686f756c642062652070726573656e7400000000006044820152606401610878565b838181518110611e4957611e49613817565b60200260200101516020015160001415611ea55760405162461bcd60e51b815260206004820152601c60248201527f4665652076616c75652073686f756c6420626520706f736974697665000000006044820152606401610878565b6000858152600f602052604090208451859083908110611ec757611ec7613817565b602090810291909101810151825460018082018555600094855293839020825160029092020180546001600160a01b0319166001600160a01b039092169190911781559101519101558351849082908110611f2457611f24613817565b602002602001015160000151838281518110611f4257611f42613817565b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611f7457611f74613817565b602002602001015160200151828281518110611f9257611f92613817565b602090810291909101015280611fa781613843565b915050611dae565b50825115611ff3577f99aba1d63749cfd5ad1afda7c4663840924d54eb5f005bbbeadedc6ec13674b2848383604051611fea93929190613b07565b60405180910390a15b5050505050565b6000828152600760205260409020546001600160a01b03166120735760405162461bcd60e51b815260206004820152602c60248201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610878565b610f358282612cb3565b6000818152600460205260409020805460609161076b9161209d906137a7565b80601f01602080910402602001604051908101604052809291908181526020018280546120c9906137a7565b80156121165780601f106120eb57610100808354040283529160200191612116565b820191906000526020600020905b8154815290600101906020018083116120f957829003601f168201915b505050505060038054612128906137a7565b80601f0160208091040260200160405190810160405280929190818152602001828054612154906137a7565b80156121a15780601f10612176576101008083540402835291602001916121a1565b820191906000526020600020905b81548152906001019060200180831161218457829003601f168201915b5050505050612cd290919063ffffffff16565b6121bf848484611d13565b610f788382611ffa565b6121d460108261159e565b6040516001600160a01b038216907f47d1c22a25bb3a5d4e481b9b1e6944c2eade3181a0a20b495ed61d35b5323f2490600090a250565b6001600160a01b0381166122705760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610878565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60006301ffc9a760e01b6001600160e01b03198316148061076b5750506001600160e01b03191660009081526001602052604090205460ff1690565b61231182826119ee565b6123675760405162461bcd60e51b815260206004820152602160248201527f526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c6044820152606560f81b6064820152608401610878565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6001600160a01b0383166123e4576123df81600d80546000838152600e60205260408120829055600182018355919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50155565b612407565b816001600160a01b0316836001600160a01b031614612407576124078382612e22565b6001600160a01b03821661241e576109ae81612ebf565b826001600160a01b0316826001600160a01b0316146109ae576109ae8282612f6e565b6000612455846001600160a01b0316612fb2565b1561253b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061248c903390899088908890600401613b71565b6020604051808303816000875af19250505080156124c7575060408051601f3d908101601f191682019092526124c491810190613ba4565b60015b612521573d8080156124f5576040519150601f19603f3d011682016040523d82523d6000602084013e6124fa565b606091505b5080516125195760405162461bcd60e51b8152600401610878906139a8565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506117f9565b5060016117f9565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b6020820152815182815260608181018452926000919060208201818036833701905050905060005b6020811015610b02578260048683602081106125aa576125aa613817565b1a60f81b6001600160f81b031916901c60f81c60ff16815181106125d0576125d0613817565b01602001516001600160f81b031916826125eb8360026138af565b815181106125fb576125fb613817565b60200101906001600160f81b031916908160001a9053508285826020811061262557612625613817565b825191901a600f1690811061263c5761263c613817565b01602001516001600160f81b031916826126578360026138af565b612662906001613990565b8151811061267257612672613817565b60200101906001600160f81b031916908160001a9053508061269381613843565b91505061258c565b6060816126bf5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156126e957806126d381613843565b91506126e29050600a83613bd7565b91506126c3565b6000816001600160401b0381111561270357612703613246565b6040519080825280601f01601f19166020018201604052801561272d576020820181803683370190505b5090505b84156117f957612742600183613979565b915061274f600a86613beb565b61275a906030613990565b60f81b81838151811061276f5761276f613817565b60200101906001600160f81b031916908160001a905350612791600a86613bd7565b9450612731565b6060600082518451865188518a518c518e516127b49190613990565b6127be9190613990565b6127c89190613990565b6127d29190613990565b6127dc9190613990565b6127e69190613990565b6001600160401b038111156127fd576127fd613246565b6040519080825280601f01601f191660200182016040528015612827576020820181803683370190505b5090506000805b8a5181101561289e578a818151811061284957612849613817565b01602001516001600160f81b031916838361286381613843565b94508151811061287557612875613817565b60200101906001600160f81b031916908160001a9053508061289681613843565b91505061282e565b5060005b8951811015612912578981815181106128bd576128bd613817565b01602001516001600160f81b03191683836128d781613843565b9450815181106128e9576128e9613817565b60200101906001600160f81b031916908160001a9053508061290a81613843565b9150506128a2565b5060005b88518110156129865788818151811061293157612931613817565b01602001516001600160f81b031916838361294b81613843565b94508151811061295d5761295d613817565b60200101906001600160f81b031916908160001a9053508061297e81613843565b915050612916565b5060005b87518110156129fa578781815181106129a5576129a5613817565b01602001516001600160f81b03191683836129bf81613843565b9450815181106129d1576129d1613817565b60200101906001600160f81b031916908160001a905350806129f281613843565b91505061298a565b5060005b8651811015612a6e57868181518110612a1957612a19613817565b01602001516001600160f81b0319168383612a3381613843565b945081518110612a4557612a45613817565b60200101906001600160f81b031916908160001a90535080612a6681613843565b9150506129fe565b5060005b8551811015612ae257858181518110612a8d57612a8d613817565b01602001516001600160f81b0319168383612aa781613843565b945081518110612ab957612ab9613817565b60200101906001600160f81b031916908160001a90535080612ada81613843565b915050612a72565b5060005b8451811015612b5657848181518110612b0157612b01613817565b01602001516001600160f81b0319168383612b1b81613843565b945081518110612b2d57612b2d613817565b60200101906001600160f81b031916908160001a90535080612b4e81613843565b915050612ae6565b50909998505050505050505050565b6001600160a01b038216612bbb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610878565b6000818152600760205260409020546001600160a01b031615612c205760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610878565b612c2c60008383612389565b6001600160a01b0382166000908152600860205260408120805460019290612c55908490613990565b909155505060008181526007602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600082815260046020908152604090912082516109ae92840190612feb565b8051825160609184918491600091612cea9190613990565b6001600160401b03811115612d0157612d01613246565b6040519080825280601f01601f191660200182016040528015612d2b576020820181803683370190505b5090506000805b8451811015612da257848181518110612d4d57612d4d613817565b01602001516001600160f81b0319168383612d6781613843565b945081518110612d7957612d79613817565b60200101906001600160f81b031916908160001a90535080612d9a81613843565b915050612d32565b5060005b8351811015612e1657838181518110612dc157612dc1613817565b01602001516001600160f81b0319168383612ddb81613843565b945081518110612ded57612ded613817565b60200101906001600160f81b031916908160001a90535080612e0e81613843565b915050612da6565b50909695505050505050565b60006001612e2f84610d6f565b612e399190613979565b6000838152600c6020526040902054909150808214612e8c576001600160a01b0384166000908152600b602090815260408083208584528252808320548484528184208190558352600c90915290208190555b506000918252600c602090815260408084208490556001600160a01b039094168352600b81528383209183525290812055565b600d54600090612ed190600190613979565b6000838152600e6020526040812054600d8054939450909284908110612ef957612ef9613817565b9060005260206000200154905080600d8381548110612f1a57612f1a613817565b6000918252602080832090910192909255828152600e9091526040808220849055858252812055600d805480612f5257612f52613bff565b6001900381819060005260206000200160009055905550505050565b6000612f7983610d6f565b6001600160a01b039093166000908152600b602090815260408083208684528252808320859055938252600c9052919091209190915550565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906117f9575050151592915050565b828054612ff7906137a7565b90600052602060002090601f016020900481019282613019576000855561305f565b82601f1061303257805160ff191683800117855561305f565b8280016001018555821561305f579182015b8281111561305f578251825591602001919060010190613044565b5061306b92915061306f565b5090565b5b8082111561306b5760008155600101613070565b6001600160e01b0319811681146109e657600080fd5b6000602082840312156130ac57600080fd5b81356130b781613084565b9392505050565b6000815180845260005b818110156130e4576020818501810151868301820152016130c8565b818111156130f6576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006130b760208301846130be565b60006020828403121561313057600080fd5b5035919050565b6001600160a01b03811681146109e657600080fd5b6000806040838503121561315f57600080fd5b823561316a81613137565b946020939093013593505050565b60006020828403121561318a57600080fd5b81356130b781613137565b600081518084526020808501945080840160005b838110156131c5578151875295820195908201906001016131a9565b509495945050505050565b6020815260006130b76020830184613195565b6000806000606084860312156131f857600080fd5b833561320381613137565b9250602084013561321381613137565b929592945050506040919091013590565b6000806040838503121561323757600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b038111828210171561327e5761327e613246565b60405290565b604051601f8201601f191681016001600160401b03811182821017156132ac576132ac613246565b604052919050565b60006001600160401b038311156132cd576132cd613246565b6132e0601f8401601f1916602001613284565b90508281528383830111156132f457600080fd5b828260208301376000602084830101529392505050565b600082601f83011261331c57600080fd5b6130b7838335602085016132b4565b60006020828403121561333d57600080fd5b81356001600160401b0381111561335357600080fd5b6117f98482850161330b565b6000806040838503121561337257600080fd5b823561337d81613137565b91506020830135801515811461339257600080fd5b809150509250929050565b600080600080608085870312156133b357600080fd5b84356133be81613137565b935060208501356133ce81613137565b92506040850135915060608501356001600160401b038111156133f057600080fd5b8501601f8101871361340157600080fd5b613410878235602084016132b4565b91505092959194509250565b60008083601f84011261342e57600080fd5b5081356001600160401b0381111561344557600080fd5b6020830191508360208260051b850101111561346057600080fd5b9250929050565b600080600080600080600080600060c08a8c03121561348557600080fd5b89356001600160401b038082111561349c57600080fd5b6134a88d838e0161341c565b909b50995060208c0135915060ff821682146134c357600080fd5b90975060408b0135965060608b0135955060808b013590808211156134e757600080fd5b6134f38d838e0161341c565b909650945060a08c013591508082111561350c57600080fd5b506135198c828d0161341c565b915080935050809150509295985092959850929598565b6020808252825182820181905260009190848201906040850190845b81811015612e165783516001600160a01b03168352928401929184019160010161354c565b60006001600160401b0382111561358a5761358a613246565b5060051b60200190565b6000604082840312156135a657600080fd5b604051604081018181106001600160401b03821117156135c8576135c8613246565b60405290508082356135d981613137565b8152602092830135920191909152919050565b6000602082840312156135fe57600080fd5b6001600160401b03808335111561361457600080fd5b8235830184601f82011261362757600080fd5b6136396136348235613571565b613284565b81358082526020808301929160051b8401018781111561365857600080fd5b602084015b8181101561376c57858135111561367357600080fd5b803585016080818b03601f1901121561368b57600080fd5b61369361325c565b60208201356136a181613137565b8152604082013560208201526060820135888111156136bf57600080fd5b8201603f81018c136136d057600080fd5b60208101356136e161363482613571565b81815260069190911b82016040019060208101908e83111561370257600080fd5b6040840193505b8284101561372e5761371b8f85613594565b8252602082019150604084019350613709565b604085015250505060808201358881111561374857600080fd5b6137578c60208386010161330b565b6060830152508552506020938401930161365d565b5090979650505050505050565b6000806040838503121561378c57600080fd5b823561379781613137565b9150602083013561339281613137565b600181811c908216806137bb57607f821691505b602082108114156137dc57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156138575761385761382d565b5060010190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008160001904831182151516156138c9576138c961382d565b500290565b6000808335601e198436030181126138e557600080fd5b8301803591506001600160401b038211156138ff57600080fd5b6020019150600681901b360382131561346057600080fd5b60006040828403121561392957600080fd5b6130b78383613594565b6000808335601e1984360301811261394a57600080fd5b8301803591506001600160401b0382111561396457600080fd5b60200191503681900382131561346057600080fd5b60008282101561398b5761398b61382d565b500390565b600082198211156139a3576139a361382d565b500190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060808252810185905260006001600160fb1b03861115613a4357600080fd5b8560051b808860808501376001600160a01b03861660208481019190915260809184018481038301604086015291820185905260a0600586901b8301810191600091840188835b89811015613af557868603609f190183528135368c9003601e19018112613aaf578586fd5b8b0180356001600160401b03811115613ac6578687fd5b8036038d1315613ad4578687fd5b613ae188828885016139fa565b975050509183019190830190600101613a8a565b50939c9b505050505050505050505050565b6000606082018583526020606081850152818651808452608086019150828801935060005b81811015613b515784516001600160a01b031683529383019391830191600101613b2c565b50508481036040860152613b658187613195565b98975050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611c14908301846130be565b600060208284031215613bb657600080fd5b81516130b781613084565b634e487b7160e01b600052601260045260246000fd5b600082613be657613be6613bc1565b500490565b600082613bfa57613bfa613bc1565b500690565b634e487b7160e01b600052603160045260246000fdfea264697066735822122045a45571550e7d05524d48868077d6ec4776ed636c604688904ccd06ac4ab99764736f6c634300080b003300000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000d3fe775d09c4ea2b3e36efac3c34e97d66f38868000000000000000000000000db3848c14bc8dc83c1184a74c579cc547e454aa9000000000000000000000000000000000000000000000000000000000000000f466c756666792050756e6b4361747300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003465043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014687474703a2f2f697066732e696f2f697066732f000000000000000000000000

Deployed Bytecode

0x6080604052600436106102255760003560e01c80638f32d59b11610123578063b9465edf116100ab578063e5c8b03d1161006f578063e5c8b03d14610678578063e8a3d4851461068d578063e985e9c5146106a2578063eb12d61e146106eb578063f2fde38b1461070b57600080fd5b8063b9465edf146105e3578063b9c4d9fb146105f6578063c0ac998314610623578063c87b56dd14610638578063e3c0cee51461065857600080fd5b806398650275116100f2578063986502751461054e57806399e0dd7c14610563578063a22cb46514610583578063aa271e1a146105a3578063b88d4fde146105c357600080fd5b80638f32d59b146104d9578063938e3d7b146104f957806395d89b4114610519578063983b2d561461052e57600080fd5b80633092afd5116101b15780636352211e116101755780636352211e1461044657806370a0823114610466578063715018a6146104865780637df73e271461049b5780638da5cb5b146104bb57600080fd5b80633092afd51461038757806338af3eed146103a757806342842e0e146103c75780634f6ccce7146103e75780636308f1cd1461040757600080fd5b80630e316ab7116101f85780630e316ab7146102db5780630ebd4c7f146102fb57806318160ddd1461032857806323b872dd146103475780632f745c591461036757600080fd5b806301ffc9a71461022a57806306fdde031461025f578063081812fc14610281578063095ea7b3146102b9575b600080fd5b34801561023657600080fd5b5061024a61024536600461309a565b61072b565b60405190151581526020015b60405180910390f35b34801561026b57600080fd5b50610274610771565b604051610256919061310b565b34801561028d57600080fd5b506102a161029c36600461311e565b610803565b6040516001600160a01b039091168152602001610256565b3480156102c557600080fd5b506102d96102d436600461314c565b61089d565b005b3480156102e757600080fd5b506102d96102f6366004613178565b6109b3565b34801561030757600080fd5b5061031b61031636600461311e565b6109e9565b60405161025691906131d0565b34801561033457600080fd5b50600d545b604051908152602001610256565b34801561035357600080fd5b506102d96103623660046131e3565b610b0a565b34801561037357600080fd5b5061033961038236600461314c565b610b3b565b34801561039357600080fd5b506102d96103a2366004613178565b610bd1565b3480156103b357600080fd5b506012546102a1906001600160a01b031681565b3480156103d357600080fd5b506102d96103e23660046131e3565b610c04565b3480156103f357600080fd5b5061033961040236600461311e565b610c1f565b34801561041357600080fd5b50610427610422366004613224565b610cb2565b604080516001600160a01b039093168352602083019190915201610256565b34801561045257600080fd5b506102a161046136600461311e565b610cf8565b34801561047257600080fd5b50610339610481366004613178565b610d6f565b34801561049257600080fd5b506102d9610df6565b3480156104a757600080fd5b5061024a6104b6366004613178565b610e6a565b3480156104c757600080fd5b506000546001600160a01b03166102a1565b3480156104e557600080fd5b506000546001600160a01b0316331461024a565b34801561050557600080fd5b506102d961051436600461332b565b610e77565b34801561052557600080fd5b50610274610eaa565b34801561053a57600080fd5b506102d9610549366004613178565b610eb9565b34801561055a57600080fd5b506102d9610eec565b34801561056f57600080fd5b506102d961057e36600461332b565b610ef7565b34801561058f57600080fd5b506102d961059e36600461335f565b610f2a565b3480156105af57600080fd5b5061024a6105be366004613178565b610f39565b3480156105cf57600080fd5b506102d96105de36600461339d565b610f46565b6102d96105f1366004613467565b610f7e565b34801561060257600080fd5b5061061661061136600461311e565b6111bb565b6040516102569190613530565b34801561062f57600080fd5b506102746112e1565b34801561064457600080fd5b5061027461065336600461311e565b61136f565b34801561066457600080fd5b506102d96106733660046135ec565b6113f7565b34801561068457600080fd5b506102d9611522565b34801561069957600080fd5b5061027461152b565b3480156106ae57600080fd5b5061024a6106bd366004613779565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b3480156106f757600080fd5b506102d9610706366004613178565b611538565b34801561071757600080fd5b506102d9610726366004613178565b61156b565b60006001600160e01b031982166380ac58cd60e01b148061075c57506001600160e01b03198216635b5e139f60e01b145b8061076b575061076b8261161a565b92915050565b606060058054610780906137a7565b80601f01602080910402602001604051908101604052809291908181526020018280546107ac906137a7565b80156107f95780601f106107ce576101008083540402835291602001916107f9565b820191906000526020600020905b8154815290600101906020018083116107dc57829003601f168201915b5050505050905090565b6000818152600760205260408120546001600160a01b03166108815760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600960205260409020546001600160a01b031690565b60006108a882610cf8565b9050806001600160a01b0316836001600160a01b031614156109165760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610878565b336001600160a01b0382161480610932575061093281336106bd565b6109a45760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610878565b6109ae838361165a565b505050565b6000546001600160a01b031633146109dd5760405162461bcd60e51b8152600401610878906137e2565b6109e6816116c8565b50565b6000818152600f60209081526040808320805482518185028101850190935280835260609493849084015b82821015610a5c576000848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610a14565b505050509050600081516001600160401b03811115610a7d57610a7d613246565b604051908082528060200260200182016040528015610aa6578160200160208202803683370190505b50905060005b8251811015610b0257828181518110610ac757610ac7613817565b602002602001015160200151828281518110610ae557610ae5613817565b602090810291909101015280610afa81613843565b915050610aac565b509392505050565b610b14338261170a565b610b305760405162461bcd60e51b81526004016108789061385e565b6109ae838383611801565b6000610b4683610d6f565b8210610ba85760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610878565b506001600160a01b03919091166000908152600b60209081526040808320938352929052205490565b6000546001600160a01b03163314610bfb5760405162461bcd60e51b8152600401610878906137e2565b6109e6816119ac565b6109ae83838360405180602001604052806000815250610f46565b6000610c2a600d5490565b8210610c8d5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610878565b600d8281548110610ca057610ca0613817565b90600052602060002001549050919050565b600f6020528160005260406000208181548110610cce57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b039091169250905082565b6000818152600760205260408120546001600160a01b03168061076b5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610878565b60006001600160a01b038216610dda5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610878565b506001600160a01b031660009081526008602052604090205490565b6000546001600160a01b03163314610e205760405162461bcd60e51b8152600401610878906137e2565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600061076b6010836119ee565b6000546001600160a01b03163314610ea15760405162461bcd60e51b8152600401610878906137e2565b6109e681611a71565b606060068054610780906137a7565b6000546001600160a01b03163314610ee35760405162461bcd60e51b8152600401610878906137e2565b6109e681611a84565b610ef5336119ac565b565b6000546001600160a01b03163314610f215760405162461bcd60e51b8152600401610878906137e2565b6109e681611ac6565b610f35338383611ad9565b5050565b600061076b6011836119ee565b610f50338361170a565b610f6c5760405162461bcd60e51b81526004016108789061385e565b610f7884848484611ba8565b50505050565b610f9c6104b6888888610f948e8e308a8a611bdb565b929190611c1e565b610fe85760405162461bcd60e51b815260206004820152601a60248201527f7369676e65722073686f756c64207369676e20746f6b656e49640000000000006044820152606401610878565b610ff988666a94d74f4300006138af565b34146110475760405162461bcd60e51b815260206004820152601a60248201527f286d696e742920696e636f7272656374206d73672e76616c75650000000000006044820152606401610878565b60005b88811015611175576110e9338b8b8481811061106857611068613817565b9050602002013587878581811061108157611081613817565b905060200281019061109391906138ce565b808060200260200160405190810160405280939291908181526020016000905b828210156110df576110d060408302860136819003810190613917565b815260200190600101906110b3565b5050505050611d13565b6111638a8a838181106110fe576110fe613817565b9050602002013584848481811061111757611117613817565b90506020028101906111299190613933565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ffa92505050565b8061116d81613843565b91505061104a565b506012546040516001600160a01b03909116903480156108fc02916000818181858888f193505050501580156111af573d6000803e3d6000fd5b50505050505050505050565b6000818152600f60209081526040808320805482518185028101850190935280835260609493849084015b8282101561122e576000848152602090819020604080518082019091526002850290910180546001600160a01b031682526001908101548284015290835290920191016111e6565b505050509050600081516001600160401b0381111561124f5761124f613246565b604051908082528060200260200182016040528015611278578160200160208202803683370190505b50905060005b8251811015610b025782818151811061129957611299613817565b6020026020010151600001518282815181106112b7576112b7613817565b6001600160a01b0390921660209283029190910190910152806112d981613843565b91505061127e565b600380546112ee906137a7565b80601f016020809104026020016040519081016040528092919081815260200182805461131a906137a7565b80156113675780601f1061133c57610100808354040283529160200191611367565b820191906000526020600020905b81548152906001019060200180831161134a57829003601f168201915b505050505081565b6000818152600760205260409020546060906001600160a01b03166113ee5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610878565b61076b8261207d565b6000546001600160a01b0316331480611414575061141433610f39565b61146b5760405162461bcd60e51b815260206004820152602260248201527f4f6e6c7920666f72206f776e657220616e64206d696e74657273206d696e74696044820152616e6760f01b6064820152608401610878565b60005b8151811015610f3557600082828151811061148b5761148b613817565b602002602001015160000151905060008383815181106114ad576114ad613817565b602002602001015160200151905060008484815181106114cf576114cf613817565b602002602001015160400151905060008585815181106114f1576114f1613817565b602002602001015160600151905061150b848484846121b4565b50505050808061151a90613843565b91505061146e565b610ef5336116c8565b600280546112ee906137a7565b6000546001600160a01b031633146115625760405162461bcd60e51b8152600401610878906137e2565b6109e6816121c9565b6000546001600160a01b031633146115955760405162461bcd60e51b8152600401610878906137e2565b6109e68161220b565b6115a882826119ee565b156115f55760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006044820152606401610878565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60006001600160e01b031982166380ac58cd60e01b148061164b57506001600160e01b03198216635b5e139f60e01b145b8061076b575061076b826122cb565b600081815260096020526040902080546001600160a01b0319166001600160a01b038416908117909155819061168f82610cf8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6116d3601082612307565b6040516001600160a01b038216907f3525e22824a8a7df2c9a6029941c824cf95b6447f1e13d5128fd3826d35afe8b90600090a250565b6000818152600760205260408120546001600160a01b03166117835760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610878565b600061178e83610cf8565b9050806001600160a01b0316846001600160a01b031614806117c95750836001600160a01b03166117be84610803565b6001600160a01b0316145b806117f957506001600160a01b038082166000908152600a602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661181482610cf8565b6001600160a01b03161461187c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610878565b6001600160a01b0382166118de5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610878565b6118e9838383612389565b6118f460008261165a565b6001600160a01b038316600090815260086020526040812080546001929061191d908490613979565b90915550506001600160a01b038216600090815260086020526040812080546001929061194b908490613990565b909155505060008181526007602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6119b7601182612307565b6040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b60006001600160a01b038216611a515760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b6064820152608401610878565b506001600160a01b03166000908152602091909152604090205460ff1690565b8051610f35906002906020840190612feb565b611a8f60118261159e565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b8051610f35906003906020840190612feb565b816001600160a01b0316836001600160a01b03161415611b3b5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610878565b6001600160a01b038381166000818152600a6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611bb3848484611801565b611bbf84848484612441565b610f785760405162461bcd60e51b8152600401610878906139a8565b6060611c148686868686604051602001611bf9959493929190613a23565b60405160208183030381529060405280519060200120612543565b9695505050505050565b6000808590506000611c966040518060400160405280601a81526020017f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250611c69845161269b565b60408051600080825260208201818152828401828152606084019283526080840190945288939091612798565b90506001818051906020012087878760405160008152602001604052604051611cdb949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611cfd573d6000803e3d6000fd5b5050604051601f19015198975050505050505050565b611d1d8383612b65565b600081516001600160401b03811115611d3857611d38613246565b604051908082528060200260200182016040528015611d61578160200160208202803683370190505b509050600082516001600160401b03811115611d7f57611d7f613246565b604051908082528060200260200182016040528015611da8578160200160208202803683370190505b50905060005b8351811015611faf5760006001600160a01b0316848281518110611dd457611dd4613817565b6020026020010151600001516001600160a01b03161415611e375760405162461bcd60e51b815260206004820152601b60248201527f526563697069656e742073686f756c642062652070726573656e7400000000006044820152606401610878565b838181518110611e4957611e49613817565b60200260200101516020015160001415611ea55760405162461bcd60e51b815260206004820152601c60248201527f4665652076616c75652073686f756c6420626520706f736974697665000000006044820152606401610878565b6000858152600f602052604090208451859083908110611ec757611ec7613817565b602090810291909101810151825460018082018555600094855293839020825160029092020180546001600160a01b0319166001600160a01b039092169190911781559101519101558351849082908110611f2457611f24613817565b602002602001015160000151838281518110611f4257611f42613817565b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611f7457611f74613817565b602002602001015160200151828281518110611f9257611f92613817565b602090810291909101015280611fa781613843565b915050611dae565b50825115611ff3577f99aba1d63749cfd5ad1afda7c4663840924d54eb5f005bbbeadedc6ec13674b2848383604051611fea93929190613b07565b60405180910390a15b5050505050565b6000828152600760205260409020546001600160a01b03166120735760405162461bcd60e51b815260206004820152602c60248201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610878565b610f358282612cb3565b6000818152600460205260409020805460609161076b9161209d906137a7565b80601f01602080910402602001604051908101604052809291908181526020018280546120c9906137a7565b80156121165780601f106120eb57610100808354040283529160200191612116565b820191906000526020600020905b8154815290600101906020018083116120f957829003601f168201915b505050505060038054612128906137a7565b80601f0160208091040260200160405190810160405280929190818152602001828054612154906137a7565b80156121a15780601f10612176576101008083540402835291602001916121a1565b820191906000526020600020905b81548152906001019060200180831161218457829003601f168201915b5050505050612cd290919063ffffffff16565b6121bf848484611d13565b610f788382611ffa565b6121d460108261159e565b6040516001600160a01b038216907f47d1c22a25bb3a5d4e481b9b1e6944c2eade3181a0a20b495ed61d35b5323f2490600090a250565b6001600160a01b0381166122705760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610878565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60006301ffc9a760e01b6001600160e01b03198316148061076b5750506001600160e01b03191660009081526001602052604090205460ff1690565b61231182826119ee565b6123675760405162461bcd60e51b815260206004820152602160248201527f526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c6044820152606560f81b6064820152608401610878565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6001600160a01b0383166123e4576123df81600d80546000838152600e60205260408120829055600182018355919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50155565b612407565b816001600160a01b0316836001600160a01b031614612407576124078382612e22565b6001600160a01b03821661241e576109ae81612ebf565b826001600160a01b0316826001600160a01b0316146109ae576109ae8282612f6e565b6000612455846001600160a01b0316612fb2565b1561253b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061248c903390899088908890600401613b71565b6020604051808303816000875af19250505080156124c7575060408051601f3d908101601f191682019092526124c491810190613ba4565b60015b612521573d8080156124f5576040519150601f19603f3d011682016040523d82523d6000602084013e6124fa565b606091505b5080516125195760405162461bcd60e51b8152600401610878906139a8565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506117f9565b5060016117f9565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b6020820152815182815260608181018452926000919060208201818036833701905050905060005b6020811015610b02578260048683602081106125aa576125aa613817565b1a60f81b6001600160f81b031916901c60f81c60ff16815181106125d0576125d0613817565b01602001516001600160f81b031916826125eb8360026138af565b815181106125fb576125fb613817565b60200101906001600160f81b031916908160001a9053508285826020811061262557612625613817565b825191901a600f1690811061263c5761263c613817565b01602001516001600160f81b031916826126578360026138af565b612662906001613990565b8151811061267257612672613817565b60200101906001600160f81b031916908160001a9053508061269381613843565b91505061258c565b6060816126bf5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156126e957806126d381613843565b91506126e29050600a83613bd7565b91506126c3565b6000816001600160401b0381111561270357612703613246565b6040519080825280601f01601f19166020018201604052801561272d576020820181803683370190505b5090505b84156117f957612742600183613979565b915061274f600a86613beb565b61275a906030613990565b60f81b81838151811061276f5761276f613817565b60200101906001600160f81b031916908160001a905350612791600a86613bd7565b9450612731565b6060600082518451865188518a518c518e516127b49190613990565b6127be9190613990565b6127c89190613990565b6127d29190613990565b6127dc9190613990565b6127e69190613990565b6001600160401b038111156127fd576127fd613246565b6040519080825280601f01601f191660200182016040528015612827576020820181803683370190505b5090506000805b8a5181101561289e578a818151811061284957612849613817565b01602001516001600160f81b031916838361286381613843565b94508151811061287557612875613817565b60200101906001600160f81b031916908160001a9053508061289681613843565b91505061282e565b5060005b8951811015612912578981815181106128bd576128bd613817565b01602001516001600160f81b03191683836128d781613843565b9450815181106128e9576128e9613817565b60200101906001600160f81b031916908160001a9053508061290a81613843565b9150506128a2565b5060005b88518110156129865788818151811061293157612931613817565b01602001516001600160f81b031916838361294b81613843565b94508151811061295d5761295d613817565b60200101906001600160f81b031916908160001a9053508061297e81613843565b915050612916565b5060005b87518110156129fa578781815181106129a5576129a5613817565b01602001516001600160f81b03191683836129bf81613843565b9450815181106129d1576129d1613817565b60200101906001600160f81b031916908160001a905350806129f281613843565b91505061298a565b5060005b8651811015612a6e57868181518110612a1957612a19613817565b01602001516001600160f81b0319168383612a3381613843565b945081518110612a4557612a45613817565b60200101906001600160f81b031916908160001a90535080612a6681613843565b9150506129fe565b5060005b8551811015612ae257858181518110612a8d57612a8d613817565b01602001516001600160f81b0319168383612aa781613843565b945081518110612ab957612ab9613817565b60200101906001600160f81b031916908160001a90535080612ada81613843565b915050612a72565b5060005b8451811015612b5657848181518110612b0157612b01613817565b01602001516001600160f81b0319168383612b1b81613843565b945081518110612b2d57612b2d613817565b60200101906001600160f81b031916908160001a90535080612b4e81613843565b915050612ae6565b50909998505050505050505050565b6001600160a01b038216612bbb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610878565b6000818152600760205260409020546001600160a01b031615612c205760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610878565b612c2c60008383612389565b6001600160a01b0382166000908152600860205260408120805460019290612c55908490613990565b909155505060008181526007602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600082815260046020908152604090912082516109ae92840190612feb565b8051825160609184918491600091612cea9190613990565b6001600160401b03811115612d0157612d01613246565b6040519080825280601f01601f191660200182016040528015612d2b576020820181803683370190505b5090506000805b8451811015612da257848181518110612d4d57612d4d613817565b01602001516001600160f81b0319168383612d6781613843565b945081518110612d7957612d79613817565b60200101906001600160f81b031916908160001a90535080612d9a81613843565b915050612d32565b5060005b8351811015612e1657838181518110612dc157612dc1613817565b01602001516001600160f81b0319168383612ddb81613843565b945081518110612ded57612ded613817565b60200101906001600160f81b031916908160001a90535080612e0e81613843565b915050612da6565b50909695505050505050565b60006001612e2f84610d6f565b612e399190613979565b6000838152600c6020526040902054909150808214612e8c576001600160a01b0384166000908152600b602090815260408083208584528252808320548484528184208190558352600c90915290208190555b506000918252600c602090815260408084208490556001600160a01b039094168352600b81528383209183525290812055565b600d54600090612ed190600190613979565b6000838152600e6020526040812054600d8054939450909284908110612ef957612ef9613817565b9060005260206000200154905080600d8381548110612f1a57612f1a613817565b6000918252602080832090910192909255828152600e9091526040808220849055858252812055600d805480612f5257612f52613bff565b6001900381819060005260206000200160009055905550505050565b6000612f7983610d6f565b6001600160a01b039093166000908152600b602090815260408083208684528252808320859055938252600c9052919091209190915550565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906117f9575050151592915050565b828054612ff7906137a7565b90600052602060002090601f016020900481019282613019576000855561305f565b82601f1061303257805160ff191683800117855561305f565b8280016001018555821561305f579182015b8281111561305f578251825591602001919060010190613044565b5061306b92915061306f565b5090565b5b8082111561306b5760008155600101613070565b6001600160e01b0319811681146109e657600080fd5b6000602082840312156130ac57600080fd5b81356130b781613084565b9392505050565b6000815180845260005b818110156130e4576020818501810151868301820152016130c8565b818111156130f6576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006130b760208301846130be565b60006020828403121561313057600080fd5b5035919050565b6001600160a01b03811681146109e657600080fd5b6000806040838503121561315f57600080fd5b823561316a81613137565b946020939093013593505050565b60006020828403121561318a57600080fd5b81356130b781613137565b600081518084526020808501945080840160005b838110156131c5578151875295820195908201906001016131a9565b509495945050505050565b6020815260006130b76020830184613195565b6000806000606084860312156131f857600080fd5b833561320381613137565b9250602084013561321381613137565b929592945050506040919091013590565b6000806040838503121561323757600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b038111828210171561327e5761327e613246565b60405290565b604051601f8201601f191681016001600160401b03811182821017156132ac576132ac613246565b604052919050565b60006001600160401b038311156132cd576132cd613246565b6132e0601f8401601f1916602001613284565b90508281528383830111156132f457600080fd5b828260208301376000602084830101529392505050565b600082601f83011261331c57600080fd5b6130b7838335602085016132b4565b60006020828403121561333d57600080fd5b81356001600160401b0381111561335357600080fd5b6117f98482850161330b565b6000806040838503121561337257600080fd5b823561337d81613137565b91506020830135801515811461339257600080fd5b809150509250929050565b600080600080608085870312156133b357600080fd5b84356133be81613137565b935060208501356133ce81613137565b92506040850135915060608501356001600160401b038111156133f057600080fd5b8501601f8101871361340157600080fd5b613410878235602084016132b4565b91505092959194509250565b60008083601f84011261342e57600080fd5b5081356001600160401b0381111561344557600080fd5b6020830191508360208260051b850101111561346057600080fd5b9250929050565b600080600080600080600080600060c08a8c03121561348557600080fd5b89356001600160401b038082111561349c57600080fd5b6134a88d838e0161341c565b909b50995060208c0135915060ff821682146134c357600080fd5b90975060408b0135965060608b0135955060808b013590808211156134e757600080fd5b6134f38d838e0161341c565b909650945060a08c013591508082111561350c57600080fd5b506135198c828d0161341c565b915080935050809150509295985092959850929598565b6020808252825182820181905260009190848201906040850190845b81811015612e165783516001600160a01b03168352928401929184019160010161354c565b60006001600160401b0382111561358a5761358a613246565b5060051b60200190565b6000604082840312156135a657600080fd5b604051604081018181106001600160401b03821117156135c8576135c8613246565b60405290508082356135d981613137565b8152602092830135920191909152919050565b6000602082840312156135fe57600080fd5b6001600160401b03808335111561361457600080fd5b8235830184601f82011261362757600080fd5b6136396136348235613571565b613284565b81358082526020808301929160051b8401018781111561365857600080fd5b602084015b8181101561376c57858135111561367357600080fd5b803585016080818b03601f1901121561368b57600080fd5b61369361325c565b60208201356136a181613137565b8152604082013560208201526060820135888111156136bf57600080fd5b8201603f81018c136136d057600080fd5b60208101356136e161363482613571565b81815260069190911b82016040019060208101908e83111561370257600080fd5b6040840193505b8284101561372e5761371b8f85613594565b8252602082019150604084019350613709565b604085015250505060808201358881111561374857600080fd5b6137578c60208386010161330b565b6060830152508552506020938401930161365d565b5090979650505050505050565b6000806040838503121561378c57600080fd5b823561379781613137565b9150602083013561339281613137565b600181811c908216806137bb57607f821691505b602082108114156137dc57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156138575761385761382d565b5060010190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008160001904831182151516156138c9576138c961382d565b500290565b6000808335601e198436030181126138e557600080fd5b8301803591506001600160401b038211156138ff57600080fd5b6020019150600681901b360382131561346057600080fd5b60006040828403121561392957600080fd5b6130b78383613594565b6000808335601e1984360301811261394a57600080fd5b8301803591506001600160401b0382111561396457600080fd5b60200191503681900382131561346057600080fd5b60008282101561398b5761398b61382d565b500390565b600082198211156139a3576139a361382d565b500190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060808252810185905260006001600160fb1b03861115613a4357600080fd5b8560051b808860808501376001600160a01b03861660208481019190915260809184018481038301604086015291820185905260a0600586901b8301810191600091840188835b89811015613af557868603609f190183528135368c9003601e19018112613aaf578586fd5b8b0180356001600160401b03811115613ac6578687fd5b8036038d1315613ad4578687fd5b613ae188828885016139fa565b975050509183019190830190600101613a8a565b50939c9b505050505050505050505050565b6000606082018583526020606081850152818651808452608086019150828801935060005b81811015613b515784516001600160a01b031683529383019391830191600101613b2c565b50508481036040860152613b658187613195565b98975050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611c14908301846130be565b600060208284031215613bb657600080fd5b81516130b781613084565b634e487b7160e01b600052601260045260246000fd5b600082613be657613be6613bc1565b500490565b600082613bfa57613bfa613bc1565b500690565b634e487b7160e01b600052603160045260246000fdfea264697066735822122045a45571550e7d05524d48868077d6ec4776ed636c604688904ccd06ac4ab99764736f6c634300080b0033

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

00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000d3fe775d09c4ea2b3e36efac3c34e97d66f38868000000000000000000000000db3848c14bc8dc83c1184a74c579cc547e454aa9000000000000000000000000000000000000000000000000000000000000000f466c756666792050756e6b4361747300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003465043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014687474703a2f2f697066732e696f2f697066732f000000000000000000000000

-----Decoded View---------------
Arg [0] : name (string): Fluffy PunkCats
Arg [1] : symbol (string): FPC
Arg [2] : contractURI (string):
Arg [3] : tokenURIPrefix (string): http://ipfs.io/ipfs/
Arg [4] : signer (address): 0xd3Fe775D09C4ea2b3E36EfAC3C34e97D66f38868
Arg [5] : _beneficiary (address): 0xDB3848C14bC8dc83c1184a74C579cc547e454Aa9

-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [4] : 000000000000000000000000d3fe775d09c4ea2b3e36efac3c34e97d66f38868
Arg [5] : 000000000000000000000000db3848c14bc8dc83c1184a74c579cc547e454aa9
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [7] : 466c756666792050756e6b436174730000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [9] : 4650430000000000000000000000000000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [12] : 687474703a2f2f697066732e696f2f697066732f000000000000000000000000


Deployed Bytecode Sourcemap

240:5341:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32435:311:1;;;;;;;;;;-1:-1:-1;32435:311:1;;;;;:::i;:::-;;:::i;:::-;;;565:14:6;;558:22;540:41;;528:2;513:18;32435:311:1;;;;;;;;8603:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;10162:221::-;;;;;;;;;;-1:-1:-1;10162:221:1;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1643:32:6;;;1625:51;;1613:2;1598:18;10162:221:1;1479:203:6;9685:411:1;;;;;;;;;;-1:-1:-1;9685:411:1;;;;;:::i;:::-;;:::i;:::-;;4898:97:4;;;;;;;;;;-1:-1:-1;4898:97:4;;;;;:::i;:::-;;:::i;30072:309:1:-;;;;;;;;;;-1:-1:-1;30072:309:1;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;22379:113::-;;;;;;;;;;-1:-1:-1;22467:10:1;:17;22379:113;;;3247:25:6;;;3235:2;3220:18;22379:113:1;3101:177:6;10912:339:1;;;;;;;;;;-1:-1:-1;10912:339:1;;;;;:::i;:::-;;:::i;22047:256::-;;;;;;;;;;-1:-1:-1;22047:256:1;;;;;:::i;:::-;;:::i;5482:96:4:-;;;;;;;;;;-1:-1:-1;5482:96:4;;;;;:::i;:::-;;:::i;659:34::-;;;;;;;;;;-1:-1:-1;659:34:4;;;;-1:-1:-1;;;;;659:34:4;;;11322:185:1;;;;;;;;;;-1:-1:-1;11322:185:1;;;;;:::i;:::-;;:::i;22569:233::-;;;;;;;;;;-1:-1:-1;22569:233:1;;;;;:::i;:::-;;:::i;28556:38::-;;;;;;;;;;-1:-1:-1;28556:38:1;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4429:32:6;;;4411:51;;4493:2;4478:18;;4471:34;;;;4384:18;28556:38:1;4221:290:6;8297:239:1;;;;;;;;;;-1:-1:-1;8297:239:1;;;;;:::i;:::-;;:::i;8027:208::-;;;;;;;;;;-1:-1:-1;8027:208:1;;;;;:::i;:::-;;:::i;3846:140:3:-;;;;;;;;;;;;;:::i;5227:109::-;;;;;;;;;;-1:-1:-1;5227:109:3;;;;;:::i;:::-;;:::i;3035:79::-;;;;;;;;;;-1:-1:-1;3073:7:3;3100:6;-1:-1:-1;;;;;3100:6:3;3035:79;;3401:94;;;;;;;;;;-1:-1:-1;3441:4:3;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3401:94;;5252:115:4;;;;;;;;;;-1:-1:-1;5252:115:4;;;;;:::i;:::-;;:::i;8772:104:1:-;;;;;;;;;;;;;:::i;5379:91:4:-;;;;;;;;;;-1:-1:-1;5379:91:4;;;;;:::i;:::-;;:::i;10369:79:3:-;;;;;;;;;;;;;:::i;5058:127:4:-;;;;;;;;;;-1:-1:-1;5058:127:4;;;;;:::i;:::-;;:::i;10455:155:1:-;;;;;;;;;;-1:-1:-1;10455:155:1;;;;;:::i;:::-;;:::i;10146:109:3:-;;;;;;;;;;-1:-1:-1;10146:109:3;;;;;:::i;:::-;;:::i;11578:328:1:-;;;;;;;;;;-1:-1:-1;11578:328:1;;;;;:::i;:::-;;:::i;2814:560:4:-;;;;;;:::i;:::-;;:::i;29535:353:1:-;;;;;;;;;;-1:-1:-1;29535:353:1;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;175:28:2:-;;;;;;;;;;;;;:::i;31301:217:1:-;;;;;;;;;;-1:-1:-1;31301:217:1;;;;;:::i;:::-;;:::i;3386:530:4:-;;;;;;;;;;-1:-1:-1;3386:530:4;;;;;:::i;:::-;;:::i;5657:79:3:-;;;;;;;;;;;;;:::i;2983:25:0:-;;;;;;;;;;;;;:::i;10681:164:1:-;;;;;;;;;;-1:-1:-1;10681:164:1;;;;;:::i;:::-;-1:-1:-1;;;;;10802:25:1;;;10778:4;10802:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;10681:164;4617:100:4;;;;;;;;;;-1:-1:-1;4617:100:4;;;;;:::i;:::-;;:::i;4141:109:3:-;;;;;;;;;;-1:-1:-1;4141:109:3;;;;;:::i;:::-;;:::i;32435:311:1:-;32543:4;-1:-1:-1;;;;;;32580:40:1;;-1:-1:-1;;;32580:40:1;;:105;;-1:-1:-1;;;;;;;32637:48:1;;-1:-1:-1;;;32637:48:1;32580:105;:158;;;;32702:36;32726:11;32702:23;:36::i;:::-;32560:178;32435:311;-1:-1:-1;;32435:311:1:o;8603:100::-;8657:13;8690:5;8683:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8603:100;:::o;10162:221::-;10238:7;13505:16;;;:7;:16;;;;;;-1:-1:-1;;;;;13505:16:1;10258:73;;;;-1:-1:-1;;;10258:73:1;;13988:2:6;10258:73:1;;;13970:21:6;14027:2;14007:18;;;14000:30;14066:34;14046:18;;;14039:62;-1:-1:-1;;;14117:18:6;;;14110:42;14169:19;;10258:73:1;;;;;;;;;-1:-1:-1;10351:24:1;;;;:15;:24;;;;;;-1:-1:-1;;;;;10351:24:1;;10162:221::o;9685:411::-;9766:13;9782:23;9797:7;9782:14;:23::i;:::-;9766:39;;9830:5;-1:-1:-1;;;;;9824:11:1;:2;-1:-1:-1;;;;;9824:11:1;;;9816:57;;;;-1:-1:-1;;;9816:57:1;;14401:2:6;9816:57:1;;;14383:21:6;14440:2;14420:18;;;14413:30;14479:34;14459:18;;;14452:62;-1:-1:-1;;;14530:18:6;;;14523:31;14571:19;;9816:57:1;14199:397:6;9816:57:1;1913:10:3;-1:-1:-1;;;;;9908:21:1;;;;:62;;-1:-1:-1;9933:37:1;9950:5;1913:10:3;10681:164:1;:::i;9933:37::-;9886:168;;;;-1:-1:-1;;;9886:168:1;;14803:2:6;9886:168:1;;;14785:21:6;14842:2;14822:18;;;14815:30;14881:34;14861:18;;;14854:62;14952:26;14932:18;;;14925:54;14996:19;;9886:168:1;14601:420:6;9886:168:1;10067:21;10076:2;10080:7;10067:8;:21::i;:::-;9755:341;9685:411;;:::o;4898:97:4:-;3441:4:3;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3239:54;;;;-1:-1:-1;;;3239:54:3;;;;;;;:::i;:::-;4965:22:4::1;4979:7;4965:13;:22::i;:::-;4898:97:::0;:::o;30072:309:1:-;30159:18;30180:8;;;:4;:8;;;;;;;;30159:29;;;;;;;;;;;;;;;;;30133:13;;30159:18;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30159:29:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30199:20;30233:5;:12;-1:-1:-1;;;;;30222:24:1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30222:24:1;;30199:47;;30262:6;30257:93;30278:5;:12;30274:1;:16;30257:93;;;30324:5;30330:1;30324:8;;;;;;;;:::i;:::-;;;;;;;:14;;;30312:6;30319:1;30312:9;;;;;;;;:::i;:::-;;;;;;;;;;:26;30292:3;;;;:::i;:::-;;;;30257:93;;;-1:-1:-1;30367:6:1;30072:309;-1:-1:-1;;;30072:309:1:o;10912:339::-;11107:41;1913:10:3;11140:7:1;11107:18;:41::i;:::-;11099:103;;;;-1:-1:-1;;;11099:103:1;;;;;;;:::i;:::-;11215:28;11225:4;11231:2;11235:7;11215:9;:28::i;22047:256::-;22144:7;22180:23;22197:5;22180:16;:23::i;:::-;22172:5;:31;22164:87;;;;-1:-1:-1;;;22164:87:1;;16411:2:6;22164:87:1;;;16393:21:6;16450:2;16430:18;;;16423:30;16489:34;16469:18;;;16462:62;-1:-1:-1;;;16540:18:6;;;16533:41;16591:19;;22164:87:1;16209:407:6;22164:87:1;-1:-1:-1;;;;;;22269:19:1;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;22047:256::o;5482:96:4:-;3441:4:3;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3239:54;;;;-1:-1:-1;;;3239:54:3;;;;;;;:::i;:::-;5548:22:4::1;5562:7;5548:13;:22::i;11322:185:1:-:0;11460:39;11477:4;11483:2;11487:7;11460:39;;;;;;;;;;;;:16;:39::i;22569:233::-;22644:7;22680:30;22467:10;:17;;22379:113;22680:30;22672:5;:38;22664:95;;;;-1:-1:-1;;;22664:95:1;;16823:2:6;22664:95:1;;;16805:21:6;16862:2;16842:18;;;16835:30;16901:34;16881:18;;;16874:62;-1:-1:-1;;;16952:18:6;;;16945:42;17004:19;;22664:95:1;16621:408:6;22664:95:1;22777:10;22788:5;22777:17;;;;;;;;:::i;:::-;;;;;;;;;22770:24;;22569:233;;;:::o;28556:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28556:38:1;;;;-1:-1:-1;28556:38:1;-1:-1:-1;28556:38:1;:::o;8297:239::-;8369:7;8405:16;;;:7;:16;;;;;;-1:-1:-1;;;;;8405:16:1;8440:19;8432:73;;;;-1:-1:-1;;;8432:73:1;;17236:2:6;8432:73:1;;;17218:21:6;17275:2;17255:18;;;17248:30;17314:34;17294:18;;;17287:62;-1:-1:-1;;;17365:18:6;;;17358:39;17414:19;;8432:73:1;17034:405:6;8027:208:1;8099:7;-1:-1:-1;;;;;8127:19:1;;8119:74;;;;-1:-1:-1;;;8119:74:1;;17646:2:6;8119:74:1;;;17628:21:6;17685:2;17665:18;;;17658:30;17724:34;17704:18;;;17697:62;-1:-1:-1;;;17775:18:6;;;17768:40;17825:19;;8119:74:1;17444:406:6;8119:74:1;-1:-1:-1;;;;;;8211:16:1;;;;;:9;:16;;;;;;;8027:208::o;3846:140:3:-;3441:4;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3239:54;;;;-1:-1:-1;;;3239:54:3;;;;;;;:::i;:::-;3945:1:::1;3929:6:::0;;3908:40:::1;::::0;-1:-1:-1;;;;;3929:6:3;;::::1;::::0;3908:40:::1;::::0;3945:1;;3908:40:::1;3976:1;3959:19:::0;;-1:-1:-1;;;;;;3959:19:3::1;::::0;;3846:140::o;5227:109::-;5283:4;5307:21;:8;5320:7;5307:12;:21::i;5252:115:4:-;3441:4:3;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3239:54;;;;-1:-1:-1;;;3239:54:3;;;;;;;:::i;:::-;5331:28:4::1;5347:11;5331:15;:28::i;8772:104:1:-:0;8828:13;8861:7;8854:14;;;;;:::i;5379:91:4:-;3441:4:3;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3239:54;;;;-1:-1:-1;;;3239:54:3;;;;;;;:::i;:::-;5443:19:4::1;5454:7;5443:10;:19::i;10369:79:3:-:0;10413:27;1913:10;10413:13;:27::i;:::-;10369:79::o;5058:127:4:-;3441:4:3;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3239:54;;;;-1:-1:-1;;;3239:54:3;;;;;;;:::i;:::-;5143:34:4::1;5162:14;5143:18;:34::i;10455:155:1:-:0;10550:52;1913:10:3;10583:8:1;10593;10550:18;:52::i;:::-;10455:155;;:::o;10146:109:3:-;10202:4;10226:21;:8;10239:7;10226:12;:21::i;11578:328:1:-;11753:41;1913:10:3;11786:7:1;11753:18;:41::i;:::-;11745:103;;;;-1:-1:-1;;;11745:103:1;;;;;;;:::i;:::-;11859:39;11873:4;11879:2;11883:7;11892:5;11859:13;:39::i;:::-;11578:328;;;;:::o;2814:560:4:-;2973:66;2982:56;3030:1;3033;3036;2982:39;2997:7;;3006:4;3012:8;;2982:14;:39::i;:::-;:47;:56;;:47;:56::i;2973:66::-;2965:105;;;;-1:-1:-1;;;2965:105:4;;18057:2:6;2965:105:4;;;18039:21:6;18096:2;18076:18;;;18069:30;18135:28;18115:18;;;18108:56;18181:18;;2965:105:4;17855:350:6;2965:105:4;3102:19;3107:7;3102:4;:19;:::i;:::-;3089:9;:32;3081:71;;;;-1:-1:-1;;;3081:71:4;;18585:2:6;3081:71:4;;;18567:21:6;18624:2;18604:18;;;18597:30;18663:28;18643:18;;;18636:56;18709:18;;3081:71:4;18383:350:6;3081:71:4;3168:6;3163:160;3180:18;;;3163:160;;;3220:39;3226:10;3238:7;;3246:1;3238:10;;;;;;;:::i;:::-;;;;;;;3250:5;;3256:1;3250:8;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;3220:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:5;:39::i;:::-;3274:37;3287:7;;3295:1;3287:10;;;;;;;:::i;:::-;;;;;;;3299:8;;3308:1;3299:11;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;3274:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3274:12:4;;-1:-1:-1;;;3274:37:4:i;:::-;3200:3;;;;:::i;:::-;;;;3163:160;;;-1:-1:-1;3335:11:4;;:31;;-1:-1:-1;;;;;3335:11:4;;;;3356:9;3335:31;;;;;:11;:31;:11;:31;3356:9;3335:11;:31;;;;;;;;;;;;;;;;;;;;;2814:560;;;;;;;;;:::o;29535:353:1:-;29640:18;29661:8;;;:4;:8;;;;;;;;29640:29;;;;;;;;;;;;;;;;;29603:24;;29640:18;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;29640:29:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29680:31;29736:5;:12;-1:-1:-1;;;;;29714:35:1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29714:35:1;;29680:69;;29765:6;29760:97;29781:5;:12;29777:1;:16;29760:97;;;29827:5;29833:1;29827:8;;;;;;;;:::i;:::-;;;;;;;:18;;;29815:6;29822:1;29815:9;;;;;;;;:::i;:::-;-1:-1:-1;;;;;29815:30:1;;;:9;;;;;;;;;;;:30;29795:3;;;;:::i;:::-;;;;29760:97;;175:28:2;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;31301:217:1:-;13481:4;13505:16;;;:7;:16;;;;;;31366:13;;-1:-1:-1;;;;;13505:16:1;31392:76;;;;-1:-1:-1;;;31392:76:1;;20264:2:6;31392:76:1;;;20246:21:6;20303:2;20283:18;;;20276:30;20342:34;20322:18;;;20315:62;-1:-1:-1;;;20393:18:6;;;20386:45;20448:19;;31392:76:1;20062:411:6;31392:76:1;31486:24;31502:7;31486:15;:24::i;3386:530:4:-;3441:4:3;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3467:33:4;;;;3480:20;3489:10;3480:8;:20::i;:::-;3459:80;;;;-1:-1:-1;;;3459:80:4;;20680:2:6;3459:80:4;;;20662:21:6;20719:2;20699:18;;;20692:30;20758:34;20738:18;;;20731:62;-1:-1:-1;;;20809:18:6;;;20802:32;20851:19;;3459:80:4;20478:398:6;3459:80:4;3555:6;3550:359;3571:12;:19;3567:1;:23;3550:359;;;3611:21;3635:12;3648:1;3635:15;;;;;;;;:::i;:::-;;;;;;;:21;;;3611:45;;3671:15;3689:12;3702:1;3689:15;;;;;;;;:::i;:::-;;;;;;;:23;;;3671:41;;3727:17;3747:12;3760:1;3747:15;;;;;;;;:::i;:::-;;;;;;;:20;;;3727:40;;3782:22;3807:12;3820:1;3807:15;;;;;;;;:::i;:::-;;;;;;;:24;;;3782:49;;3860:37;3866:5;3873:7;3882:4;3888:8;3860:5;:37::i;:::-;3596:313;;;;3592:3;;;;;:::i;:::-;;;;3550:359;;5657:79:3;5701:27;1913:10;5701:13;:27::i;2983:25:0:-;;;;;;;:::i;4617:100:4:-;3441:4:3;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3239:54;;;;-1:-1:-1;;;3239:54:3;;;;;;;:::i;:::-;4690:19:4::1;4701:7;4690:10;:19::i;4141:109:3:-:0;3441:4;3481:6;-1:-1:-1;;;;;3481:6:3;1913:10;3465:22;3239:54;;;;-1:-1:-1;;;3239:54:3;;;;;;;:::i;:::-;4214:28:::1;4233:8;4214:18;:28::i;309:178::-:0;387:18;391:4;397:7;387:3;:18::i;:::-;386:19;378:63;;;;-1:-1:-1;;;378:63:3;;21083:2:6;378:63:3;;;21065:21:6;21122:2;21102:18;;;21095:30;21161:33;21141:18;;;21134:61;21212:18;;378:63:3;20881:355:6;378:63:3;-1:-1:-1;;;;;452:20:3;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;452:27:3;475:4;452:27;;;309:178::o;7651:312:1:-;7760:4;-1:-1:-1;;;;;;7797:40:1;;-1:-1:-1;;;7797:40:1;;:105;;-1:-1:-1;;;;;;;7854:48:1;;-1:-1:-1;;;7854:48:1;7797:105;:158;;;;7919:36;7943:11;7919:23;:36::i;17639:174::-;17714:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;17714:29:1;-1:-1:-1;;;;;17714:29:1;;;;;;;;:24;;17768:23;17714:24;17768:14;:23::i;:::-;-1:-1:-1;;;;;17759:46:1;;;;;;;;;;;17639:174;;:::o;5874:130:3:-;5934:24;:8;5950:7;5934:15;:24::i;:::-;5974:22;;-1:-1:-1;;;;;5974:22:3;;;;;;;;5874:130;:::o;13710:348:1:-;13803:4;13505:16;;;:7;:16;;;;;;-1:-1:-1;;;;;13505:16:1;13820:73;;;;-1:-1:-1;;;13820:73:1;;21443:2:6;13820:73:1;;;21425:21:6;21482:2;21462:18;;;21455:30;21521:34;21501:18;;;21494:62;-1:-1:-1;;;21572:18:6;;;21565:42;21624:19;;13820:73:1;21241:408:6;13820:73:1;13904:13;13920:23;13935:7;13920:14;:23::i;:::-;13904:39;;13973:5;-1:-1:-1;;;;;13962:16:1;:7;-1:-1:-1;;;;;13962:16:1;;:51;;;;14006:7;-1:-1:-1;;;;;13982:31:1;:20;13994:7;13982:11;:20::i;:::-;-1:-1:-1;;;;;13982:31:1;;13962:51;:87;;;-1:-1:-1;;;;;;10802:25:1;;;10778:4;10802:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;14017:32;13954:96;13710:348;-1:-1:-1;;;;13710:348:1:o;16943:578::-;17102:4;-1:-1:-1;;;;;17075:31:1;:23;17090:7;17075:14;:23::i;:::-;-1:-1:-1;;;;;17075:31:1;;17067:85;;;;-1:-1:-1;;;17067:85:1;;21856:2:6;17067:85:1;;;21838:21:6;21895:2;21875:18;;;21868:30;21934:34;21914:18;;;21907:62;-1:-1:-1;;;21985:18:6;;;21978:39;22034:19;;17067:85:1;21654:405:6;17067:85:1;-1:-1:-1;;;;;17171:16:1;;17163:65;;;;-1:-1:-1;;;17163:65:1;;22266:2:6;17163:65:1;;;22248:21:6;22305:2;22285:18;;;22278:30;22344:34;22324:18;;;22317:62;-1:-1:-1;;;22395:18:6;;;22388:34;22439:19;;17163:65:1;22064:400:6;17163:65:1;17241:39;17262:4;17268:2;17272:7;17241:20;:39::i;:::-;17345:29;17362:1;17366:7;17345:8;:29::i;:::-;-1:-1:-1;;;;;17387:15:1;;;;;;:9;:15;;;;;:20;;17406:1;;17387:15;:20;;17406:1;;17387:20;:::i;:::-;;;;-1:-1:-1;;;;;;;17418:13:1;;;;;;:9;:13;;;;;:18;;17435:1;;17418:13;:18;;17435:1;;17418:18;:::i;:::-;;;;-1:-1:-1;;17447:16:1;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;17447:21:1;-1:-1:-1;;;;;17447:21:1;;;;;;;;;17486:27;;17447:16;;17486:27;;;;;;;16943:578;;;:::o;10586:130:3:-;10646:24;:8;10662:7;10646:15;:24::i;:::-;10686:22;;-1:-1:-1;;;;;10686:22:3;;;;;;;;10586:130;:::o;845:203::-;917:4;-1:-1:-1;;;;;942:21:3;;934:68;;;;-1:-1:-1;;;934:68:3;;22934:2:6;934:68:3;;;22916:21:6;22973:2;22953:18;;;22946:30;23012:34;22992:18;;;22985:62;-1:-1:-1;;;23063:18:6;;;23056:32;23105:19;;934:68:3;22732:398:6;934:68:3;-1:-1:-1;;;;;;1020:20:3;:11;:20;;;;;;;;;;;;;;;845:203::o;3443:107:0:-;3516:26;;;;:11;;:26;;;;;:::i;10456:122:3:-;10513:21;:8;10526:7;10513:12;:21::i;:::-;10550:20;;-1:-1:-1;;;;;10550:20:3;;;;;;;;10456:122;:::o;1260:119:2:-;1339:32;;;;:14;;:32;;;;;:::i;17955:315:1:-;18110:8;-1:-1:-1;;;;;18101:17:1;:5;-1:-1:-1;;;;;18101:17:1;;;18093:55;;;;-1:-1:-1;;;18093:55:1;;23337:2:6;18093:55:1;;;23319:21:6;23376:2;23356:18;;;23349:30;23415:27;23395:18;;;23388:55;23460:18;;18093:55:1;23135:349:6;18093:55:1;-1:-1:-1;;;;;18159:25:1;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;18159:46:1;;;;;;;;;;18221:41;;540::6;;;18221::1;;513:18:6;18221:41:1;;;;;;;17955:315;;;:::o;12788:::-;12945:28;12955:4;12961:2;12965:7;12945:9;:28::i;:::-;12992:48;13015:4;13021:2;13025:7;13034:5;12992:22;:48::i;:::-;12984:111;;;;-1:-1:-1;;;12984:111:1;;;;;;;:::i;4134:234:4:-;4260:13;4293:67;4314:3;;4327:9;4339:8;;4303:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4293:56;;;;;;:65;:67::i;:::-;4286:74;4134:234;-1:-1:-1;;;;;;4134:234:4:o;11531:469:5:-;11625:7;11645:21;11675:7;11645:38;;11694:24;11721:211;11742:39;;;;;;;;;;;;;;;;;11802:26;:8;:15;:24;:26::i;:::-;11867:12;;;11877:1;11867:12;;;;;;11881;;;;;;11895;;;;;;11909;;;;;;;;;11844:8;;11867:12;;11721:6;:211::i;:::-;11694:238;;11950:42;11970:11;11960:22;;;;;;11984:1;11987;11990;11950:42;;;;;;;;;;;;;;;;;26118:25:6;;;26191:4;26179:17;;;;26174:2;26159:18;;26152:45;26228:2;26213:18;;26206:34;26271:2;26256:18;;26249:34;26105:3;26090:19;;25891:398;11950:42:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11950:42:5;;-1:-1:-1;;11950:42:5;;;11531:469;-1:-1:-1;;;;;;;;11531:469:5:o;30389:705:1:-;30482:18;30488:2;30492:7;30482:5;:18::i;:::-;30511:27;30555:5;:12;-1:-1:-1;;;;;30541:27:1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30541:27:1;;30511:57;;30579:17;30610:5;:12;-1:-1:-1;;;;;30599:24:1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30599:24:1;;30579:44;;30639:6;30634:346;30655:5;:12;30651:1;:16;30634:346;;;30727:3;-1:-1:-1;;;;;30697:34:1;:5;30703:1;30697:8;;;;;;;;:::i;:::-;;;;;;;:18;;;-1:-1:-1;;;;;30697:34:1;;;30689:74;;;;-1:-1:-1;;;30689:74:1;;26496:2:6;30689:74:1;;;26478:21:6;26535:2;26515:18;;;26508:30;26574:29;26554:18;;;26547:57;26621:18;;30689:74:1;26294:351:6;30689:74:1;30786:5;30792:1;30786:8;;;;;;;;:::i;:::-;;;;;;;:14;;;30804:1;30786:19;;30778:60;;;;-1:-1:-1;;;30778:60:1;;26852:2:6;30778:60:1;;;26834:21:6;26891:2;26871:18;;;26864:30;26930;26910:18;;;26903:58;26978:18;;30778:60:1;26650:352:6;30778:60:1;30853:13;;;;:4;:13;;;;;30872:8;;:5;;30878:1;;30872:8;;;;;;:::i;:::-;;;;;;;;;;;;30853:28;;;;;;;;-1:-1:-1;30853:28:1;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;30853:28:1;-1:-1:-1;;;;;30853:28:1;;;;;;;;;;;;;;;30912:8;;;;30918:1;;30912:8;;;;;;:::i;:::-;;;;;;;:18;;;30896:10;30907:1;30896:13;;;;;;;;:::i;:::-;;;;;;:34;-1:-1:-1;;;;;30896:34:1;;;-1:-1:-1;;;;;30896:34:1;;;;;30954:5;30960:1;30954:8;;;;;;;;:::i;:::-;;;;;;;:14;;;30945:3;30949:1;30945:6;;;;;;;;:::i;:::-;;;;;;;;;;:23;30669:3;;;;:::i;:::-;;;;30634:346;;;-1:-1:-1;30994:12:1;;:16;30990:97;;31032:43;31050:7;31059:10;31071:3;31032:43;;;;;;;;:::i;:::-;;;;;;;;30990:97;30471:623;;30389:705;;;:::o;31765:211::-;13481:4;13505:16;;;:7;:16;;;;;;-1:-1:-1;;;;;13505:16:1;31852:73;;;;-1:-1:-1;;;31852:73:1;;28116:2:6;31852:73:1;;;28098:21:6;28155:2;28135:18;;;28128:30;28194:34;28174:18;;;28167:62;-1:-1:-1;;;28245:18:6;;;28238:42;28297:19;;31852:73:1;27914:408:6;31852:73:1;31936:32;31955:7;31964:3;31936:18;:32::i;607:142:2:-;721:19;;;;:10;:19;;;;;699:42;;666:13;;699:42;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:14;:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:42;;;;:::i;3928:194:4:-;4042:30;4054:2;4058:7;4067:4;4042:11;:30::i;:::-;4083:31;4096:7;4105:8;4083:12;:31::i;5744:122:3:-;5801:21;:8;5814:7;5801:12;:21::i;:::-;5838:20;;-1:-1:-1;;;;;5838:20:3;;;;;;;;5744:122;:::o;4356:229::-;-1:-1:-1;;;;;4430:22:3;;4422:73;;;;-1:-1:-1;;;4422:73:3;;28529:2:6;4422:73:3;;;28511:21:6;28568:2;28548:18;;;28541:30;28607:34;28587:18;;;28580:62;-1:-1:-1;;;28658:18:6;;;28651:36;28704:19;;4422:73:3;28327:402:6;4422:73:3;4532:6;;;4511:38;;-1:-1:-1;;;;;4511:38:3;;;;4532:6;;;4511:38;;;4560:6;:17;;-1:-1:-1;;;;;;4560:17:3;-1:-1:-1;;;;;4560:17:3;;;;;;;;;;4356:229::o;2128:190:0:-;2213:4;-1:-1:-1;;;;;;;;;1617:40:0;;;2237:73;;;-1:-1:-1;;;;;;;;2277:33:0;;;;;:20;:33;;;;;;;;;2128:190::o;567:183:3:-;647:18;651:4;657:7;647:3;:18::i;:::-;639:64;;;;-1:-1:-1;;;639:64:3;;28936:2:6;639:64:3;;;28918:21:6;28975:2;28955:18;;;28948:30;29014:34;28994:18;;;28987:62;-1:-1:-1;;;29065:18:6;;;29058:31;29106:19;;639:64:3;28734:397:6;639:64:3;-1:-1:-1;;;;;714:20:3;737:5;714:20;;;;;;;;;;;:28;;-1:-1:-1;;714:28:3;;;567:183::o;23415:589:1:-;-1:-1:-1;;;;;23621:18:1;;23617:187;;23656:40;23688:7;24831:10;:17;;24804:24;;;;:15;:24;;;;;:44;;;24859:24;;;;;;;;;;;;24727:164;23656:40;23617:187;;;23726:2;-1:-1:-1;;;;;23718:10:1;:4;-1:-1:-1;;;;;23718:10:1;;23714:90;;23745:47;23778:4;23784:7;23745:32;:47::i;:::-;-1:-1:-1;;;;;23818:16:1;;23814:183;;23851:45;23888:7;23851:36;:45::i;23814:183::-;23924:4;-1:-1:-1;;;;;23918:10:1;:2;-1:-1:-1;;;;;23918:10:1;;23914:83;;23945:40;23973:2;23977:7;23945:27;:40::i;18835:799::-;18990:4;19011:15;:2;-1:-1:-1;;;;;19011:13:1;;:15::i;:::-;19007:620;;;19047:72;;-1:-1:-1;;;19047:72:1;;-1:-1:-1;;;;;19047:36:1;;;;;:72;;1913:10:3;;19098:4:1;;19104:7;;19113:5;;19047:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19047:72:1;;;;;;;;-1:-1:-1;;19047:72:1;;;;;;;;;;;;:::i;:::-;;;19043:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19289:13:1;;19285:272;;19332:60;;-1:-1:-1;;;19332:60:1;;;;;;;:::i;19285:272::-;19507:6;19501:13;19492:6;19488:2;19484:15;19477:38;19043:529;-1:-1:-1;;;;;;19170:51:1;-1:-1:-1;;;19170:51:1;;-1:-1:-1;19163:58:1;;19007:620;-1:-1:-1;19611:4:1;19604:11;;13502:375:5;13584:42;;;;;;;;;;;-1:-1:-1;;;13584:42:5;;;;13656:13;;;;;13558;13656;;;;;13558;-1:-1:-1;;13656:13:5;;;;;;;;;;;-1:-1:-1;13656:13:5;13637:32;;13685:9;13680:161;13704:2;13700:1;:6;13680:161;;;13739:8;13766:1;13754:5;13760:1;13754:8;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;13754:13:5;;;;13748:20;;13739:30;;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;13739:30:5;13728:3;13732;:1;13734;13732:3;:::i;:::-;13728:8;;;;;;;;:::i;:::-;;;;:41;-1:-1:-1;;;;;13728:41:5;;;;;;;;;13797:8;13812:5;13818:1;13812:8;;;;;;;:::i;:::-;13797:32;;13812:8;;;13823:4;13806:22;;13797:32;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;13797:32:5;13784:3;13790;:1;13792;13790:3;:::i;:::-;13788:5;;:1;:5;:::i;:::-;13784:10;;;;;;;;:::i;:::-;;;;:45;-1:-1:-1;;;;;13784:45:5;;;;;;;;-1:-1:-1;13708:3:5;;;;:::i;:::-;;;;13680:161;;9608:723;9664:13;9885:10;9881:53;;-1:-1:-1;;9912:10:5;;;;;;;;;;;;-1:-1:-1;;;9912:10:5;;;;;9608:723::o;9881:53::-;9959:5;9944:12;10000:78;10007:9;;10000:78;;10033:8;;;;:::i;:::-;;-1:-1:-1;10056:10:5;;-1:-1:-1;10064:2:5;10056:10;;:::i;:::-;;;10000:78;;;10088:19;10120:6;-1:-1:-1;;;;;10110:17:5;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10110:17:5;;10088:39;;10138:154;10145:10;;10138:154;;10172:11;10182:1;10172:11;;:::i;:::-;;-1:-1:-1;10241:10:5;10249:2;10241:5;:10;:::i;:::-;10228:24;;:2;:24;:::i;:::-;10215:39;;10198:6;10205;10198:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;10198:56:5;;;;;;;;-1:-1:-1;10269:11:5;10278:2;10269:11;;:::i;:::-;;;10138:154;;12008:892;12173:12;12198:24;12313:3;:10;12300:3;:10;12287:3;:10;12274:3;:10;12261:3;:10;12248:3;:10;12235:3;:10;:23;;;;:::i;:::-;:36;;;;:::i;:::-;:49;;;;:::i;:::-;:62;;;;:::i;:::-;:75;;;;:::i;:::-;:88;;;;:::i;:::-;-1:-1:-1;;;;;12225:99:5;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12225:99:5;;12198:126;;12335:6;12361;12356:63;12377:3;:10;12373:1;:14;12356:63;;;12413:3;12417:1;12413:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;12413:6:5;12394:11;12406:3;;;;:::i;:::-;;;12394:16;;;;;;;;:::i;:::-;;;;:25;-1:-1:-1;;;;;12394:25:5;;;;;;;;-1:-1:-1;12389:3:5;;;;:::i;:::-;;;;12356:63;;;;12435:6;12430:63;12451:3;:10;12447:1;:14;12430:63;;;12487:3;12491:1;12487:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;12487:6:5;12468:11;12480:3;;;;:::i;:::-;;;12468:16;;;;;;;;:::i;:::-;;;;:25;-1:-1:-1;;;;;12468:25:5;;;;;;;;-1:-1:-1;12463:3:5;;;;:::i;:::-;;;;12430:63;;;;12509:6;12504:63;12525:3;:10;12521:1;:14;12504:63;;;12561:3;12565:1;12561:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;12561:6:5;12542:11;12554:3;;;;:::i;:::-;;;12542:16;;;;;;;;:::i;:::-;;;;:25;-1:-1:-1;;;;;12542:25:5;;;;;;;;-1:-1:-1;12537:3:5;;;;:::i;:::-;;;;12504:63;;;;12583:6;12578:63;12599:3;:10;12595:1;:14;12578:63;;;12635:3;12639:1;12635:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;12635:6:5;12616:11;12628:3;;;;:::i;:::-;;;12616:16;;;;;;;;:::i;:::-;;;;:25;-1:-1:-1;;;;;12616:25:5;;;;;;;;-1:-1:-1;12611:3:5;;;;:::i;:::-;;;;12578:63;;;;12657:6;12652:63;12673:3;:10;12669:1;:14;12652:63;;;12709:3;12713:1;12709:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;12709:6:5;12690:11;12702:3;;;;:::i;:::-;;;12690:16;;;;;;;;:::i;:::-;;;;:25;-1:-1:-1;;;;;12690:25:5;;;;;;;;-1:-1:-1;12685:3:5;;;;:::i;:::-;;;;12652:63;;;;12731:6;12726:63;12747:3;:10;12743:1;:14;12726:63;;;12783:3;12787:1;12783:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;12783:6:5;12764:11;12776:3;;;;:::i;:::-;;;12764:16;;;;;;;;:::i;:::-;;;;:25;-1:-1:-1;;;;;12764:25:5;;;;;;;;-1:-1:-1;12759:3:5;;;;:::i;:::-;;;;12726:63;;;;12805:6;12800:63;12821:3;:10;12817:1;:14;12800:63;;;12857:3;12861:1;12857:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;12857:6:5;12838:11;12850:3;;;;:::i;:::-;;;12838:16;;;;;;;;:::i;:::-;;;;:25;-1:-1:-1;;;;;12838:25:5;;;;;;;;-1:-1:-1;12833:3:5;;;;:::i;:::-;;;;12800:63;;;-1:-1:-1;12881:11:5;;12008:892;-1:-1:-1;;;;;;;;;12008:892:5:o;15394:382:1:-;-1:-1:-1;;;;;15474:16:1;;15466:61;;;;-1:-1:-1;;;15466:61:1;;30468:2:6;15466:61:1;;;30450:21:6;;;30487:18;;;30480:30;30546:34;30526:18;;;30519:62;30598:18;;15466:61:1;30266:356:6;15466:61:1;13481:4;13505:16;;;:7;:16;;;;;;-1:-1:-1;;;;;13505:16:1;:30;15538:58;;;;-1:-1:-1;;;15538:58:1;;30829:2:6;15538:58:1;;;30811:21:6;30868:2;30848:18;;;30841:30;30907;30887:18;;;30880:58;30955:18;;15538:58:1;30627:352:6;15538:58:1;15609:45;15638:1;15642:2;15646:7;15609:20;:45::i;:::-;-1:-1:-1;;;;;15667:13:1;;;;;;:9;:13;;;;;:18;;15684:1;;15667:13;:18;;15684:1;;15667:18;:::i;:::-;;;;-1:-1:-1;;15696:16:1;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;15696:21:1;-1:-1:-1;;;;;15696:21:1;;;;;;;;15735:33;;15696:16;;;15735:33;;15696:16;;15735:33;15394:382;;:::o;996:119:2:-;1082:19;;;;:10;:19;;;;;;;;:25;;;;;;;;:::i;10535:422:5:-;10756:10;;10743;;10610:13;;10661:2;;10700;;10636:16;;10743:23;;10756:10;10743:23;:::i;:::-;-1:-1:-1;;;;;10733:34:5;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10733:34:5;;10714:53;;10778:6;10804;10799:55;10820:3;:10;10816:1;:14;10799:55;;;10848:3;10852:1;10848:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;10848:6:5;10837:3;10841;;;;:::i;:::-;;;10837:8;;;;;;;;:::i;:::-;;;;:17;-1:-1:-1;;;;;10837:17:5;;;;;;;;-1:-1:-1;10832:3:5;;;;:::i;:::-;;;;10799:55;;;;10870:6;10865:55;10886:3;:10;10882:1;:14;10865:55;;;10914:3;10918:1;10914:6;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;10914:6:5;10903:3;10907;;;;:::i;:::-;;;10903:8;;;;;;;;:::i;:::-;;;;:17;-1:-1:-1;;;;;10903:17:5;;;;;;;;-1:-1:-1;10898:3:5;;;;:::i;:::-;;;;10865:55;;;-1:-1:-1;10945:3:5;;10535:422;-1:-1:-1;;;;;;10535:422:5:o;25518:988:1:-;25784:22;25834:1;25809:22;25826:4;25809:16;:22::i;:::-;:26;;;;:::i;:::-;25846:18;25867:26;;;:17;:26;;;;;;25784:51;;-1:-1:-1;26000:28:1;;;25996:328;;-1:-1:-1;;;;;26067:18:1;;26045:19;26067:18;;;:12;:18;;;;;;;;:34;;;;;;;;;26118:30;;;;;;:44;;;26235:30;;:17;:30;;;;;:43;;;25996:328;-1:-1:-1;26420:26:1;;;;:17;:26;;;;;;;;26413:33;;;-1:-1:-1;;;;;26464:18:1;;;;;:12;:18;;;;;:34;;;;;;;26457:41;25518:988::o;26801:1079::-;27079:10;:17;27054:22;;27079:21;;27099:1;;27079:21;:::i;:::-;27111:18;27132:24;;;:15;:24;;;;;;27505:10;:26;;27054:46;;-1:-1:-1;27132:24:1;;27054:46;;27505:26;;;;;;:::i;:::-;;;;;;;;;27483:48;;27569:11;27544:10;27555;27544:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;27649:28;;;:15;:28;;;;;;;:41;;;27821:24;;;;;27814:31;27856:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;26872:1008;;;26801:1079;:::o;24305:221::-;24390:14;24407:20;24424:2;24407:16;:20::i;:::-;-1:-1:-1;;;;;24438:16:1;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;24483:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;24305:221:1:o;6170:619:5:-;6230:4;6698:20;;6541:66;6738:23;;;;;;:42;;-1:-1:-1;;6765:15:5;;;6730:51;-1:-1:-1;;6170:619:5:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:6;-1:-1:-1;;;;;;88:32:6;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:6:o;592:472::-;634:3;672:5;666:12;699:6;694:3;687:19;724:1;734:162;748:6;745:1;742:13;734:162;;;810:4;866:13;;;862:22;;856:29;838:11;;;834:20;;827:59;763:12;734:162;;;914:6;911:1;908:13;905:87;;;980:1;973:4;964:6;959:3;955:16;951:27;944:38;905:87;-1:-1:-1;1046:2:6;1025:15;-1:-1:-1;;1021:29:6;1012:39;;;;1053:4;1008:50;;592:472;-1:-1:-1;;592:472:6:o;1069:220::-;1218:2;1207:9;1200:21;1181:4;1238:45;1279:2;1268:9;1264:18;1256:6;1238:45;:::i;1294:180::-;1353:6;1406:2;1394:9;1385:7;1381:23;1377:32;1374:52;;;1422:1;1419;1412:12;1374:52;-1:-1:-1;1445:23:6;;1294:180;-1:-1:-1;1294:180:6:o;1687:131::-;-1:-1:-1;;;;;1762:31:6;;1752:42;;1742:70;;1808:1;1805;1798:12;1823:315;1891:6;1899;1952:2;1940:9;1931:7;1927:23;1923:32;1920:52;;;1968:1;1965;1958:12;1920:52;2007:9;1994:23;2026:31;2051:5;2026:31;:::i;:::-;2076:5;2128:2;2113:18;;;;2100:32;;-1:-1:-1;;;1823:315:6:o;2143:247::-;2202:6;2255:2;2243:9;2234:7;2230:23;2226:32;2223:52;;;2271:1;2268;2261:12;2223:52;2310:9;2297:23;2329:31;2354:5;2329:31;:::i;2395:435::-;2448:3;2486:5;2480:12;2513:6;2508:3;2501:19;2539:4;2568:2;2563:3;2559:12;2552:19;;2605:2;2598:5;2594:14;2626:1;2636:169;2650:6;2647:1;2644:13;2636:169;;;2711:13;;2699:26;;2745:12;;;;2780:15;;;;2672:1;2665:9;2636:169;;;-1:-1:-1;2821:3:6;;2395:435;-1:-1:-1;;;;;2395:435:6:o;2835:261::-;3014:2;3003:9;2996:21;2977:4;3034:56;3086:2;3075:9;3071:18;3063:6;3034:56;:::i;3283:456::-;3360:6;3368;3376;3429:2;3417:9;3408:7;3404:23;3400:32;3397:52;;;3445:1;3442;3435:12;3397:52;3484:9;3471:23;3503:31;3528:5;3503:31;:::i;:::-;3553:5;-1:-1:-1;3610:2:6;3595:18;;3582:32;3623:33;3582:32;3623:33;:::i;:::-;3283:456;;3675:7;;-1:-1:-1;;;3729:2:6;3714:18;;;;3701:32;;3283:456::o;3968:248::-;4036:6;4044;4097:2;4085:9;4076:7;4072:23;4068:32;4065:52;;;4113:1;4110;4103:12;4065:52;-1:-1:-1;;4136:23:6;;;4206:2;4191:18;;;4178:32;;-1:-1:-1;3968:248:6:o;4516:127::-;4577:10;4572:3;4568:20;4565:1;4558:31;4608:4;4605:1;4598:15;4632:4;4629:1;4622:15;4648:253;4720:2;4714:9;4762:4;4750:17;;-1:-1:-1;;;;;4782:34:6;;4818:22;;;4779:62;4776:88;;;4844:18;;:::i;:::-;4880:2;4873:22;4648:253;:::o;4906:275::-;4977:2;4971:9;5042:2;5023:13;;-1:-1:-1;;5019:27:6;5007:40;;-1:-1:-1;;;;;5062:34:6;;5098:22;;;5059:62;5056:88;;;5124:18;;:::i;:::-;5160:2;5153:22;4906:275;;-1:-1:-1;4906:275:6:o;5186:407::-;5251:5;-1:-1:-1;;;;;5277:6:6;5274:30;5271:56;;;5307:18;;:::i;:::-;5345:57;5390:2;5369:15;;-1:-1:-1;;5365:29:6;5396:4;5361:40;5345:57;:::i;:::-;5336:66;;5425:6;5418:5;5411:21;5465:3;5456:6;5451:3;5447:16;5444:25;5441:45;;;5482:1;5479;5472:12;5441:45;5531:6;5526:3;5519:4;5512:5;5508:16;5495:43;5585:1;5578:4;5569:6;5562:5;5558:18;5554:29;5547:40;5186:407;;;;;:::o;5598:222::-;5641:5;5694:3;5687:4;5679:6;5675:17;5671:27;5661:55;;5712:1;5709;5702:12;5661:55;5734:80;5810:3;5801:6;5788:20;5781:4;5773:6;5769:17;5734:80;:::i;5825:322::-;5894:6;5947:2;5935:9;5926:7;5922:23;5918:32;5915:52;;;5963:1;5960;5953:12;5915:52;6003:9;5990:23;-1:-1:-1;;;;;6028:6:6;6025:30;6022:50;;;6068:1;6065;6058:12;6022:50;6091;6133:7;6124:6;6113:9;6109:22;6091:50;:::i;6152:416::-;6217:6;6225;6278:2;6266:9;6257:7;6253:23;6249:32;6246:52;;;6294:1;6291;6284:12;6246:52;6333:9;6320:23;6352:31;6377:5;6352:31;:::i;:::-;6402:5;-1:-1:-1;6459:2:6;6444:18;;6431:32;6501:15;;6494:23;6482:36;;6472:64;;6532:1;6529;6522:12;6472:64;6555:7;6545:17;;;6152:416;;;;;:::o;6573:795::-;6668:6;6676;6684;6692;6745:3;6733:9;6724:7;6720:23;6716:33;6713:53;;;6762:1;6759;6752:12;6713:53;6801:9;6788:23;6820:31;6845:5;6820:31;:::i;:::-;6870:5;-1:-1:-1;6927:2:6;6912:18;;6899:32;6940:33;6899:32;6940:33;:::i;:::-;6992:7;-1:-1:-1;7046:2:6;7031:18;;7018:32;;-1:-1:-1;7101:2:6;7086:18;;7073:32;-1:-1:-1;;;;;7117:30:6;;7114:50;;;7160:1;7157;7150:12;7114:50;7183:22;;7236:4;7228:13;;7224:27;-1:-1:-1;7214:55:6;;7265:1;7262;7255:12;7214:55;7288:74;7354:7;7349:2;7336:16;7331:2;7327;7323:11;7288:74;:::i;:::-;7278:84;;;6573:795;;;;;;;:::o;7373:367::-;7436:8;7446:6;7500:3;7493:4;7485:6;7481:17;7477:27;7467:55;;7518:1;7515;7508:12;7467:55;-1:-1:-1;7541:20:6;;-1:-1:-1;;;;;7573:30:6;;7570:50;;;7616:1;7613;7606:12;7570:50;7653:4;7645:6;7641:17;7629:29;;7713:3;7706:4;7696:6;7693:1;7689:14;7681:6;7677:27;7673:38;7670:47;7667:67;;;7730:1;7727;7720:12;7667:67;7373:367;;;;;:::o;7745:1446::-;7990:6;7998;8006;8014;8022;8030;8038;8046;8054;8107:3;8095:9;8086:7;8082:23;8078:33;8075:53;;;8124:1;8121;8114:12;8075:53;8164:9;8151:23;-1:-1:-1;;;;;8234:2:6;8226:6;8223:14;8220:34;;;8250:1;8247;8240:12;8220:34;8289:70;8351:7;8342:6;8331:9;8327:22;8289:70;:::i;:::-;8378:8;;-1:-1:-1;8263:96:6;-1:-1:-1;8463:2:6;8448:18;;8435:32;;-1:-1:-1;8507:4:6;8496:16;;8486:27;;8476:55;;8527:1;8524;8517:12;8476:55;8550:5;;-1:-1:-1;8602:2:6;8587:18;;8574:32;;-1:-1:-1;8653:2:6;8638:18;;8625:32;;-1:-1:-1;8710:3:6;8695:19;;8682:33;;8727:16;;;8724:36;;;8756:1;8753;8746:12;8724:36;8795:72;8859:7;8848:8;8837:9;8833:24;8795:72;:::i;:::-;8886:8;;-1:-1:-1;8769:98:6;-1:-1:-1;8974:3:6;8959:19;;8946:33;;-1:-1:-1;8991:16:6;;;8988:36;;;9020:1;9017;9010:12;8988:36;;9059:72;9123:7;9112:8;9101:9;9097:24;9059:72;:::i;:::-;9033:98;;9150:8;9140:18;;;9177:8;9167:18;;;7745:1446;;;;;;;;;;;:::o;9196:674::-;9383:2;9435:21;;;9505:13;;9408:18;;;9527:22;;;9354:4;;9383:2;9606:15;;;;9580:2;9565:18;;;9354:4;9649:195;9663:6;9660:1;9657:13;9649:195;;;9728:13;;-1:-1:-1;;;;;9724:39:6;9712:52;;9819:15;;;;9784:12;;;;9760:1;9678:9;9649:195;;9875;9947:4;-1:-1:-1;;;;;9972:6:6;9969:30;9966:56;;;10002:18;;:::i;:::-;-1:-1:-1;10047:1:6;10043:14;10059:4;10039:25;;9875:195::o;10075:545::-;10125:5;10173:4;10161:9;10156:3;10152:19;10148:30;10145:50;;;10191:1;10188;10181:12;10145:50;10224:4;10218:11;10268:4;10260:6;10256:17;10339:6;10327:10;10324:22;-1:-1:-1;;;;;10291:10:6;10288:34;10285:62;10282:88;;;10350:18;;:::i;:::-;10386:4;10379:24;10421:6;-1:-1:-1;10421:6:6;10451:23;;10483:33;10451:23;10483:33;:::i;:::-;10525:23;;10609:2;10594:18;;;10581:32;10564:15;;10557:57;;;;10075:545;;-1:-1:-1;10075:545:6:o;10625:2378::-;10739:6;10792:2;10780:9;10771:7;10767:23;10763:32;10760:52;;;10808:1;10805;10798:12;10760:52;-1:-1:-1;;;;;10889:2:6;10877:9;10864:23;10861:31;10858:51;;;10905:1;10902;10895:12;10858:51;10956:9;10943:23;10932:9;10928:39;11005:7;10998:4;10994:2;10990:13;10986:27;10976:55;;11027:1;11024;11017:12;10976:55;11051:86;11067:69;11132:2;11119:16;11067:69;:::i;:::-;11051:86;:::i;:::-;11183:16;;11171:29;;;11225:2;11216:12;;;;11159:3;11267:1;11263:24;11255:33;;11251:42;11305:19;;;11302:39;;;11337:1;11334;11327:12;11302:39;11369:2;11365;11361:11;11381:1592;11397:6;11392:3;11389:15;11381:1592;;;11476:2;11470:3;11457:17;11454:25;11451:45;;;11492:1;11489;11482:12;11451:45;11527:17;;11519:26;;11597:4;11569:16;;;-1:-1:-1;;11565:30:6;11561:41;11558:61;;;11615:1;11612;11605:12;11558:61;11645:22;;:::i;:::-;11716:2;11712;11708:11;11695:25;11733:33;11758:7;11733:33;:::i;:::-;11779:22;;11858:2;11850:11;;11837:25;11832:2;11821:14;;11814:49;11911:2;11903:11;;11890:25;11931:14;;;11928:34;;;11958:1;11955;11948:12;11928:34;11985:15;;12035:2;12027:11;;12023:25;-1:-1:-1;12013:53:6;;12062:1;12059;12052:12;12013:53;12110:2;12106;12102:11;12089:25;12140:72;12156:55;12208:2;12156:55;:::i;12140:72::-;12256:17;;;12354:1;12350:10;;;;12342:19;;12363:2;12338:28;;12306:2;12295:14;;;12382:21;;;12379:41;;;12416:1;12413;12406:12;12379:41;12454:2;12450;12446:11;12433:24;;12470:192;12488:8;12481:5;12478:19;12470:192;;;12570:37;12599:7;12592:5;12570:37;:::i;:::-;12563:5;12556:52;12645:2;12638:5;12634:14;12625:23;;12520:2;12513:5;12509:14;12500:23;;12470:192;;;12693:2;12682:14;;12675:29;-1:-1:-1;;;12754:4:6;12746:13;;12733:27;12776:16;;;12773:36;;;12805:1;12802;12795:12;12773:36;12845:54;12891:7;12886:2;12875:8;12871:2;12867:17;12863:26;12845:54;:::i;:::-;12840:2;12829:14;;12822:78;-1:-1:-1;12913:18:6;;-1:-1:-1;12960:2:6;12951:12;;;;11414;11381:1592;;;-1:-1:-1;12992:5:6;;10625:2378;-1:-1:-1;;;;;;;10625:2378:6:o;13008:388::-;13076:6;13084;13137:2;13125:9;13116:7;13112:23;13108:32;13105:52;;;13153:1;13150;13143:12;13105:52;13192:9;13179:23;13211:31;13236:5;13211:31;:::i;:::-;13261:5;-1:-1:-1;13318:2:6;13303:18;;13290:32;13331:33;13290:32;13331:33;:::i;13401:380::-;13480:1;13476:12;;;;13523;;;13544:61;;13598:4;13590:6;13586:17;13576:27;;13544:61;13651:2;13643:6;13640:14;13620:18;13617:38;13614:161;;;13697:10;13692:3;13688:20;13685:1;13678:31;13732:4;13729:1;13722:15;13760:4;13757:1;13750:15;13614:161;;13401:380;;;:::o;15026:356::-;15228:2;15210:21;;;15247:18;;;15240:30;15306:34;15301:2;15286:18;;15279:62;15373:2;15358:18;;15026:356::o;15387:127::-;15448:10;15443:3;15439:20;15436:1;15429:31;15479:4;15476:1;15469:15;15503:4;15500:1;15493:15;15519:127;15580:10;15575:3;15571:20;15568:1;15561:31;15611:4;15608:1;15601:15;15635:4;15632:1;15625:15;15651:135;15690:3;-1:-1:-1;;15711:17:6;;15708:43;;;15731:18;;:::i;:::-;-1:-1:-1;15778:1:6;15767:13;;15651:135::o;15791:413::-;15993:2;15975:21;;;16032:2;16012:18;;;16005:30;16071:34;16066:2;16051:18;;16044:62;-1:-1:-1;;;16137:2:6;16122:18;;16115:47;16194:3;16179:19;;15791:413::o;18210:168::-;18250:7;18316:1;18312;18308:6;18304:14;18301:1;18298:21;18293:1;18286:9;18279:17;18275:45;18272:71;;;18323:18;;:::i;:::-;-1:-1:-1;18363:9:6;;18210:168::o;18738:568::-;18854:4;18860:6;18920:11;18907:25;19014:2;19010:7;18999:8;18983:14;18979:29;18975:43;18955:18;18951:68;18941:96;;19033:1;19030;19023:12;18941:96;19060:33;;19112:20;;;-1:-1:-1;;;;;;19144:30:6;;19141:50;;;19187:1;19184;19177:12;19141:50;19220:4;19208:17;;-1:-1:-1;19271:1:6;19267:14;;;19251;19247:35;19237:46;;19234:66;;;19296:1;19293;19286:12;19311:219;19391:6;19444:2;19432:9;19423:7;19419:23;19415:32;19412:52;;;19460:1;19457;19450:12;19412:52;19483:41;19516:7;19505:9;19483:41;:::i;19535:522::-;19613:4;19619:6;19679:11;19666:25;19773:2;19769:7;19758:8;19742:14;19738:29;19734:43;19714:18;19710:68;19700:96;;19792:1;19789;19782:12;19700:96;19819:33;;19871:20;;;-1:-1:-1;;;;;;19903:30:6;;19900:50;;;19946:1;19943;19936:12;19900:50;19979:4;19967:17;;-1:-1:-1;20010:14:6;20006:27;;;19996:38;;19993:58;;;20047:1;20044;20037:12;22469:125;22509:4;22537:1;22534;22531:8;22528:34;;;22542:18;;:::i;:::-;-1:-1:-1;22579:9:6;;22469:125::o;22599:128::-;22639:3;22670:1;22666:6;22663:1;22660:13;22657:39;;;22676:18;;:::i;:::-;-1:-1:-1;22712:9:6;;22599:128::o;23489:414::-;23691:2;23673:21;;;23730:2;23710:18;;;23703:30;23769:34;23764:2;23749:18;;23742:62;-1:-1:-1;;;23835:2:6;23820:18;;23813:48;23893:3;23878:19;;23489:414::o;23908:267::-;23997:6;23992:3;23985:19;24049:6;24042:5;24035:4;24030:3;24026:14;24013:43;-1:-1:-1;24101:1:6;24076:16;;;24094:4;24072:27;;;24065:38;;;;24157:2;24136:15;;;-1:-1:-1;;24132:29:6;24123:39;;;24119:50;;23908:267::o;24180:1706::-;24507:2;24489:21;;;24526:18;;24519:34;;;-1:-1:-1;;;;;;24565:31:6;;24562:51;;;24609:1;24606;24599:12;24562:51;24643:6;24640:1;24636:14;24701:6;24693;24687:3;24676:9;24672:19;24659:49;-1:-1:-1;;;;;24882:32:6;;24842:4;24862:18;;;24855:60;;;;24776:3;24727:22;;;-1:-1:-1;;;24951:28:6;;24946:2;24931:18;;24924:56;24768:12;;;25011:18;;;24902:3;25096:1;25092:14;;;25084:23;;25080:33;;;-1:-1:-1;;25045:12:6;;25136:6;-1:-1:-1;25171:686:6;25185:6;25182:1;25179:13;25171:686;;;25250:15;;;-1:-1:-1;;25246:30:6;25234:43;;25316:20;;25391:14;25387:27;;;-1:-1:-1;;25383:41:6;25359:66;;25349:96;;25440:2;25436;25429:14;25349:96;25471:31;;25531:19;;-1:-1:-1;;;;;25566:32:6;;25563:54;;;25612:2;25608;25601:14;25563:54;25665:8;25649:14;25645:29;25637:6;25633:42;25630:64;;;25689:2;25685;25678:14;25630:64;25717:60;25770:6;25760:8;25755:2;25748:5;25744:14;25717:60;:::i;:::-;25707:70;-1:-1:-1;;;25835:12:6;;;;25800:15;;;;25207:1;25200:9;25171:686;;;-1:-1:-1;25874:6:6;;24180:1706;-1:-1:-1;;;;;;;;;;;;24180:1706:6:o;27007:902::-;27255:4;27303:2;27292:9;27288:18;27333:6;27322:9;27315:25;27359:2;27397;27392;27381:9;27377:18;27370:30;27420:6;27455;27449:13;27486:6;27478;27471:22;27524:3;27513:9;27509:19;27502:26;;27563:2;27555:6;27551:15;27537:29;;27584:1;27594:195;27608:6;27605:1;27602:13;27594:195;;;27673:13;;-1:-1:-1;;;;;27669:39:6;27657:52;;27764:15;;;;27729:12;;;;27705:1;27623:9;27594:195;;;27598:3;;27834:9;27829:3;27825:19;27820:2;27809:9;27805:18;27798:47;27862:41;27899:3;27891:6;27862:41;:::i;:::-;27854:49;27007:902;-1:-1:-1;;;;;;;;27007:902:6:o;29136:497::-;-1:-1:-1;;;;;29413:15:6;;;29395:34;;29465:15;;29460:2;29445:18;;29438:43;29512:2;29497:18;;29490:34;;;29560:3;29555:2;29540:18;;29533:31;;;29338:4;;29581:46;;29607:19;;29599:6;29581:46;:::i;29638:249::-;29707:6;29760:2;29748:9;29739:7;29735:23;29731:32;29728:52;;;29776:1;29773;29766:12;29728:52;29808:9;29802:16;29827:30;29851:5;29827:30;:::i;29892:127::-;29953:10;29948:3;29944:20;29941:1;29934:31;29984:4;29981:1;29974:15;30008:4;30005:1;29998:15;30024:120;30064:1;30090;30080:35;;30095:18;;:::i;:::-;-1:-1:-1;30129:9:6;;30024:120::o;30149:112::-;30181:1;30207;30197:35;;30212:18;;:::i;:::-;-1:-1:-1;30246:9:6;;30149:112::o;30984:127::-;31045:10;31040:3;31036:20;31033:1;31026:31;31076:4;31073:1;31066:15;31100:4;31097:1;31090:15

Swarm Source

ipfs://45a45571550e7d05524d48868077d6ec4776ed636c604688904ccd06ac4ab997
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.