Token HA Works

 

Overview

TokenID:
2600000001

Transfers:
-

 
Loading
[ Download CSV Export  ] 
Loading
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume
Loading

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x17220b9e5ffc50c8e9e3873f24dbca7188c2bb95

Contract Name:
ArtistCollection

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 22 : ArtistCollection.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import "../royalties/Royalties.sol";
import "../Signable.sol";

// Version: Artist-4.0
contract ArtistCollection is
    ERC721,
    ERC721Enumerable,
    ERC721URIStorage,
    ERC721Burnable,
    Royalties,
    AccessControlEnumerable
{
    // OpenSea metadata freeze
    event PermanentURI(string _value, uint256 indexed _id);

    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;
    Counters.Counter private _editionCounter;
    string private _baseURIextended;
    uint256 private constant _MAX_SINGLES = 100000000;

    /*
        * @dev allows the artist (and potentially other 3rd parties) permission to mint
        * on behalf of the artist
     */
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    /**
     * @dev Allows minting via signable mint (an off-chain signature from a `MINTER_ROLE` user is still required)
     */
    bool private _signableMinting = false;

    function getSignableMinting() public view returns (bool){
        return _signableMinting;
    }

    function setSignableMinting(bool val) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "This action can only be performed by an admin");
        _signableMinting = val;
    }

    constructor(
        string memory baseURI,
        string memory contractName,
        string memory tokenSymbol,
        address artist
    ) ERC721(contractName, tokenSymbol) {
        _baseURIextended = baseURI;

        /**
        * @dev Minter admin is set as the artist meaning they have rights over the minter role
        * Singable minter is used to provide gassless minting and can be revoked by the default admin (i.e. artist)
        * The minter admin role can be updated by the default admin only
        */
        _setupRole(DEFAULT_ADMIN_ROLE, artist);
        _setupRole(MINTER_ROLE, artist);
    }

    function _baseURI() internal view override returns (string memory) {
        return _baseURIextended;
    }

    /**
     * Required to allow the artist to administrate the contract on OpenSea.
     * Note if there are many addresses with the DEFAULT_ADMIN_ROLE, the one which is returned may be arbitrary.
     */
    function owner() public view virtual returns (address) {
        return _getPrimaryAdmin();
    }

    function _getPrimaryAdmin() internal view virtual returns (address) {
        if (getRoleMemberCount(DEFAULT_ADMIN_ROLE) == 0) {
            return address(0);
        }
        return getRoleMember(DEFAULT_ADMIN_ROLE, 0);
    }

    /**
     * @dev Throws if called by any account other than an approved minter.
     */
    modifier onlyMinter() {
        require(hasRole(MINTER_ROLE, msg.sender), "Restricted to approved minters");
        _;
    }

    function mintAndTransfer(
        address to,
        string memory _tokenURI,
        address payable receiver,
        uint256 basisPoints
    ) public onlyMinter {
        uint256 newestToken = getNextTokenId();
        mint(msg.sender, _tokenURI, receiver, basisPoints);
        safeTransferFrom(msg.sender, to, newestToken);
    }

    /*
     * @dev hard limit of _MAX_SINGLES single tokens
     */
    function mint(
        address to,
        string memory _tokenURI,
        address payable receiver,
        uint256 basisPoints
    ) public onlyMinter {
        require(basisPoints < 10001, "Total royalties exceeds 100%");
        uint256 tokenId = getNextTokenId();
        require(
            tokenId < _MAX_SINGLES,
            "Maximum number of single tokens exceeded"
        );

        _mintSingle(to, tokenId, _tokenURI, receiver, basisPoints);
        _tokenIdCounter.increment();
    }

    function mintEditions(
        address to,
        string[] memory _tokenURIs,
        address payable receiver,
        uint256 basisPoints
    ) public onlyMinter {
        require(basisPoints < 10001, "Total royalties exceeds 100%");
        require(_tokenURIs.length > 1, "Must be more than 1 token per edition");

        uint256 tokenId = getNextEditionId();
        _mintEditions(to, tokenId, _tokenURIs, receiver, basisPoints);
        _editionCounter.increment();
    }

    /**
     * @dev Allows a third party to mint on artists behalf but only when the artist provides an off-chain
     * signature each time.
     *
     * Note signer needs to peek at expected next token ID using getNextTokenId() and include this in their
     * signature. This is required to avoid replay attacks.
     */
    function mintSignable(
        address to,
        string memory _tokenURI,
        address payable receiver,
        uint256 basisPoints,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public {
        require(_signableMinting == true, "Global signable minting must be turned on");
        require(basisPoints < 10001, "Total royalties exceeds 100%");
        uint256 tokenId = getNextTokenId();
        require(
            tokenId < _MAX_SINGLES,
            "Maximum number of single tokens exceeded"
        );

        address authorizer = Signable.recoverPersonalAddress(tokenId, _tokenURI, v, r, s);
        
        require(hasRole(MINTER_ROLE, authorizer), "Signature wrong.");

        _mintSingle(to, tokenId, _tokenURI, receiver, basisPoints);
        _tokenIdCounter.increment();
    }

    /**
     * As mintSignable except for editions
     *
     * Note signer needs to peek at expected next token ID using getNextEditionId() and include this in their
     * signature. This is required to avoid replay attacks.
     */
    function mintEditionsSignable(
        address to,
        string[] memory _tokenURIs,
        address payable receiver,
        uint256 basisPoints,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public {
        require(_signableMinting == true, "Global signable minting must be turned on");
        require(basisPoints < 10001, "Total royalties exceeds 100%");
        require(_tokenURIs.length > 1, "Must be more than 1 token per edition");
        uint256 tokenId = getNextEditionId();
        address authorizer = Signable.recoverPersonalAddressBulk(
            tokenId,
            _tokenURIs,
            v,
            r,
            s
        );
        require(hasRole(MINTER_ROLE, authorizer), "Signature wrong.");

        _mintEditions(to, tokenId, _tokenURIs, receiver, basisPoints);
        _editionCounter.increment();
    }

    function _mintEditions(
        address to,
        uint256 tokenId,
        string[] memory _tokenURIs,
        address payable receiver,
        uint256 basisPoints
    ) internal {
        for (uint256 i = 0; i < _tokenURIs.length; i++) {
            _mintSingle(to, tokenId + i, _tokenURIs[i], receiver, basisPoints);
        }
    }

    function _mintSingle(
        address to,
        uint256 tokenId,
        string memory _tokenURI,
        address payable receiver,
        uint256 basisPoints
    ) internal {
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, _tokenURI);
        if (basisPoints > 0) {
            _setRoyalties(tokenId, receiver, basisPoints);
        }
        emit PermanentURI(tokenURI(tokenId), tokenId);
    }

    function getNextTokenId() public view returns (uint256) {
        return _tokenIdCounter.current() + 1;
    }

    function getNextEditionId() public view returns (uint256) {
        return ((_editionCounter.current() + 1) * _MAX_SINGLES) + 1;
    }

    // The following functions are overrides required by Solidity.
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function _burn(uint256 tokenId)
        internal
        override(ERC721, ERC721URIStorage)
    {
        super._burn(tokenId);
    }

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

    function _existsRoyalties(uint256 tokenId)
        internal
        view
        virtual
        override(Royalties)
        returns (bool)
    {
        return super._exists(tokenId);
    }

    function _getRoyaltyFallback()
        internal
        view
        override
        returns (address payable)
    {
        return payable(_getPrimaryAdmin());
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable, AccessControlEnumerable)
        returns (bool)
    {
        return
            super.supportsInterface(interfaceId) ||
            _supportsRoyaltyInterfaces(interfaceId);
    }
}

File 2 of 22 : Royalties.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

abstract contract Royalties {
    mapping(uint256 => address payable) internal _tokenRoyaltyReceiver;
    mapping(uint256 => uint256) internal _tokenRoyaltyBPS;

    function _existsRoyalties(uint256 tokenId)
        internal
        view
        virtual
        returns (bool);

    /**
     *  @dev Rarible: RoyaltiesV1
     *
     *  bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb
     *  bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f
     *
     *  => 0xb9c4d9fb ^ 0x0ebd4c7f = 0xb7799584
     */
    bytes4 private constant _INTERFACE_ID_ROYALTIES_RARIBLE = 0xb7799584;

    /**
     *  @dev Foundation
     *
     *  bytes4(keccak256('getFees(uint256)')) == 0xd5a06d4c
     *
     *  => 0xd5a06d4c = 0xd5a06d4c
     */
    bytes4 private constant _INTERFACE_ID_ROYALTIES_FOUNDATION = 0xd5a06d4c;

    /**
     *  @dev EIP-2981
     *
     * bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
     *
     * => 0x2a55205a = 0x2a55205a
     */
    bytes4 private constant _INTERFACE_ID_ROYALTIES_EIP2981 = 0x2a55205a;

    function _setRoyalties(
        uint256 tokenId,
        address payable receiver,
        uint256 basisPoints
    ) internal {
        require(basisPoints > 0, "Basis points must be above 0");
        _tokenRoyaltyReceiver[tokenId] = receiver;
        _tokenRoyaltyBPS[tokenId] = basisPoints;
    }

    /**
     * @dev 3rd party Marketplace Royalty Support
     */

    /**
     * @dev IFoundation
     */
    function getFees(uint256 tokenId)
        external
        view
        virtual
        returns (address payable[] memory, uint256[] memory)
    {
        require(_existsRoyalties(tokenId), "Nonexistent token");

        address payable[] memory receivers = new address payable[](1);
        uint256[] memory bps = new uint256[](1);
        receivers[0] = _getRoyaltyReceiver(tokenId);
        bps[0] = _getRoyaltyBps(tokenId);
        return (receivers, bps);
    }

    /**
     * @dev IRaribleV1
     */
    function getFeeRecipients(uint256 tokenId)
        external
        view
        virtual
        returns (address payable[] memory)
    {
        require(_existsRoyalties(tokenId), "Nonexistent token");

        address payable[] memory receivers = new address payable[](1);
        receivers[0] = _getRoyaltyReceiver(tokenId);
        return receivers;
    }

    function getFeeBps(uint256 tokenId)
        external
        view
        virtual
        returns (uint256[] memory)
    {
        require(_existsRoyalties(tokenId), "Nonexistent token");

        uint256[] memory bps = new uint256[](1);
        bps[0] = _getRoyaltyBps(tokenId);
        return bps;
    }

    /**
     * @dev EIP-2981
     * Returns primary receiver i.e. receivers[0]
     */
    function royaltyInfo(uint256 tokenId, uint256 value)
        external
        view
        virtual
        returns (address, uint256)
    {
        require(_existsRoyalties(tokenId), "Nonexistent token");
        return _getRoyaltyInfo(tokenId, value);
    }

    function _getRoyaltyInfo(uint256 tokenId, uint256 value)
        internal
        view
        returns (address receiver, uint256 amount)
    {
        address _receiver = _getRoyaltyReceiver(tokenId);
        return (_receiver, (_tokenRoyaltyBPS[tokenId] * value) / 10000);
    }

    function _getRoyaltyBps(uint256 tokenId) internal view returns (uint256) {
        return _tokenRoyaltyBPS[tokenId];
    }

    function _getRoyaltyReceiver(uint256 tokenId)
        internal
        view
        returns (address payable)
    {
        uint256 bps = _getRoyaltyBps(tokenId);
        address payable receiver = _tokenRoyaltyReceiver[tokenId];
        if (bps == 0 || receiver == address(0)) {
            /**
             * @dev: If bps is 0 the receiver was never set
             * Fall back to this contract so badly behaved
             * marketplaces have somewhere to send money to
             */
            return (_getRoyaltyFallback());
        }

        return receiver;
    }

    function _getRoyaltyFallback()
        internal
        view
        virtual
        returns (address payable);

    function _supportsRoyaltyInterfaces(bytes4 interfaceId)
        internal
        pure
        returns (bool)
    {
        return
            interfaceId == _INTERFACE_ID_ROYALTIES_RARIBLE ||
            interfaceId == _INTERFACE_ID_ROYALTIES_FOUNDATION ||
            interfaceId == _INTERFACE_ID_ROYALTIES_EIP2981;
    }
}

File 3 of 22 : Signable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

library Signable {
    function recoverAddressBulk(
        uint256 tokenId,
        string[] memory _tokenURIs,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal view returns (address) {
        bytes32 h = keccak256(
            abi.encode(this, tokenId, _tokenURIs)
        );
        address _address = ecrecover(h, v, r, s);

        return _address;
    }

    function recoverAddress(
        uint256 tokenId,
        string memory _tokenURI,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal view returns (address) {
        bytes32 h = keccak256(abi.encode(this, tokenId, _tokenURI));
        address _address = ecrecover(h, v, r, s);

        return _address;
    }

    /**
     * @dev Personal: recovers the address from a personal sign from the user
     */
    function recoverPersonalAddressBulk(
        uint256 tokenId,
        string[] memory _tokenURIs,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal view returns (address) {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        bytes32 h = keccak256(
            abi.encode(this, tokenId, _tokenURIs)
        );
        bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, h));
        address _address = ecrecover(prefixedHash, v, r, s);

        return _address;
    }

    function recoverPersonalAddress(
        uint256 tokenId,
        string memory _tokenURI,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal view returns (address) {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        bytes32 h = keccak256(abi.encode(this, tokenId, _tokenURI));
        bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, h));
        address _address = ecrecover(prefixedHash, v, r, s);

        return _address;
    }
}

File 4 of 22 : ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: 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 {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_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);
    }

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

File 5 of 22 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, 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;
}

File 6 of 22 : IERC165.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);
}

File 7 of 22 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 8 of 22 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

File 9 of 22 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @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) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 10 of 22 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

File 11 of 22 : Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

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

File 12 of 22 : ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 13 of 22 : ERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC721.sol";
import "./IERC721Enumerable.sol";

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

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

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

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

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

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

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

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

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

File 14 of 22 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

File 15 of 22 : ERC721URIStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC721.sol";

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");

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

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

        return super.tokenURI(tokenId);
    }

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

    /**
     * @dev 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 override {
        super._burn(tokenId);

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

File 16 of 22 : ERC721Burnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC721.sol";
import "../../../utils/Context.sol";

/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @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 17 of 22 : Counters.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

File 18 of 22 : AccessControlEnumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IAccessControlEnumerable.sol";
import "./AccessControl.sol";
import "../utils/structs/EnumerableSet.sol";

/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
    using EnumerableSet for EnumerableSet.AddressSet;

    mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;

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

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {grantRole} to track enumerable memberships
     */
    function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
        super.grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {revokeRole} to track enumerable memberships
     */
    function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
        super.revokeRole(role, account);
        _roleMembers[role].remove(account);
    }

    /**
     * @dev Overload {renounceRole} to track enumerable memberships
     */
    function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
        super.renounceRole(role, account);
        _roleMembers[role].remove(account);
    }

    /**
     * @dev Overload {_setupRole} to track enumerable memberships
     */
    function _setupRole(bytes32 role, address account) internal virtual override {
        super._setupRole(role, account);
        _roleMembers[role].add(account);
    }
}

File 19 of 22 : IAccessControlEnumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IAccessControl.sol";

/**
 * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerable is IAccessControl {
    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}

File 20 of 22 : IAccessControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 21 of 22 : AccessControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 22 of 22 : EnumerableSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}

Settings
{
  "metadata": {
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"string","name":"contractName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"address","name":"artist","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":false,"internalType":"string","name":"_value","type":"string"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"}],"name":"PermanentURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFeeBps","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFeeRecipients","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFees","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextEditionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSignableMinting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"_tokenURI","type":"string"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint256","name":"basisPoints","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"_tokenURI","type":"string"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint256","name":"basisPoints","type":"uint256"}],"name":"mintAndTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string[]","name":"_tokenURIs","type":"string[]"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint256","name":"basisPoints","type":"uint256"}],"name":"mintEditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string[]","name":"_tokenURIs","type":"string[]"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint256","name":"basisPoints","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"mintEditionsSignable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"_tokenURI","type":"string"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint256","name":"basisPoints","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"mintSignable","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":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"val","type":"bool"}],"name":"setSignableMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526012805460ff191690553480156200001b57600080fd5b5060405162003b5938038062003b598339810160408190526200003e91620003a5565b8251839083906200005790600090602085019062000232565b5080516200006d90600190602084019062000232565b50508451620000859150601190602087019062000232565b5062000093600082620000c9565b620000bf7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a682620000c9565b5050505062000495565b620000e082826200010c60201b620013361760201c565b6000828152600e6020908152604090912062000107918390620013446200011c821b17901c565b505050565b6200011882826200013c565b5050565b600062000133836001600160a01b038416620001e0565b90505b92915050565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff1662000118576000828152600d602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200019c3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054620002295750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000136565b50600062000136565b828054620002409062000458565b90600052602060002090601f016020900481019282620002645760008555620002af565b82601f106200027f57805160ff1916838001178555620002af565b82800160010185558215620002af579182015b82811115620002af57825182559160200191906001019062000292565b50620002bd929150620002c1565b5090565b5b80821115620002bd5760008155600101620002c2565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200030057600080fd5b81516001600160401b03808211156200031d576200031d620002d8565b604051601f8301601f19908116603f01168101908282118183101715620003485762000348620002d8565b816040528381526020925086838588010111156200036557600080fd5b600091505b838210156200038957858201830151818301840152908201906200036a565b838211156200039b5760008385830101525b9695505050505050565b60008060008060808587031215620003bc57600080fd5b84516001600160401b0380821115620003d457600080fd5b620003e288838901620002ee565b95506020870151915080821115620003f957600080fd5b6200040788838901620002ee565b945060408701519150808211156200041e57600080fd5b506200042d87828801620002ee565b606087015190935090506001600160a01b03811681146200044d57600080fd5b939692955090935050565b600181811c908216806200046d57607f821691505b602082108114156200048f57634e487b7160e01b600052602260045260246000fd5b50919050565b6136b480620004a56000396000f3fe608060405234801561001057600080fd5b50600436106102485760003560e01c806370a082311161013b578063b88d4fde116100b8578063d53913931161007c578063d539139314610520578063d547741f14610535578063d5a06d4c14610548578063da14cbbc14610569578063e985e9c51461057c57600080fd5b8063b88d4fde146104bf578063b9c4d9fb146104d2578063c87b56dd146104f2578063ca15c87314610505578063caa0f92a1461051857600080fd5b806395d89b41116100ff57806395d89b4114610489578063a217fddf14610491578063a22cb46514610499578063a66b7ec9146104ac578063b273f348146104b457600080fd5b806370a08231146104355780638da5cb5b146104485780638f2bdc2e146104505780639010d07c1461046357806391d148541461047657600080fd5b80632f2ff15d116101c95780634f6ccce71161018d5780634f6ccce7146103d65780635346d1b1146103e9578063573b8e03146103fc5780636352211e1461040f578063646d11c81461042257600080fd5b80632f2ff15d146103775780632f745c591461038a57806336568abe1461039d57806342842e0e146103b057806342966c68146103c357600080fd5b806318160ddd1161021057806318160ddd146102ea57806323b872dd146102fc578063248a9ca31461030f5780632a55205a146103325780632a989d941461036457600080fd5b806301ffc9a71461024d57806306fdde0314610275578063081812fc1461028a578063095ea7b3146102b55780630ebd4c7f146102ca575b600080fd5b61026061025b366004612ae4565b6105b8565b60405190151581526020015b60405180910390f35b61027d6105d8565b60405161026c9190612b59565b61029d610298366004612b6c565b61066a565b6040516001600160a01b03909116815260200161026c565b6102c86102c3366004612b9a565b6106f7565b005b6102dd6102d8366004612b6c565b61080d565b60405161026c9190612c01565b6008545b60405190815260200161026c565b6102c861030a366004612c14565b61088a565b6102ee61031d366004612b6c565b6000908152600d602052604090206001015490565b610345610340366004612c55565b6108bc565b604080516001600160a01b03909316835260208301919091520161026c565b6102c8610372366004612c8c565b6108f9565b6102c8610385366004612ca7565b610979565b6102ee610398366004612b9a565b61099b565b6102c86103ab366004612ca7565b610a31565b6102c86103be366004612c14565b610a53565b6102c86103d1366004612b6c565b610a6e565b6102ee6103e4366004612b6c565b610ae8565b6102c86103f7366004612da7565b610b7b565b6102c861040a366004612e37565b610c80565b61029d61041d366004612b6c565b610cde565b6102c8610430366004612f40565b610d55565b6102ee610443366004612f89565b610df2565b61029d610e79565b6102c861045e366004612fa6565b610e88565b61029d610471366004612c55565b610f80565b610260610484366004612ca7565b610f9f565b61027d610fca565b6102ee600081565b6102c86104a7366004612ff4565b610fd9565b6102ee61109e565b60125460ff16610260565b6102c86104cd366004613029565b6110ce565b6104e56104e0366004612b6c565b611106565b60405161026c91906130e2565b61027d610500366004612b6c565b611189565b6102ee610513366004612b6c565b611194565b6102ee6111ab565b6102ee60008051602061365f83398151915281565b6102c8610543366004612ca7565b6111b6565b61055b610556366004612b6c565b6111c0565b60405161026c9291906130f5565b6102c8610577366004612e37565b611297565b61026061058a366004613123565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006105c382611359565b806105d257506105d28261137e565b92915050565b6060600080546105e790613151565b80601f016020809104026020016040519081016040528092919081815260200182805461061390613151565b80156106605780601f1061063557610100808354040283529160200191610660565b820191906000526020600020905b81548152906001019060200180831161064357829003601f168201915b5050505050905090565b6000610675826113cf565b6106db5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061070282610cde565b9050806001600160a01b0316836001600160a01b031614156107705760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016106d2565b336001600160a01b038216148061078c575061078c813361058a565b6107fe5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016106d2565b61080883836113ec565b505050565b60606108188261145a565b6108345760405162461bcd60e51b81526004016106d29061318c565b60408051600180825281830190925260009160208083019080368337019050506000848152600c602052604090205490915081600081518110610879576108796131b7565b602090810291909101015292915050565b610895335b82611465565b6108b15760405162461bcd60e51b81526004016106d2906131cd565b61080883838361154f565b6000806108c88461145a565b6108e45760405162461bcd60e51b81526004016106d29061318c565b6108ee84846116fa565b915091509250929050565b610904600033610f9f565b6109665760405162461bcd60e51b815260206004820152602d60248201527f5468697320616374696f6e2063616e206f6e6c7920626520706572666f726d6560448201526c3210313c9030b71030b236b4b760991b60648201526084016106d2565b6012805460ff1916911515919091179055565b6109838282611741565b6000828152600e602052604090206108089082611344565b60006109a683610df2565b8210610a085760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016106d2565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610a3b8282611767565b6000828152600e6020526040902061080890826117e1565b610808838383604051806020016040528060008152506110ce565b610a773361088f565b610adc5760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b60648201526084016106d2565b610ae5816117f6565b50565b6000610af360085490565b8210610b565760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016106d2565b60088281548110610b6957610b696131b7565b90600052602060002001549050919050565b60125460ff161515600114610ba25760405162461bcd60e51b81526004016106d29061321e565b6127118410610bc35760405162461bcd60e51b81526004016106d290613267565b6000610bcd6111ab565b90506305f5e1008110610bf25760405162461bcd60e51b81526004016106d29061329e565b6000610c0182898787876117ff565b9050610c1b60008051602061365f83398151915282610f9f565b610c5a5760405162461bcd60e51b815260206004820152601060248201526f29b4b3b730ba3ab932903bb937b7339760811b60448201526064016106d2565b610c6789838a8a8a611902565b610c75600f80546001019055565b505050505050505050565b610c9860008051602061365f83398151915233610f9f565b610cb45760405162461bcd60e51b81526004016106d2906132e6565b6000610cbe6111ab565b9050610ccc33858585611297565b610cd7338683610a53565b5050505050565b6000818152600260205260408120546001600160a01b0316806105d25760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016106d2565b610d6d60008051602061365f83398151915233610f9f565b610d895760405162461bcd60e51b81526004016106d2906132e6565b6127118110610daa5760405162461bcd60e51b81526004016106d290613267565b6001835111610dcb5760405162461bcd60e51b81526004016106d29061331d565b6000610dd561109e565b9050610de4858286868661196e565b610cd7601080546001019055565b60006001600160a01b038216610e5d5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016106d2565b506001600160a01b031660009081526003602052604090205490565b6000610e836119c3565b905090565b60125460ff161515600114610eaf5760405162461bcd60e51b81526004016106d29061321e565b6127118410610ed05760405162461bcd60e51b81526004016106d290613267565b6001865111610ef15760405162461bcd60e51b81526004016106d29061331d565b6000610efb61109e565b90506000610f0c82898787876119e3565b9050610f2660008051602061365f83398151915282610f9f565b610f655760405162461bcd60e51b815260206004820152601060248201526f29b4b3b730ba3ab932903bb937b7339760811b60448201526064016106d2565b610f7289838a8a8a61196e565b610c75601080546001019055565b6000828152600e60205260408120610f989083611a35565b9392505050565b6000918252600d602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600180546105e790613151565b6001600160a01b0382163314156110325760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016106d2565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60006305f5e1006110ae60105490565b6110b9906001613378565b6110c39190613390565b610e83906001613378565b6110d83383611465565b6110f45760405162461bcd60e51b81526004016106d2906131cd565b61110084848484611a41565b50505050565b60606111118261145a565b61112d5760405162461bcd60e51b81526004016106d29061318c565b6040805160018082528183019092526000916020808301908036833701905050905061115883611a74565b8160008151811061116b5761116b6131b7565b6001600160a01b039092166020928302919091019091015292915050565b60606105d282611ab8565b6000818152600e602052604081206105d290611c1a565b60006110c3600f5490565b610a3b8282611c24565b6060806111cc8361145a565b6111e85760405162461bcd60e51b81526004016106d29061318c565b60408051600180825281830190925260009160208083019080368337505060408051600180825281830190925292935060009291506020808301908036833701905050905061123685611a74565b82600081518110611249576112496131b7565b6001600160a01b039092166020928302919091018201526000868152600c909152604090205481600081518110611282576112826131b7565b60209081029190910101529094909350915050565b6112af60008051602061365f83398151915233610f9f565b6112cb5760405162461bcd60e51b81526004016106d2906132e6565b61271181106112ec5760405162461bcd60e51b81526004016106d290613267565b60006112f66111ab565b90506305f5e100811061131b5760405162461bcd60e51b81526004016106d29061329e565b6113288582868686611902565b610cd7600f80546001019055565b6113408282611c4a565b5050565b6000610f98836001600160a01b038416611cd0565b60006001600160e01b03198216635a05180f60e01b14806105d257506105d282611d1f565b60006001600160e01b03198216632dde656160e21b14806113af57506001600160e01b031982166335681b5360e21b145b806105d257506001600160e01b0319821663152a902d60e11b1492915050565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061142182610cde565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006105d2826113cf565b6000611470826113cf565b6114d15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016106d2565b60006114dc83610cde565b9050806001600160a01b0316846001600160a01b031614806115175750836001600160a01b031661150c8461066a565b6001600160a01b0316145b8061154757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661156282610cde565b6001600160a01b0316146115ca5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016106d2565b6001600160a01b03821661162c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016106d2565b611637838383611d44565b6116426000826113ec565b6001600160a01b038316600090815260036020526040812080546001929061166b9084906133af565b90915550506001600160a01b0382166000908152600360205260408120805460019290611699908490613378565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600080600061170885611a74565b6000868152600c602052604090205490915081906127109061172b908790613390565b61173591906133dc565b92509250509250929050565b6000828152600d602052604090206001015461175d8133611d4f565b6108088383611c4a565b6001600160a01b03811633146117d75760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016106d2565b6113408282611db3565b6000610f98836001600160a01b038416611e1a565b610ae581611f0d565b6000806040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000308888604051602001611851939291906133f0565b6040516020818303038152906040528051906020012090506000828260405160200161187e929190613417565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff8b169284019290925260608301899052608083018890529092509060019060a0016020604051602081039080840390855afa1580156118e9573d6000803e3d6000fd5b5050604051601f1901519b9a5050505050505050505050565b61190c8585611f4d565b6119168484611f67565b801561192757611927848383611ff2565b837fa109ba539900bf1b633f956d63c96fc89b814c7287f7aa50a9216d0b5565720761195286611189565b60405161195f9190612b59565b60405180910390a25050505050565b60005b83518110156119bb576119a9866119888388613378565b86848151811061199a5761199a6131b7565b60200260200101518686611902565b806119b381613439565b915050611971565b505050505050565b60006119ce81611194565b6119d85750600090565b610e83600080610f80565b6000806040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152509050600030888860405160200161185193929190613454565b6000610f98838361207b565b611a4c84848461154f565b611a58848484846120a5565b6111005760405162461bcd60e51b81526004016106d2906134cd565b6000818152600c6020908152604080832054600b9092528220546001600160a01b0316811580611aab57506001600160a01b038116155b15610f9857611547610e79565b6060611ac3826113cf565b611b295760405162461bcd60e51b815260206004820152603160248201527f45524337323155524953746f726167653a2055524920717565727920666f72206044820152703737b732bc34b9ba32b73a103a37b5b2b760791b60648201526084016106d2565b6000828152600a602052604081208054611b4290613151565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6e90613151565b8015611bbb5780601f10611b9057610100808354040283529160200191611bbb565b820191906000526020600020905b815481529060010190602001808311611b9e57829003601f168201915b505050505090506000611bcc6121b2565b9050805160001415611bdf575092915050565b815115611c11578082604051602001611bf992919061351f565b60405160208183030381529060405292505050919050565b611547846121c1565b60006105d2825490565b6000828152600d6020526040902060010154611c408133611d4f565b6108088383611db3565b611c548282610f9f565b611340576000828152600d602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611c8c3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054611d17575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d2565b5060006105d2565b60006001600160e01b03198216637965db0b60e01b14806105d257506105d28261228b565b6108088383836122b0565b611d598282610f9f565b61134057611d71816001600160a01b03166014612368565b611d7c836020612368565b604051602001611d8d92919061354e565b60408051601f198184030181529082905262461bcd60e51b82526106d291600401612b59565b611dbd8282610f9f565b15611340576000828152600d602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015611f03576000611e3e6001836133af565b8554909150600090611e52906001906133af565b9050818114611eb7576000866000018281548110611e7257611e726131b7565b9060005260206000200154905080876000018481548110611e9557611e956131b7565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611ec857611ec86135c3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d2565b60009150506105d2565b611f1681612504565b6000818152600a602052604090208054611f2f90613151565b159050610ae5576000818152600a60205260408120610ae5916129fb565b6113408282604051806020016040528060008152506125ab565b611f70826113cf565b611fd35760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b60648201526084016106d2565b6000828152600a60209081526040909120825161080892840190612a35565b600081116120425760405162461bcd60e51b815260206004820152601c60248201527f426173697320706f696e7473206d7573742062652061626f766520300000000060448201526064016106d2565b6000928352600b6020908152604080852080546001600160a01b0319166001600160a01b039590951694909417909355600c9052912055565b6000826000018281548110612092576120926131b7565b9060005260206000200154905092915050565b60006001600160a01b0384163b156121a757604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906120e99033908990889088906004016135d9565b602060405180830381600087803b15801561210357600080fd5b505af1925050508015612133575060408051601f3d908101601f1916820190925261213091810190613616565b60015b61218d573d808015612161576040519150601f19603f3d011682016040523d82523d6000602084013e612166565b606091505b5080516121855760405162461bcd60e51b81526004016106d2906134cd565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611547565b506001949350505050565b6060601180546105e790613151565b60606121cc826113cf565b6122305760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016106d2565b600061223a6121b2565b9050600081511161225a5760405180602001604052806000815250610f98565b80612264846125de565b60405160200161227592919061351f565b6040516020818303038152906040529392505050565b60006001600160e01b0319821663780e9d6360e01b14806105d257506105d2826126dc565b6001600160a01b03831661230b5761230681600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b61232e565b816001600160a01b0316836001600160a01b03161461232e5761232e838261272c565b6001600160a01b03821661234557610808816127c9565b826001600160a01b0316826001600160a01b031614610808576108088282612878565b60606000612377836002613390565b612382906002613378565b67ffffffffffffffff81111561239a5761239a612cd7565b6040519080825280601f01601f1916602001820160405280156123c4576020820181803683370190505b509050600360fc1b816000815181106123df576123df6131b7565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061240e5761240e6131b7565b60200101906001600160f81b031916908160001a9053506000612432846002613390565b61243d906001613378565b90505b60018111156124b5576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612471576124716131b7565b1a60f81b828281518110612487576124876131b7565b60200101906001600160f81b031916908160001a90535060049490941c936124ae81613633565b9050612440565b508315610f985760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106d2565b600061250f82610cde565b905061251d81600084611d44565b6125286000836113ec565b6001600160a01b03811660009081526003602052604081208054600192906125519084906133af565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6125b583836128bc565b6125c260008484846120a5565b6108085760405162461bcd60e51b81526004016106d2906134cd565b6060816126025750506040805180820190915260018152600360fc1b602082015290565b8160005b811561262c578061261681613439565b91506126259050600a836133dc565b9150612606565b60008167ffffffffffffffff81111561264757612647612cd7565b6040519080825280601f01601f191660200182016040528015612671576020820181803683370190505b5090505b8415611547576126866001836133af565b9150612693600a8661364a565b61269e906030613378565b60f81b8183815181106126b3576126b36131b7565b60200101906001600160f81b031916908160001a9053506126d5600a866133dc565b9450612675565b60006001600160e01b031982166380ac58cd60e01b148061270d57506001600160e01b03198216635b5e139f60e01b145b806105d257506301ffc9a760e01b6001600160e01b03198316146105d2565b6000600161273984610df2565b61274391906133af565b600083815260076020526040902054909150808214612796576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906127db906001906133af565b60008381526009602052604081205460088054939450909284908110612803576128036131b7565b906000526020600020015490508060088381548110612824576128246131b7565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061285c5761285c6135c3565b6001900381819060005260206000200160009055905550505050565b600061288383610df2565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166129125760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016106d2565b61291b816113cf565b156129685760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016106d2565b61297460008383611d44565b6001600160a01b038216600090815260036020526040812080546001929061299d908490613378565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b508054612a0790613151565b6000825580601f10612a17575050565b601f016020900490600052602060002090810190610ae59190612ab9565b828054612a4190613151565b90600052602060002090601f016020900481019282612a635760008555612aa9565b82601f10612a7c57805160ff1916838001178555612aa9565b82800160010185558215612aa9579182015b82811115612aa9578251825591602001919060010190612a8e565b50612ab5929150612ab9565b5090565b5b80821115612ab55760008155600101612aba565b6001600160e01b031981168114610ae557600080fd5b600060208284031215612af657600080fd5b8135610f9881612ace565b60005b83811015612b1c578181015183820152602001612b04565b838111156111005750506000910152565b60008151808452612b45816020860160208601612b01565b601f01601f19169290920160200192915050565b602081526000610f986020830184612b2d565b600060208284031215612b7e57600080fd5b5035919050565b6001600160a01b0381168114610ae557600080fd5b60008060408385031215612bad57600080fd5b8235612bb881612b85565b946020939093013593505050565b600081518084526020808501945080840160005b83811015612bf657815187529582019590820190600101612bda565b509495945050505050565b602081526000610f986020830184612bc6565b600080600060608486031215612c2957600080fd5b8335612c3481612b85565b92506020840135612c4481612b85565b929592945050506040919091013590565b60008060408385031215612c6857600080fd5b50508035926020909101359150565b80358015158114612c8757600080fd5b919050565b600060208284031215612c9e57600080fd5b610f9882612c77565b60008060408385031215612cba57600080fd5b823591506020830135612ccc81612b85565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612d1657612d16612cd7565b604052919050565b600067ffffffffffffffff831115612d3857612d38612cd7565b612d4b601f8401601f1916602001612ced565b9050828152838383011115612d5f57600080fd5b828260208301376000602084830101529392505050565b600082601f830112612d8757600080fd5b610f9883833560208501612d1e565b803560ff81168114612c8757600080fd5b600080600080600080600060e0888a031215612dc257600080fd5b8735612dcd81612b85565b9650602088013567ffffffffffffffff811115612de957600080fd5b612df58a828b01612d76565b9650506040880135612e0681612b85565b945060608801359350612e1b60808901612d96565b925060a0880135915060c0880135905092959891949750929550565b60008060008060808587031215612e4d57600080fd5b8435612e5881612b85565b9350602085013567ffffffffffffffff811115612e7457600080fd5b612e8087828801612d76565b9350506040850135612e9181612b85565b9396929550929360600135925050565b600082601f830112612eb257600080fd5b8135602067ffffffffffffffff80831115612ecf57612ecf612cd7565b8260051b612ede838201612ced565b9384528581018301938381019088861115612ef857600080fd5b84880192505b85831015612f3457823584811115612f165760008081fd5b612f248a87838c0101612d76565b8352509184019190840190612efe565b98975050505050505050565b60008060008060808587031215612f5657600080fd5b8435612f6181612b85565b9350602085013567ffffffffffffffff811115612f7d57600080fd5b612e8087828801612ea1565b600060208284031215612f9b57600080fd5b8135610f9881612b85565b600080600080600080600060e0888a031215612fc157600080fd5b8735612fcc81612b85565b9650602088013567ffffffffffffffff811115612fe857600080fd5b612df58a828b01612ea1565b6000806040838503121561300757600080fd5b823561301281612b85565b915061302060208401612c77565b90509250929050565b6000806000806080858703121561303f57600080fd5b843561304a81612b85565b9350602085013561305a81612b85565b925060408501359150606085013567ffffffffffffffff81111561307d57600080fd5b8501601f8101871361308e57600080fd5b61309d87823560208401612d1e565b91505092959194509250565b600081518084526020808501945080840160005b83811015612bf65781516001600160a01b0316875295820195908201906001016130bd565b602081526000610f9860208301846130a9565b60408152600061310860408301856130a9565b828103602084015261311a8185612bc6565b95945050505050565b6000806040838503121561313657600080fd5b823561314181612b85565b91506020830135612ccc81612b85565b600181811c9082168061316557607f821691505b6020821081141561318657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526029908201527f476c6f62616c207369676e61626c65206d696e74696e67206d757374206265206040820152683a3ab93732b21037b760b91b606082015260800190565b6020808252601c908201527f546f74616c20726f79616c746965732065786365656473203130302500000000604082015260600190565b60208082526028908201527f4d6178696d756d206e756d626572206f662073696e676c6520746f6b656e7320604082015267195e18d95959195960c21b606082015260800190565b6020808252601e908201527f5265737472696374656420746f20617070726f766564206d696e746572730000604082015260600190565b60208082526025908201527f4d757374206265206d6f7265207468616e203120746f6b656e2070657220656460408201526434ba34b7b760d91b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000821982111561338b5761338b613362565b500190565b60008160001904831182151516156133aa576133aa613362565b500290565b6000828210156133c1576133c1613362565b500390565b634e487b7160e01b600052601260045260246000fd5b6000826133eb576133eb6133c6565b500490565b60018060a01b038416815282602082015260606040820152600061311a6060830184612b2d565b60008351613429818460208801612b01565b9190910191825250602001919050565b600060001982141561344d5761344d613362565b5060010190565b60006060820160018060a01b0386168352602085818501526060604085015281855180845260808601915060808160051b870101935082870160005b828110156134be57607f198887030184526134ac868351612b2d565b95509284019290840190600101613490565b50939998505050505050505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351613531818460208801612b01565b835190830190613545818360208801612b01565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613586816017850160208801612b01565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516135b7816028840160208801612b01565b01602801949350505050565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061360c90830184612b2d565b9695505050505050565b60006020828403121561362857600080fd5b8151610f9881612ace565b60008161364257613642613362565b506000190190565b600082613659576136596133c6565b50069056fe9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6a264697066735822122027ae6fce80c33ac8c9cc9228b1e9c27385549cabca5f93ed06376046653b788864736f6c63430008090033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000e42d045c9b4d41a39d68f922c3662b078dd603400000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b563420636f6e747261637400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025634000000000000000000000000000000000000000000000000000000000000

Deployed ByteCode Sourcemap

559:8594:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8854:297;;;;;;:::i;:::-;;:::i;:::-;;;565:14:22;;558:22;540:41;;528:2;513:18;8854:297:1;;;;;;;;2414:98:7;;;:::i;:::-;;;;;;;:::i;3925:217::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:22;;;1674:51;;1662:2;1647:18;3925:217:7;1528:203:22;3463:401:7;;;;;;:::i;:::-;;:::i;:::-;;2530:305:2;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1535:111:11:-;1622:10;:17;1535:111;;;3044:25:22;;;3032:2;3017:18;1535:111:11;2898:177:22;4789:330:7;;;;;;:::i;:::-;;:::i;3917:121:3:-;;;;;;:::i;:::-;3983:7;4009:12;;;:6;:12;;;;;:22;;;;3917:121;2928:258:2;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4353:32:22;;;4335:51;;4417:2;4402:18;;4395:34;;;;4308:18;2928:258:2;4161:274:22;1514:191:1;;;;;;:::i;:::-;;:::i;1876:193:4:-;;;;;;:::i;:::-;;:::i;1211:253:11:-;;;;;;:::i;:::-;;:::i;2445:202:4:-;;;;;;:::i;:::-;;:::i;5185:179:7:-;;;;;;:::i;:::-;;:::i;451:241:10:-;;;;;;:::i;:::-;;:::i;1718:230:11:-;;;;;;:::i;:::-;;:::i;4937:812:1:-;;;;;;:::i;:::-;;:::i;3213:335::-;;;;;;:::i;:::-;;:::i;2117:235:7:-;;;;;;:::i;:::-;;:::i;4128:478:1:-;;;;;;:::i;:::-;;:::i;1855:205:7:-;;;;;;:::i;:::-;;:::i;2654:97:1:-;;;:::i;5991:855::-;;;;;;:::i;:::-;;:::i;1346:143:4:-;;;;;;:::i;:::-;;:::i;2834:137:3:-;;;;;;:::i;:::-;;:::i;2576:102:7:-;;;:::i;1952:49:3:-;;1997:4;1952:49;;4209:290:7;;;;;;:::i;:::-;;:::i;7729:134:1:-;;;:::i;1412:96::-;1485:16;;;;1412:96;;5430:320:7;;;;;;:::i;:::-;;:::i;2165:359:2:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;8290:189:1:-;;;;;;:::i;:::-;;:::i;1657:132:4:-;;;;;;:::i;:::-;;:::i;7614:109:1:-;;;:::i;1169:62::-;;-1:-1:-1;;;;;;;;;;;1169:62:1;;2157:198:4;;;;;;:::i;:::-;;:::i;1654:466:2:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3622:500:1:-;;;;;;:::i;:::-;;:::i;4565:162:7:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4685:25:7;;;4662:4;4685:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4565:162;8854:297:1;9014:4;9053:36;9077:11;9053:23;:36::i;:::-;:91;;;;9105:39;9132:11;9105:26;:39::i;:::-;9034:110;8854:297;-1:-1:-1;;8854:297:1:o;2414:98:7:-;2468:13;2500:5;2493:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2414:98;:::o;3925:217::-;4001:7;4028:16;4036:7;4028;:16::i;:::-;4020:73;;;;-1:-1:-1;;;4020:73:7;;14341:2:22;4020:73:7;;;14323:21:22;14380:2;14360:18;;;14353:30;14419:34;14399:18;;;14392:62;-1:-1:-1;;;14470:18:22;;;14463:42;14522:19;;4020:73:7;;;;;;;;;-1:-1:-1;4111:24:7;;;;:15;:24;;;;;;-1:-1:-1;;;;;4111:24:7;;3925:217::o;3463:401::-;3543:13;3559:23;3574:7;3559:14;:23::i;:::-;3543:39;;3606:5;-1:-1:-1;;;;;3600:11:7;:2;-1:-1:-1;;;;;3600:11:7;;;3592:57;;;;-1:-1:-1;;;3592:57:7;;14754:2:22;3592:57:7;;;14736:21:22;14793:2;14773:18;;;14766:30;14832:34;14812:18;;;14805:62;-1:-1:-1;;;14883:18:22;;;14876:31;14924:19;;3592:57:7;14552:397:22;3592:57:7;666:10:16;-1:-1:-1;;;;;3681:21:7;;;;:62;;-1:-1:-1;3706:37:7;3723:5;666:10:16;4565:162:7;:::i;3706:37::-;3660:165;;;;-1:-1:-1;;;3660:165:7;;15156:2:22;3660:165:7;;;15138:21:22;15195:2;15175:18;;;15168:30;15234:34;15214:18;;;15207:62;15305:26;15285:18;;;15278:54;15349:19;;3660:165:7;14954:420:22;3660:165:7;3836:21;3845:2;3849:7;3836:8;:21::i;:::-;3533:331;3463:401;;:::o;2530:305:2:-;2629:16;2669:25;2686:7;2669:16;:25::i;:::-;2661:55;;;;-1:-1:-1;;;2661:55:2;;;;;;;:::i;:::-;2750:16;;;2764:1;2750:16;;;;;;;;;2727:20;;2750:16;;;;;;;;;;;-1:-1:-1;;3542:7:2;3568:25;;;:16;:25;;;;;;2727:39;;-1:-1:-1;2776:3:2;2780:1;2776:6;;;;;;;;:::i;:::-;;;;;;;;;;:32;2825:3;2530:305;-1:-1:-1;;2530:305:2:o;4789:330:7:-;4978:41;666:10:16;4997:12:7;5011:7;4978:18;:41::i;:::-;4970:103;;;;-1:-1:-1;;;4970:103:7;;;;;;;:::i;:::-;5084:28;5094:4;5100:2;5104:7;5084:9;:28::i;2928:258:2:-;3044:7;3053;3084:25;3101:7;3084:16;:25::i;:::-;3076:55;;;;-1:-1:-1;;;3076:55:2;;;;;;;:::i;:::-;3148:31;3164:7;3173:5;3148:15;:31::i;:::-;3141:38;;;;2928:258;;;;;:::o;1514:191:1:-;1577:39;1997:4:3;1605:10:1;1577:7;:39::i;:::-;1569:97;;;;-1:-1:-1;;;1569:97:1;;16477:2:22;1569:97:1;;;16459:21:22;16516:2;16496:18;;;16489:30;16555:34;16535:18;;;16528:62;-1:-1:-1;;;16606:18:22;;;16599:43;16659:19;;1569:97:1;16275:409:22;1569:97:1;1676:16;:22;;-1:-1:-1;;1676:22:1;;;;;;;;;;1514:191::o;1876:193:4:-;1991:30;2007:4;2013:7;1991:15;:30::i;:::-;2031:18;;;;:12;:18;;;;;:31;;2054:7;2031:22;:31::i;1211:253:11:-;1308:7;1343:23;1360:5;1343:16;:23::i;:::-;1335:5;:31;1327:87;;;;-1:-1:-1;;;1327:87:11;;16891:2:22;1327:87:11;;;16873:21:22;16930:2;16910:18;;;16903:30;16969:34;16949:18;;;16942:62;-1:-1:-1;;;17020:18:22;;;17013:41;17071:19;;1327:87:11;16689:407:22;1327:87:11;-1:-1:-1;;;;;;1431:19:11;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;1211:253::o;2445:202:4:-;2563:33;2582:4;2588:7;2563:18;:33::i;:::-;2606:18;;;;:12;:18;;;;;:34;;2632:7;2606:25;:34::i;5185:179:7:-;5318:39;5335:4;5341:2;5345:7;5318:39;;;;;;;;;;;;:16;:39::i;451:241:10:-;567:41;666:10:16;586:12:10;587:96:16;567:41:10;559:102;;;;-1:-1:-1;;;559:102:10;;17303:2:22;559:102:10;;;17285:21:22;17342:2;17322:18;;;17315:30;17381:34;17361:18;;;17354:62;-1:-1:-1;;;17432:18:22;;;17425:46;17488:19;;559:102:10;17101:412:22;559:102:10;671:14;677:7;671:5;:14::i;:::-;451:241;:::o;1718:230:11:-;1793:7;1828:30;1622:10;:17;;1535:111;1828:30;1820:5;:38;1812:95;;;;-1:-1:-1;;;1812:95:11;;17720:2:22;1812:95:11;;;17702:21:22;17759:2;17739:18;;;17732:30;17798:34;17778:18;;;17771:62;-1:-1:-1;;;17849:18:22;;;17842:42;17901:19;;1812:95:11;17518:408:22;1812:95:11;1924:10;1935:5;1924:17;;;;;;;;:::i;:::-;;;;;;;;;1917:24;;1718:230;;;:::o;4937:812:1:-;5161:16;;;;:24;;:16;:24;5153:78;;;;-1:-1:-1;;;5153:78:1;;;;;;;:::i;:::-;5263:5;5249:11;:19;5241:60;;;;-1:-1:-1;;;5241:60:1;;;;;;;:::i;:::-;5311:15;5329:16;:14;:16::i;:::-;5311:34;;1016:9;5376:7;:22;5355:109;;;;-1:-1:-1;;;5355:109:1;;;;;;;:::i;:::-;5475:18;5496:60;5528:7;5537:9;5548:1;5551;5554;5496:31;:60::i;:::-;5475:81;;5583:32;-1:-1:-1;;;;;;;;;;;5604:10:1;5583:7;:32::i;:::-;5575:61;;;;-1:-1:-1;;;5575:61:1;;19309:2:22;5575:61:1;;;19291:21:22;19348:2;19328:18;;;19321:30;-1:-1:-1;;;19367:18:22;;;19360:46;19423:18;;5575:61:1;19107:340:22;5575:61:1;5647:58;5659:2;5663:7;5672:9;5683:8;5693:11;5647;:58::i;:::-;5715:27;:15;978:19:17;;996:1;978:19;;;891:123;5715:27:1;5143:606;;4937:812;;;;;;;:::o;3213:335::-;3122:32;-1:-1:-1;;;;;;;;;;;3143:10:1;3122:7;:32::i;:::-;3114:75;;;;-1:-1:-1;;;3114:75:1;;;;;;;:::i;:::-;3388:19:::1;3410:16;:14;:16::i;:::-;3388:38;;3436:50;3441:10;3453:9;3464:8;3474:11;3436:4;:50::i;:::-;3496:45;3513:10;3525:2;3529:11;3496:16;:45::i;:::-;3378:170;3213:335:::0;;;;:::o;2117:235:7:-;2189:7;2224:16;;;:7;:16;;;;;;-1:-1:-1;;;;;2224:16:7;2258:19;2250:73;;;;-1:-1:-1;;;2250:73:7;;20013:2:22;2250:73:7;;;19995:21:22;20052:2;20032:18;;;20025:30;20091:34;20071:18;;;20064:62;-1:-1:-1;;;20142:18:22;;;20135:39;20191:19;;2250:73:7;19811:405:22;4128:478:1;3122:32;-1:-1:-1;;;;;;;;;;;3143:10:1;3122:7;:32::i;:::-;3114:75;;;;-1:-1:-1;;;3114:75:1;;;;;;;:::i;:::-;4325:5:::1;4311:11;:19;4303:60;;;;-1:-1:-1::0;;;4303:60:1::1;;;;;;;:::i;:::-;4401:1;4381:10;:17;:21;4373:71;;;;-1:-1:-1::0;;;4373:71:1::1;;;;;;;:::i;:::-;4455:15;4473:18;:16;:18::i;:::-;4455:36;;4501:61;4515:2;4519:7;4528:10;4540:8;4550:11;4501:13;:61::i;:::-;4572:27;:15;978:19:17::0;;996:1;978:19;;;891:123;1855:205:7;1927:7;-1:-1:-1;;;;;1954:19:7;;1946:74;;;;-1:-1:-1;;;1946:74:7;;20829:2:22;1946:74:7;;;20811:21:22;20868:2;20848:18;;;20841:30;20907:34;20887:18;;;20880:62;-1:-1:-1;;;20958:18:22;;;20951:40;21008:19;;1946:74:7;20627:406:22;1946:74:7;-1:-1:-1;;;;;;2037:16:7;;;;;:9;:16;;;;;;;1855:205::o;2654:97:1:-;2700:7;2726:18;:16;:18::i;:::-;2719:25;;2654:97;:::o;5991:855::-;6226:16;;;;:24;;:16;:24;6218:78;;;;-1:-1:-1;;;6218:78:1;;;;;;;:::i;:::-;6328:5;6314:11;:19;6306:60;;;;-1:-1:-1;;;6306:60:1;;;;;;;:::i;:::-;6404:1;6384:10;:17;:21;6376:71;;;;-1:-1:-1;;;6376:71:1;;;;;;;:::i;:::-;6457:15;6475:18;:16;:18::i;:::-;6457:36;;6503:18;6524:135;6573:7;6594:10;6618:1;6633;6648;6524:35;:135::i;:::-;6503:156;;6677:32;-1:-1:-1;;;;;;;;;;;6698:10:1;6677:7;:32::i;:::-;6669:61;;;;-1:-1:-1;;;6669:61:1;;19309:2:22;6669:61:1;;;19291:21:22;19348:2;19328:18;;;19321:30;-1:-1:-1;;;19367:18:22;;;19360:46;19423:18;;6669:61:1;19107:340:22;6669:61:1;6741;6755:2;6759:7;6768:10;6780:8;6790:11;6741:13;:61::i;:::-;6812:27;:15;978:19:17;;996:1;978:19;;;891:123;1346:143:4;1428:7;1454:18;;;:12;:18;;;;;:28;;1476:5;1454:21;:28::i;:::-;1447:35;1346:143;-1:-1:-1;;;1346:143:4:o;2834:137:3:-;2912:4;2935:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;2935:29:3;;;;;;;;;;;;;;;2834:137::o;2576:102:7:-;2632:13;2664:7;2657:14;;;;;:::i;4209:290::-;-1:-1:-1;;;;;4311:24:7;;666:10:16;4311:24:7;;4303:62;;;;-1:-1:-1;;;4303:62:7;;21240:2:22;4303:62:7;;;21222:21:22;21279:2;21259:18;;;21252:30;21318:27;21298:18;;;21291:55;21363:18;;4303:62:7;21038:349:22;4303:62:7;666:10:16;4376:32:7;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;4376:42:7;;;;;;;;;;;;:53;;-1:-1:-1;;4376:53:7;;;;;;;;;;4444:48;;540:41:22;;;4376:42:7;;666:10:16;4444:48:7;;513:18:22;4444:48:7;;;;;;;4209:290;;:::o;7729:134:1:-;7778:7;1016:9;7806:25;:15;864:14:17;;773:112;7806:25:1;:29;;7834:1;7806:29;:::i;:::-;7805:46;;;;:::i;:::-;7804:52;;7855:1;7804:52;:::i;5430:320:7:-;5599:41;666:10:16;5632:7:7;5599:18;:41::i;:::-;5591:103;;;;-1:-1:-1;;;5591:103:7;;;;;;;:::i;:::-;5704:39;5718:4;5724:2;5728:7;5737:5;5704:13;:39::i;:::-;5430:320;;;;:::o;2165:359:2:-;2271:24;2319:25;2336:7;2319:16;:25::i;:::-;2311:55;;;;-1:-1:-1;;;2311:55:2;;;;;;;:::i;:::-;2414:24;;;2436:1;2414:24;;;;;;;;;2377:34;;2414:24;;;;;;;;;;;-1:-1:-1;2414:24:2;2377:61;;2463:28;2483:7;2463:19;:28::i;:::-;2448:9;2458:1;2448:12;;;;;;;;:::i;:::-;-1:-1:-1;;;;;2448:43:2;;;:12;;;;;;;;;;;:43;2508:9;2165:359;-1:-1:-1;;2165:359:2:o;8290:189:1:-;8413:13;8449:23;8464:7;8449:14;:23::i;1657:132:4:-;1729:7;1755:18;;;:12;:18;;;;;:27;;:25;:27::i;7614:109:1:-;7661:7;7687:25;:15;864:14:17;;773:112;2157:198:4;2273:31;2290:4;2296:7;2273:16;:31::i;1654:466:2:-;1751:24;1777:16;1817:25;1834:7;1817:16;:25::i;:::-;1809:55;;;;-1:-1:-1;;;1809:55:2;;;;;;;:::i;:::-;1912:24;;;1934:1;1912:24;;;;;;;;;1875:34;;1912:24;;;;;;;;;-1:-1:-1;;1969:16:2;;;1983:1;1969:16;;;;;;;;;1875:61;;-1:-1:-1;1946:20:2;;1969:16;-1:-1:-1;1969:16:2;;;;;;;;;;;-1:-1:-1;1969:16:2;1946:39;;2010:28;2030:7;2010:19;:28::i;:::-;1995:9;2005:1;1995:12;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1995:43:2;;;:12;;;;;;;;;;:43;3542:7;3568:25;;;:16;:25;;;;;;;2048:3;2052:1;2048:6;;;;;;;;:::i;:::-;;;;;;;;;;:32;2098:9;;2109:3;;-1:-1:-1;1654:466:2;-1:-1:-1;;1654:466:2:o;3622:500:1:-;3122:32;-1:-1:-1;;;;;;;;;;;3143:10:1;3122:7;:32::i;:::-;3114:75;;;;-1:-1:-1;;;3114:75:1;;;;;;;:::i;:::-;3808:5:::1;3794:11;:19;3786:60;;;;-1:-1:-1::0;;;3786:60:1::1;;;;;;;:::i;:::-;3856:15;3874:16;:14;:16::i;:::-;3856:34;;1016:9;3921:7;:22;3900:109;;;;-1:-1:-1::0;;;3900:109:1::1;;;;;;;:::i;:::-;4020:58;4032:2;4036:7;4045:9;4056:8;4066:11;4020;:58::i;:::-;4088:27;:15;978:19:17::0;;996:1;978:19;;;891:123;6084:110:3;6162:25;6173:4;6179:7;6162:10;:25::i;:::-;6084:110;;:::o;7545:150:21:-;7615:4;7638:50;7643:3;-1:-1:-1;;;;;7663:23:21;;7638:4;:50::i;549:212:4:-;634:4;-1:-1:-1;;;;;;657:57:4;;-1:-1:-1;;;657:57:4;;:97;;;718:36;742:11;718:23;:36::i;4305:322:2:-;4408:4;-1:-1:-1;;;;;;4447:46:2;;-1:-1:-1;;;4447:46:2;;:111;;-1:-1:-1;;;;;;;4509:49:2;;-1:-1:-1;;;4509:49:2;4447:111;:173;;;-1:-1:-1;;;;;;;4574:46:2;;-1:-1:-1;;;4574:46:2;4428:192;4305:322;-1:-1:-1;;4305:322:2:o;7222:125:7:-;7287:4;7310:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7310:16:7;:30;;;7222:125::o;11074:171::-;11148:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;11148:29:7;-1:-1:-1;;;;;11148:29:7;;;;;;;;:24;;11201:23;11148:24;11201:14;:23::i;:::-;-1:-1:-1;;;;;11192:46:7;;;;;;;;;;;11074:171;;:::o;8485:190:1:-;8619:4;8646:22;8660:7;8646:13;:22::i;7506:344:7:-;7599:4;7623:16;7631:7;7623;:16::i;:::-;7615:73;;;;-1:-1:-1;;;7615:73:7;;22032:2:22;7615:73:7;;;22014:21:22;22071:2;22051:18;;;22044:30;22110:34;22090:18;;;22083:62;-1:-1:-1;;;22161:18:22;;;22154:42;22213:19;;7615:73:7;21830:408:22;7615:73:7;7698:13;7714:23;7729:7;7714:14;:23::i;:::-;7698:39;;7766:5;-1:-1:-1;;;;;7755:16:7;:7;-1:-1:-1;;;;;7755:16:7;;:51;;;;7799:7;-1:-1:-1;;;;;7775:31:7;:20;7787:7;7775:11;:20::i;:::-;-1:-1:-1;;;;;7775:31:7;;7755:51;:87;;;-1:-1:-1;;;;;;4685:25:7;;;4662:4;4685:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;7810:32;7747:96;7506:344;-1:-1:-1;;;;7506:344:7:o;10403:560::-;10557:4;-1:-1:-1;;;;;10530:31:7;:23;10545:7;10530:14;:23::i;:::-;-1:-1:-1;;;;;10530:31:7;;10522:85;;;;-1:-1:-1;;;10522:85:7;;22445:2:22;10522:85:7;;;22427:21:22;22484:2;22464:18;;;22457:30;22523:34;22503:18;;;22496:62;-1:-1:-1;;;22574:18:22;;;22567:39;22623:19;;10522:85:7;22243:405:22;10522:85:7;-1:-1:-1;;;;;10625:16:7;;10617:65;;;;-1:-1:-1;;;10617:65:7;;22855:2:22;10617:65:7;;;22837:21:22;22894:2;22874:18;;;22867:30;22933:34;22913:18;;;22906:62;-1:-1:-1;;;22984:18:22;;;22977:34;23028:19;;10617:65:7;22653:400:22;10617:65:7;10693:39;10714:4;10720:2;10724:7;10693:20;:39::i;:::-;10794:29;10811:1;10815:7;10794:8;:29::i;:::-;-1:-1:-1;;;;;10834:15:7;;;;;;:9;:15;;;;;:20;;10853:1;;10834:15;:20;;10853:1;;10834:20;:::i;:::-;;;;-1:-1:-1;;;;;;;10864:13:7;;;;;;:9;:13;;;;;:18;;10881:1;;10864:13;:18;;10881:1;;10864:18;:::i;:::-;;;;-1:-1:-1;;10892:16:7;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;10892:21:7;-1:-1:-1;;;;;10892:21:7;;;;;;;;;10929:27;;10892:16;;10929:27;;;;;;;10403:560;;;:::o;3192:280:2:-;3296:16;3314:14;3344:17;3364:28;3384:7;3364:19;:28::i;:::-;3422:25;;;;:16;:25;;;;;;3344:48;;-1:-1:-1;3344:48:2;;3459:5;;3422:33;;3450:5;;3422:33;:::i;:::-;3421:43;;;;:::i;:::-;3402:63;;;;;3192:280;;;;;:::o;4288:145:3:-;3983:7;4009:12;;;:6;:12;;;;;:22;;;2430:30;2441:4;666:10:16;2430::3;:30::i;:::-;4401:25:::1;4412:4;4418:7;4401:10;:25::i;5305:214::-:0;-1:-1:-1;;;;;5400:23:3;;666:10:16;5400:23:3;5392:83;;;;-1:-1:-1;;;5392:83:3;;23647:2:22;5392:83:3;;;23629:21:22;23686:2;23666:18;;;23659:30;23725:34;23705:18;;;23698:62;-1:-1:-1;;;23776:18:22;;;23769:45;23831:19;;5392:83:3;23445:411:22;5392:83:3;5486:26;5498:4;5504:7;5486:11;:26::i;7863:156:21:-;7936:4;7959:53;7967:3;-1:-1:-1;;;;;7987:23:21;;7959:7;:53::i;8151:133:1:-;8257:20;8269:7;8257:11;:20::i;1389:483:0:-;1563:7;1582:19;:56;;;;;;;;;;;;;;;;;;;1648:9;1681:4;1687:7;1696:9;1670:36;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1660:47;;;;;;1648:59;;1717:20;1767:6;1775:1;1750:27;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1750:27:0;;;;;;;;;1740:38;;1750:27;1740:38;;;;1788:16;1807:32;;;;;;;;;24872:25:22;;;24945:4;24933:17;;24913:18;;;24906:45;;;;24967:18;;;24960:34;;;25010:18;;;25003:34;;;1740:38:0;;-1:-1:-1;1788:16:0;1807:32;;24844:19:22;;1807:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1807:32:0;;-1:-1:-1;;1807:32:0;;;1389:483;-1:-1:-1;;;;;;;;;;;1389:483:0:o;7195:413:1:-;7382:22;7392:2;7396:7;7382:9;:22::i;:::-;7414:32;7427:7;7436:9;7414:12;:32::i;:::-;7460:15;;7456:91;;7491:45;7505:7;7514:8;7524:11;7491:13;:45::i;:::-;7593:7;7561:40;7574:17;7583:7;7574:8;:17::i;:::-;7561:40;;;;;;:::i;:::-;;;;;;;;7195:413;;;;;:::o;6852:337::-;7049:9;7044:139;7068:10;:17;7064:1;:21;7044:139;;;7106:66;7118:2;7122:11;7132:1;7122:7;:11;:::i;:::-;7135:10;7146:1;7135:13;;;;;;;;:::i;:::-;;;;;;;7150:8;7160:11;7106;:66::i;:::-;7087:3;;;;:::i;:::-;;;;7044:139;;;;6852:337;;;;;:::o;2757:228::-;2816:7;2839:38;2816:7;2839:18;:38::i;:::-;2835:91;;-1:-1:-1;2913:1:1;;2757:228::o;2835:91::-;2942:36;1997:4:3;;2942:13:1;:36::i;870:513:0:-;1051:7;1070:19;:56;;;;;;;;;;;;;;;;;;;1136:9;1182:4;1188:7;1197:10;1171:37;;;;;;;;;;:::i;8803:156:21:-;8877:7;8927:22;8931:3;8943:5;8927:3;:22::i;6612:307:7:-;6763:28;6773:4;6779:2;6783:7;6763:9;:28::i;:::-;6809:48;6832:4;6838:2;6842:7;6851:5;6809:22;:48::i;:::-;6801:111;;;;-1:-1:-1;;;6801:111:7;;;;;;;:::i;3606:576:2:-;3699:15;3568:25;;;:16;:25;;;;;;;;;3804:21;:30;;;;;;-1:-1:-1;;;;;3804:30:2;3848:8;;;:34;;-1:-1:-1;;;;;;3860:22:2;;;3848:34;3844:306;;;4117:21;:19;:21::i;387:663:12:-;460:13;493:16;501:7;493;:16::i;:::-;485:78;;;;-1:-1:-1;;;485:78:12;;26804:2:22;485:78:12;;;26786:21:22;26843:2;26823:18;;;26816:30;26882:34;26862:18;;;26855:62;-1:-1:-1;;;26933:18:22;;;26926:47;26990:19;;485:78:12;26602:413:22;485:78:12;574:23;600:19;;;:10;:19;;;;;574:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;629:18;650:10;:8;:10::i;:::-;629:31;;739:4;733:18;755:1;733:23;729:70;;;-1:-1:-1;779:9:12;387:663;-1:-1:-1;;387:663:12:o;729:70::-;901:23;;:27;897:106;;975:4;981:9;958:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;944:48;;;;387:663;;;:::o;897:106::-;1020:23;1035:7;1020:14;:23::i;8346:115:21:-;8409:7;8435:19;8443:3;3961:18;;3879:107;4667:147:3;3983:7;4009:12;;;:6;:12;;;;;:22;;;2430:30;2441:4;666:10:16;2430::3;:30::i;:::-;4781:26:::1;4793:4;4799:7;4781:11;:26::i;6572:224::-:0;6646:22;6654:4;6660:7;6646;:22::i;:::-;6641:149;;6684:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;6684:29:3;;;;;;;;;:36;;-1:-1:-1;;6684:36:3;6716:4;6684:36;;;6766:12;666:10:16;;587:96;6766:12:3;-1:-1:-1;;;;;6739:40:3;6757:7;-1:-1:-1;;;;;6739:40:3;6751:4;6739:40;;;;;;;;;;6572:224;;:::o;1630:404:21:-;1693:4;3767:19;;;:12;;;:19;;;;;;1709:319;;-1:-1:-1;1751:23:21;;;;;;;;:11;:23;;;;;;;;;;;;;1931:18;;1909:19;;;:12;;;:19;;;;;;:40;;;;1963:11;;1709:319;-1:-1:-1;2012:5:21;2005:12;;2545:202:3;2630:4;-1:-1:-1;;;;;;2653:47:3;;-1:-1:-1;;;2653:47:3;;:87;;;2704:36;2728:11;2704:23;:36::i;7936:209:1:-;8093:45;8120:4;8126:2;8130:7;8093:26;:45::i;3252:484:3:-;3332:22;3340:4;3346:7;3332;:22::i;:::-;3327:403;;3515:41;3543:7;-1:-1:-1;;;;;3515:41:3;3553:2;3515:19;:41::i;:::-;3627:38;3655:4;3662:2;3627:19;:38::i;:::-;3422:265;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;3422:265:3;;;;;;;;;;-1:-1:-1;;;3370:349:3;;;;;;;:::i;6802:225::-;6876:22;6884:4;6890:7;6876;:22::i;:::-;6872:149;;;6946:5;6914:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;6914:29:3;;;;;;;;;;:37;;-1:-1:-1;;6914:37:3;;;6970:40;666:10:16;;6914:12:3;;6970:40;;6946:5;6970:40;6802:225;;:::o;2202:1388:21:-;2268:4;2405:19;;;:12;;;:19;;;;;;2439:15;;2435:1149;;2808:21;2832:14;2845:1;2832:10;:14;:::i;:::-;2880:18;;2808:38;;-1:-1:-1;2860:17:21;;2880:22;;2901:1;;2880:22;:::i;:::-;2860:42;;2934:13;2921:9;:26;2917:398;;2967:17;2987:3;:11;;2999:9;2987:22;;;;;;;;:::i;:::-;;;;;;;;;2967:42;;3138:9;3109:3;:11;;3121:13;3109:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3221:23;;;:12;;;:23;;;;;:36;;;2917:398;3393:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3485:3;:12;;:19;3498:5;3485:19;;;;;;;;;;;3478:26;;;3526:4;3519:11;;;;;;;2435:1149;3568:5;3561:12;;;;;1628:200:12;1696:20;1708:7;1696:11;:20::i;:::-;1737:19;;;;:10;:19;;;;;1731:33;;;;;:::i;:::-;:38;;-1:-1:-1;1727:95:12;;1792:19;;;;:10;:19;;;;;1785:26;;;:::i;8180:108:7:-;8255:26;8265:2;8269:7;8255:26;;;;;;;;;;;;:9;:26::i;1197:214:12:-;1296:16;1304:7;1296;:16::i;:::-;1288:75;;;;-1:-1:-1;;;1288:75:12;;28620:2:22;1288:75:12;;;28602:21:22;28659:2;28639:18;;;28632:30;28698:34;28678:18;;;28671:62;-1:-1:-1;;;28749:18:22;;;28742:44;28803:19;;1288:75:12;28418:410:22;1288:75:12;1373:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;1242:299:2:-;1400:1;1386:11;:15;1378:56;;;;-1:-1:-1;;;1378:56:2;;29035:2:22;1378:56:2;;;29017:21:22;29074:2;29054:18;;;29047:30;29113;29093:18;;;29086:58;29161:18;;1378:56:2;28833:352:22;1378:56:2;1444:30;;;;:21;:30;;;;;;;;:41;;-1:-1:-1;;;;;;1444:41:2;-1:-1:-1;;;;;1444:41:2;;;;;;;;;;;1495:16;:25;;;;:39;1242:299::o;4328:118:21:-;4395:7;4421:3;:11;;4433:5;4421:18;;;;;;;;:::i;:::-;;;;;;;;;4414:25;;4328:118;;;;:::o;11798:778:7:-;11948:4;-1:-1:-1;;;;;11968:13:7;;1034:20:15;1080:8;11964:606:7;;12003:72;;-1:-1:-1;;;12003:72:7;;-1:-1:-1;;;;;12003:36:7;;;;;:72;;666:10:16;;12054:4:7;;12060:7;;12069:5;;12003:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12003:72:7;;;;;;;;-1:-1:-1;;12003:72:7;;;;;;;;;;;;:::i;:::-;;;11999:519;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12242:13:7;;12238:266;;12284:60;;-1:-1:-1;;;12284:60:7;;;;;;;:::i;12238:266::-;12456:6;12450:13;12441:6;12437:2;12433:15;12426:38;11999:519;-1:-1:-1;;;;;;12125:51:7;-1:-1:-1;;;12125:51:7;;-1:-1:-1;12118:58:7;;11964:606;-1:-1:-1;12555:4:7;11798:778;;;;;;:::o;2335:107:1:-;2387:13;2419:16;2412:23;;;;;:::i;2744:329:7:-;2817:13;2850:16;2858:7;2850;:16::i;:::-;2842:76;;;;-1:-1:-1;;;2842:76:7;;30140:2:22;2842:76:7;;;30122:21:22;30179:2;30159:18;;;30152:30;30218:34;30198:18;;;30191:62;-1:-1:-1;;;30269:18:22;;;30262:45;30324:19;;2842:76:7;29938:411:22;2842:76:7;2929:21;2953:10;:8;:10::i;:::-;2929:34;;3004:1;2986:7;2980:21;:25;:86;;;;;;;;;;;;;;;;;3032:7;3041:18;:7;:16;:18::i;:::-;3015:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2973:93;2744:329;-1:-1:-1;;;2744:329:7:o;910:222:11:-;1012:4;-1:-1:-1;;;;;;1035:50:11;;-1:-1:-1;;;1035:50:11;;:90;;;1089:36;1113:11;1089:23;:36::i;2544:572::-;-1:-1:-1;;;;;2743:18:11;;2739:183;;2777:40;2809:7;3925:10;:17;;3898:24;;;;:15;:24;;;;;:44;;;3952:24;;;;;;;;;;;;3822:161;2777:40;2739:183;;;2846:2;-1:-1:-1;;;;;2838:10:11;:4;-1:-1:-1;;;;;2838:10:11;;2834:88;;2864:47;2897:4;2903:7;2864:32;:47::i;:::-;-1:-1:-1;;;;;2935:16:11;;2931:179;;2967:45;3004:7;2967:36;:45::i;2931:179::-;3039:4;-1:-1:-1;;;;;3033:10:11;:2;-1:-1:-1;;;;;3033:10:11;;3029:81;;3059:40;3087:2;3091:7;3059:27;:40::i;1535:441:18:-;1610:13;1635:19;1667:10;1671:6;1667:1;:10;:::i;:::-;:14;;1680:1;1667:14;:::i;:::-;1657:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1657:25:18;;1635:47;;-1:-1:-1;;;1692:6:18;1699:1;1692:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1692:15:18;;;;;;;;;-1:-1:-1;;;1717:6:18;1724:1;1717:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1717:15:18;;;;;;;;-1:-1:-1;1747:9:18;1759:10;1763:6;1759:1;:10;:::i;:::-;:14;;1772:1;1759:14;:::i;:::-;1747:26;;1742:132;1779:1;1775;:5;1742:132;;;-1:-1:-1;;;1826:5:18;1834:3;1826:11;1813:25;;;;;;;:::i;:::-;;;;1801:6;1808:1;1801:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;1801:37:18;;;;;;;;-1:-1:-1;1862:1:18;1852:11;;;;;1782:3;;;:::i;:::-;;;1742:132;;;-1:-1:-1;1891:10:18;;1883:55;;;;-1:-1:-1;;;1883:55:18;;30697:2:22;1883:55:18;;;30679:21:22;;;30716:18;;;30709:30;30775:34;30755:18;;;30748:62;30827:18;;1883:55:18;30495:356:22;9731:348:7;9790:13;9806:23;9821:7;9806:14;:23::i;:::-;9790:39;;9840:48;9861:5;9876:1;9880:7;9840:20;:48::i;:::-;9926:29;9943:1;9947:7;9926:8;:29::i;:::-;-1:-1:-1;;;;;9966:16:7;;;;;;:9;:16;;;;;:21;;9986:1;;9966:16;:21;;9986:1;;9966:21;:::i;:::-;;;;-1:-1:-1;;10004:16:7;;;;:7;:16;;;;;;9997:23;;-1:-1:-1;;;;;;9997:23:7;;;10036:36;10012:7;;10004:16;-1:-1:-1;;;;;10036:36:7;;;;;10004:16;;10036:36;9780:299;9731:348;:::o;8509:311::-;8634:18;8640:2;8644:7;8634:5;:18::i;:::-;8683:54;8714:1;8718:2;8722:7;8731:5;8683:22;:54::i;:::-;8662:151;;;;-1:-1:-1;;;8662:151:7;;;;;;;:::i;275:703:18:-;331:13;548:10;544:51;;-1:-1:-1;;574:10:18;;;;;;;;;;;;-1:-1:-1;;;574:10:18;;;;;275:703::o;544:51::-;619:5;604:12;658:75;665:9;;658:75;;690:8;;;;:::i;:::-;;-1:-1:-1;712:10:18;;-1:-1:-1;720:2:18;712:10;;:::i;:::-;;;658:75;;;742:19;774:6;764:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;764:17:18;;742:39;;791:150;798:10;;791:150;;824:11;834:1;824:11;;:::i;:::-;;-1:-1:-1;892:10:18;900:2;892:5;:10;:::i;:::-;879:24;;:2;:24;:::i;:::-;866:39;;849:6;856;849:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;849:56:18;;;;;;;;-1:-1:-1;919:11:18;928:2;919:11;;:::i;:::-;;;791:150;;1496:300:7;1598:4;-1:-1:-1;;;;;;1633:40:7;;-1:-1:-1;;;1633:40:7;;:104;;-1:-1:-1;;;;;;;1689:48:7;;-1:-1:-1;;;1689:48:7;1633:104;:156;;;-1:-1:-1;;;;;;;;;;871:40:19;;;1753:36:7;763:155:19;4600:970:11;4862:22;4912:1;4887:22;4904:4;4887:16;:22::i;:::-;:26;;;;:::i;:::-;4923:18;4944:26;;;:17;:26;;;;;;4862:51;;-1:-1:-1;5074:28:11;;;5070:323;;-1:-1:-1;;;;;5140:18:11;;5118:19;5140:18;;;:12;:18;;;;;;;;:34;;;;;;;;;5189:30;;;;;;:44;;;5305:30;;:17;:30;;;;;:43;;;5070:323;-1:-1:-1;5486:26:11;;;;:17;:26;;;;;;;;5479:33;;;-1:-1:-1;;;;;5529:18:11;;;;;:12;:18;;;;;:34;;;;;;;5522:41;4600:970::o;5858:1061::-;6132:10;:17;6107:22;;6132:21;;6152:1;;6132:21;:::i;:::-;6163:18;6184:24;;;:15;:24;;;;;;6552:10;:26;;6107:46;;-1:-1:-1;6184:24:11;;6107:46;;6552:26;;;;;;:::i;:::-;;;;;;;;;6530:48;;6614:11;6589:10;6600;6589:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;6693:28;;;:15;:28;;;;;;;:41;;;6862:24;;;;;6855:31;6896:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;5929:990;;;5858:1061;:::o;3410:217::-;3494:14;3511:20;3528:2;3511:16;:20::i;:::-;-1:-1:-1;;;;;3541:16:11;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;3585:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;3410:217:11:o;9142:372:7:-;-1:-1:-1;;;;;9221:16:7;;9213:61;;;;-1:-1:-1;;;9213:61:7;;31175:2:22;9213:61:7;;;31157:21:22;;;31194:18;;;31187:30;31253:34;31233:18;;;31226:62;31305:18;;9213:61:7;30973:356:22;9213:61:7;9293:16;9301:7;9293;:16::i;:::-;9292:17;9284:58;;;;-1:-1:-1;;;9284:58:7;;31536:2:22;9284:58:7;;;31518:21:22;31575:2;31555:18;;;31548:30;31614;31594:18;;;31587:58;31662:18;;9284:58:7;31334:352:22;9284:58:7;9353:45;9382:1;9386:2;9390:7;9353:20;:45::i;:::-;-1:-1:-1;;;;;9409:13:7;;;;;;:9;:13;;;;;:18;;9426:1;;9409:13;:18;;9426:1;;9409:18;:::i;:::-;;;;-1:-1:-1;;9437:16:7;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9437:21:7;-1:-1:-1;;;;;9437:21:7;;;;;;;;9474:33;;9437:16;;;9474:33;;9437:16;;9474:33;9142:372;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:22;-1:-1:-1;;;;;;88:32:22;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:22;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:22;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:22:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:22;;1343:180;-1:-1:-1;1343:180:22:o;1736:131::-;-1:-1:-1;;;;;1811:31:22;;1801:42;;1791:70;;1857:1;1854;1847:12;1872:315;1940:6;1948;2001:2;1989:9;1980:7;1976:23;1972:32;1969:52;;;2017:1;2014;2007:12;1969:52;2056:9;2043:23;2075:31;2100:5;2075:31;:::i;:::-;2125:5;2177:2;2162:18;;;;2149:32;;-1:-1:-1;;;1872:315:22:o;2192:435::-;2245:3;2283:5;2277:12;2310:6;2305:3;2298:19;2336:4;2365:2;2360:3;2356:12;2349:19;;2402:2;2395:5;2391:14;2423:1;2433:169;2447:6;2444:1;2441:13;2433:169;;;2508:13;;2496:26;;2542:12;;;;2577:15;;;;2469:1;2462:9;2433:169;;;-1:-1:-1;2618:3:22;;2192:435;-1:-1:-1;;;;;2192:435:22:o;2632:261::-;2811:2;2800:9;2793:21;2774:4;2831:56;2883:2;2872:9;2868:18;2860:6;2831:56;:::i;3080:456::-;3157:6;3165;3173;3226:2;3214:9;3205:7;3201:23;3197:32;3194:52;;;3242:1;3239;3232:12;3194:52;3281:9;3268:23;3300:31;3325:5;3300:31;:::i;:::-;3350:5;-1:-1:-1;3407:2:22;3392:18;;3379:32;3420:33;3379:32;3420:33;:::i;:::-;3080:456;;3472:7;;-1:-1:-1;;;3526:2:22;3511:18;;;;3498:32;;3080:456::o;3908:248::-;3976:6;3984;4037:2;4025:9;4016:7;4012:23;4008:32;4005:52;;;4053:1;4050;4043:12;4005:52;-1:-1:-1;;4076:23:22;;;4146:2;4131:18;;;4118:32;;-1:-1:-1;3908:248:22:o;4440:160::-;4505:20;;4561:13;;4554:21;4544:32;;4534:60;;4590:1;4587;4580:12;4534:60;4440:160;;;:::o;4605:180::-;4661:6;4714:2;4702:9;4693:7;4689:23;4685:32;4682:52;;;4730:1;4727;4720:12;4682:52;4753:26;4769:9;4753:26;:::i;4790:315::-;4858:6;4866;4919:2;4907:9;4898:7;4894:23;4890:32;4887:52;;;4935:1;4932;4925:12;4887:52;4971:9;4958:23;4948:33;;5031:2;5020:9;5016:18;5003:32;5044:31;5069:5;5044:31;:::i;:::-;5094:5;5084:15;;;4790:315;;;;;:::o;5110:127::-;5171:10;5166:3;5162:20;5159:1;5152:31;5202:4;5199:1;5192:15;5226:4;5223:1;5216:15;5242:275;5313:2;5307:9;5378:2;5359:13;;-1:-1:-1;;5355:27:22;5343:40;;5413:18;5398:34;;5434:22;;;5395:62;5392:88;;;5460:18;;:::i;:::-;5496:2;5489:22;5242:275;;-1:-1:-1;5242:275:22:o;5522:407::-;5587:5;5621:18;5613:6;5610:30;5607:56;;;5643:18;;:::i;:::-;5681:57;5726:2;5705:15;;-1:-1:-1;;5701:29:22;5732:4;5697:40;5681:57;:::i;:::-;5672:66;;5761:6;5754:5;5747:21;5801:3;5792:6;5787:3;5783:16;5780:25;5777:45;;;5818:1;5815;5808:12;5777:45;5867:6;5862:3;5855:4;5848:5;5844:16;5831:43;5921:1;5914:4;5905:6;5898:5;5894:18;5890:29;5883:40;5522:407;;;;;:::o;5934:222::-;5977:5;6030:3;6023:4;6015:6;6011:17;6007:27;5997:55;;6048:1;6045;6038:12;5997:55;6070:80;6146:3;6137:6;6124:20;6117:4;6109:6;6105:17;6070:80;:::i;6161:156::-;6227:20;;6287:4;6276:16;;6266:27;;6256:55;;6307:1;6304;6297:12;6322:884;6451:6;6459;6467;6475;6483;6491;6499;6552:3;6540:9;6531:7;6527:23;6523:33;6520:53;;;6569:1;6566;6559:12;6520:53;6608:9;6595:23;6627:31;6652:5;6627:31;:::i;:::-;6677:5;-1:-1:-1;6733:2:22;6718:18;;6705:32;6760:18;6749:30;;6746:50;;;6792:1;6789;6782:12;6746:50;6815;6857:7;6848:6;6837:9;6833:22;6815:50;:::i;:::-;6805:60;;;6917:2;6906:9;6902:18;6889:32;6930:33;6955:7;6930:33;:::i;:::-;6982:7;-1:-1:-1;7036:2:22;7021:18;;7008:32;;-1:-1:-1;7059:37:22;7091:3;7076:19;;7059:37;:::i;:::-;7049:47;;7143:3;7132:9;7128:19;7115:33;7105:43;;7195:3;7184:9;7180:19;7167:33;7157:43;;6322:884;;;;;;;;;;:::o;7211:675::-;7315:6;7323;7331;7339;7392:3;7380:9;7371:7;7367:23;7363:33;7360:53;;;7409:1;7406;7399:12;7360:53;7448:9;7435:23;7467:31;7492:5;7467:31;:::i;:::-;7517:5;-1:-1:-1;7573:2:22;7558:18;;7545:32;7600:18;7589:30;;7586:50;;;7632:1;7629;7622:12;7586:50;7655;7697:7;7688:6;7677:9;7673:22;7655:50;:::i;:::-;7645:60;;;7757:2;7746:9;7742:18;7729:32;7770:33;7795:7;7770:33;:::i;:::-;7211:675;;;;-1:-1:-1;7822:7:22;;7876:2;7861:18;7848:32;;-1:-1:-1;;7211:675:22:o;7891:943::-;7944:5;7997:3;7990:4;7982:6;7978:17;7974:27;7964:55;;8015:1;8012;8005:12;7964:55;8051:6;8038:20;8077:4;8100:18;8137:2;8133;8130:10;8127:36;;;8143:18;;:::i;:::-;8189:2;8186:1;8182:10;8212:28;8236:2;8232;8228:11;8212:28;:::i;:::-;8274:15;;;8344;;;8340:24;;;8305:12;;;;8376:15;;;8373:35;;;8404:1;8401;8394:12;8373:35;8440:2;8432:6;8428:15;8417:26;;8452:353;8468:6;8463:3;8460:15;8452:353;;;8554:3;8541:17;8590:2;8577:11;8574:19;8571:109;;;8634:1;8663:2;8659;8652:14;8571:109;8705:57;8758:3;8753:2;8739:11;8731:6;8727:24;8723:33;8705:57;:::i;:::-;8693:70;;-1:-1:-1;8485:12:22;;;;8783;;;;8452:353;;;8823:5;7891:943;-1:-1:-1;;;;;;;;7891:943:22:o;8839:710::-;8968:6;8976;8984;8992;9045:3;9033:9;9024:7;9020:23;9016:33;9013:53;;;9062:1;9059;9052:12;9013:53;9101:9;9088:23;9120:31;9145:5;9120:31;:::i;:::-;9170:5;-1:-1:-1;9226:2:22;9211:18;;9198:32;9253:18;9242:30;;9239:50;;;9285:1;9282;9275:12;9239:50;9308:60;9360:7;9351:6;9340:9;9336:22;9308:60;:::i;9554:247::-;9613:6;9666:2;9654:9;9645:7;9641:23;9637:32;9634:52;;;9682:1;9679;9672:12;9634:52;9721:9;9708:23;9740:31;9765:5;9740:31;:::i;9806:919::-;9960:6;9968;9976;9984;9992;10000;10008;10061:3;10049:9;10040:7;10036:23;10032:33;10029:53;;;10078:1;10075;10068:12;10029:53;10117:9;10104:23;10136:31;10161:5;10136:31;:::i;:::-;10186:5;-1:-1:-1;10242:2:22;10227:18;;10214:32;10269:18;10258:30;;10255:50;;;10301:1;10298;10291:12;10255:50;10324:60;10376:7;10367:6;10356:9;10352:22;10324:60;:::i;10983:315::-;11048:6;11056;11109:2;11097:9;11088:7;11084:23;11080:32;11077:52;;;11125:1;11122;11115:12;11077:52;11164:9;11151:23;11183:31;11208:5;11183:31;:::i;:::-;11233:5;-1:-1:-1;11257:35:22;11288:2;11273:18;;11257:35;:::i;:::-;11247:45;;10983:315;;;;;:::o;11303:795::-;11398:6;11406;11414;11422;11475:3;11463:9;11454:7;11450:23;11446:33;11443:53;;;11492:1;11489;11482:12;11443:53;11531:9;11518:23;11550:31;11575:5;11550:31;:::i;:::-;11600:5;-1:-1:-1;11657:2:22;11642:18;;11629:32;11670:33;11629:32;11670:33;:::i;:::-;11722:7;-1:-1:-1;11776:2:22;11761:18;;11748:32;;-1:-1:-1;11831:2:22;11816:18;;11803:32;11858:18;11847:30;;11844:50;;;11890:1;11887;11880:12;11844:50;11913:22;;11966:4;11958:13;;11954:27;-1:-1:-1;11944:55:22;;11995:1;11992;11985:12;11944:55;12018:74;12084:7;12079:2;12066:16;12061:2;12057;12053:11;12018:74;:::i;:::-;12008:84;;;11303:795;;;;;;;:::o;12103:469::-;12164:3;12202:5;12196:12;12229:6;12224:3;12217:19;12255:4;12284:2;12279:3;12275:12;12268:19;;12321:2;12314:5;12310:14;12342:1;12352:195;12366:6;12363:1;12360:13;12352:195;;;12431:13;;-1:-1:-1;;;;;12427:39:22;12415:52;;12487:12;;;;12522:15;;;;12463:1;12381:9;12352:195;;12577:285;12772:2;12761:9;12754:21;12735:4;12792:64;12852:2;12841:9;12837:18;12829:6;12792:64;:::i;12867:489::-;13140:2;13129:9;13122:21;13103:4;13166:64;13226:2;13215:9;13211:18;13203:6;13166:64;:::i;:::-;13278:9;13270:6;13266:22;13261:2;13250:9;13246:18;13239:50;13306:44;13343:6;13335;13306:44;:::i;:::-;13298:52;12867:489;-1:-1:-1;;;;;12867:489:22:o;13361:388::-;13429:6;13437;13490:2;13478:9;13469:7;13465:23;13461:32;13458:52;;;13506:1;13503;13496:12;13458:52;13545:9;13532:23;13564:31;13589:5;13564:31;:::i;:::-;13614:5;-1:-1:-1;13671:2:22;13656:18;;13643:32;13684:33;13643:32;13684:33;:::i;13754:380::-;13833:1;13829:12;;;;13876;;;13897:61;;13951:4;13943:6;13939:17;13929:27;;13897:61;14004:2;13996:6;13993:14;13973:18;13970:38;13967:161;;;14050:10;14045:3;14041:20;14038:1;14031:31;14085:4;14082:1;14075:15;14113:4;14110:1;14103:15;13967:161;;13754:380;;;:::o;15379:341::-;15581:2;15563:21;;;15620:2;15600:18;;;15593:30;-1:-1:-1;;;15654:2:22;15639:18;;15632:47;15711:2;15696:18;;15379:341::o;15725:127::-;15786:10;15781:3;15777:20;15774:1;15767:31;15817:4;15814:1;15807:15;15841:4;15838:1;15831:15;15857:413;16059:2;16041:21;;;16098:2;16078:18;;;16071:30;16137:34;16132:2;16117:18;;16110:62;-1:-1:-1;;;16203:2:22;16188:18;;16181:47;16260:3;16245:19;;15857:413::o;17931:405::-;18133:2;18115:21;;;18172:2;18152:18;;;18145:30;18211:34;18206:2;18191:18;;18184:62;-1:-1:-1;;;18277:2:22;18262:18;;18255:39;18326:3;18311:19;;17931:405::o;18341:352::-;18543:2;18525:21;;;18582:2;18562:18;;;18555:30;18621;18616:2;18601:18;;18594:58;18684:2;18669:18;;18341:352::o;18698:404::-;18900:2;18882:21;;;18939:2;18919:18;;;18912:30;18978:34;18973:2;18958:18;;18951:62;-1:-1:-1;;;19044:2:22;19029:18;;19022:38;19092:3;19077:19;;18698:404::o;19452:354::-;19654:2;19636:21;;;19693:2;19673:18;;;19666:30;19732:32;19727:2;19712:18;;19705:60;19797:2;19782:18;;19452:354::o;20221:401::-;20423:2;20405:21;;;20462:2;20442:18;;;20435:30;20501:34;20496:2;20481:18;;20474:62;-1:-1:-1;;;20567:2:22;20552:18;;20545:35;20612:3;20597:19;;20221:401::o;21392:127::-;21453:10;21448:3;21444:20;21441:1;21434:31;21484:4;21481:1;21474:15;21508:4;21505:1;21498:15;21524:128;21564:3;21595:1;21591:6;21588:1;21585:13;21582:39;;;21601:18;;:::i;:::-;-1:-1:-1;21637:9:22;;21524:128::o;21657:168::-;21697:7;21763:1;21759;21755:6;21751:14;21748:1;21745:21;21740:1;21733:9;21726:17;21722:45;21719:71;;;21770:18;;:::i;:::-;-1:-1:-1;21810:9:22;;21657:168::o;23058:125::-;23098:4;23126:1;23123;23120:8;23117:34;;;23131:18;;:::i;:::-;-1:-1:-1;23168:9:22;;23058:125::o;23188:127::-;23249:10;23244:3;23240:20;23237:1;23230:31;23280:4;23277:1;23270:15;23304:4;23301:1;23294:15;23320:120;23360:1;23386;23376:35;;23391:18;;:::i;:::-;-1:-1:-1;23425:9:22;;23320:120::o;23861:404::-;24111:1;24107;24102:3;24098:11;24094:19;24086:6;24082:32;24071:9;24064:51;24151:6;24146:2;24135:9;24131:18;24124:34;24194:2;24189;24178:9;24174:18;24167:30;24045:4;24214:45;24255:2;24244:9;24240:18;24232:6;24214:45;:::i;24270:370::-;24427:3;24465:6;24459:13;24481:53;24527:6;24522:3;24515:4;24507:6;24503:17;24481:53;:::i;:::-;24556:16;;;;24581:21;;;-1:-1:-1;24629:4:22;24618:16;;24270:370;-1:-1:-1;24270:370:22:o;25048:135::-;25087:3;-1:-1:-1;;25108:17:22;;25105:43;;;25128:18;;:::i;:::-;-1:-1:-1;25175:1:22;25164:13;;25048:135::o;25188:990::-;25422:4;25470:2;25459:9;25455:18;25529:1;25525;25520:3;25516:11;25512:19;25504:6;25500:32;25489:9;25482:51;25552:2;25590:6;25585:2;25574:9;25570:18;25563:34;25633:2;25628;25617:9;25613:18;25606:30;25656:6;25691;25685:13;25722:6;25714;25707:22;25760:3;25749:9;25745:19;25738:26;;25823:3;25813:6;25810:1;25806:14;25795:9;25791:30;25787:40;25773:54;;25862:2;25854:6;25850:15;25883:1;25893:256;25907:6;25904:1;25901:13;25893:256;;;26000:3;25996:8;25984:9;25976:6;25972:22;25968:37;25963:3;25956:50;26029:40;26062:6;26053;26047:13;26029:40;:::i;:::-;26019:50;-1:-1:-1;26127:12:22;;;;26092:15;;;;25929:1;25922:9;25893:256;;;-1:-1:-1;26166:6:22;;25188:990;-1:-1:-1;;;;;;;;;25188:990:22:o;26183:414::-;26385:2;26367:21;;;26424:2;26404:18;;;26397:30;26463:34;26458:2;26443:18;;26436:62;-1:-1:-1;;;26529:2:22;26514:18;;26507:48;26587:3;26572:19;;26183:414::o;27020:470::-;27199:3;27237:6;27231:13;27253:53;27299:6;27294:3;27287:4;27279:6;27275:17;27253:53;:::i;:::-;27369:13;;27328:16;;;;27391:57;27369:13;27328:16;27425:4;27413:17;;27391:57;:::i;:::-;27464:20;;27020:470;-1:-1:-1;;;;27020:470:22:o;27495:786::-;27906:25;27901:3;27894:38;27876:3;27961:6;27955:13;27977:62;28032:6;28027:2;28022:3;28018:12;28011:4;28003:6;27999:17;27977:62;:::i;:::-;-1:-1:-1;;;28098:2:22;28058:16;;;28090:11;;;28083:40;28148:13;;28170:63;28148:13;28219:2;28211:11;;28204:4;28192:17;;28170:63;:::i;:::-;28253:17;28272:2;28249:26;;27495:786;-1:-1:-1;;;;27495:786:22:o;28286:127::-;28347:10;28342:3;28338:20;28335:1;28328:31;28378:4;28375:1;28368:15;28402:4;28399:1;28392:15;29190:489;-1:-1:-1;;;;;29459:15:22;;;29441:34;;29511:15;;29506:2;29491:18;;29484:43;29558:2;29543:18;;29536:34;;;29606:3;29601:2;29586:18;;29579:31;;;29384:4;;29627:46;;29653:19;;29645:6;29627:46;:::i;:::-;29619:54;29190:489;-1:-1:-1;;;;;;29190:489:22:o;29684:249::-;29753:6;29806:2;29794:9;29785:7;29781:23;29777:32;29774:52;;;29822:1;29819;29812:12;29774:52;29854:9;29848:16;29873:30;29897:5;29873:30;:::i;30354:136::-;30393:3;30421:5;30411:39;;30430:18;;:::i;:::-;-1:-1:-1;;;30466:18:22;;30354:136::o;30856:112::-;30888:1;30914;30904:35;;30919:18;;:::i;:::-;-1:-1:-1;30953:9:22;;30856:112::o

Swarm Source

ipfs://27ae6fce80c33ac8c9cc9228b1e9c27385549cabca5f93ed06376046653b7888
Loading